summaryrefslogtreecommitdiff
path: root/programs
diff options
context:
space:
mode:
Diffstat (limited to 'programs')
-rw-r--r--programs/Makefile46
-rw-r--r--programs/Makefile.program154
-rw-r--r--programs/_confread/.cvsignore7
-rw-r--r--programs/_confread/Makefile27
-rw-r--r--programs/_confread/README.conf.V2103
-rw-r--r--programs/_confread/_confread.828
-rwxr-xr-xprograms/_confread/_confread.in520
-rw-r--r--programs/_confread/block.in8
-rw-r--r--programs/_confread/clear-or-private.in8
-rw-r--r--programs/_confread/clear.in7
-rw-r--r--programs/_confread/ipsec.conf.51286
-rw-r--r--programs/_confread/ipsec.conf.in44
-rw-r--r--programs/_confread/private-or-clear.in14
-rw-r--r--programs/_confread/private.in6
-rwxr-xr-xprograms/_confread/randomize28
-rw-r--r--programs/_copyright/.cvsignore1
-rw-r--r--programs/_copyright/Makefile44
-rw-r--r--programs/_copyright/_copyright.832
-rw-r--r--programs/_copyright/_copyright.c69
-rw-r--r--programs/_include/.cvsignore1
-rw-r--r--programs/_include/Makefile43
-rw-r--r--programs/_include/_include.835
-rwxr-xr-xprograms/_include/_include.in102
-rw-r--r--programs/_keycensor/.cvsignore1
-rw-r--r--programs/_keycensor/Makefile43
-rw-r--r--programs/_keycensor/_keycensor.833
-rwxr-xr-xprograms/_keycensor/_keycensor.in52
-rw-r--r--programs/_plutoload/.cvsignore1
-rw-r--r--programs/_plutoload/Makefile43
-rw-r--r--programs/_plutoload/_plutoload.833
-rwxr-xr-xprograms/_plutoload/_plutoload.in164
-rw-r--r--programs/_plutorun/.cvsignore1
-rw-r--r--programs/_plutorun/Makefile43
-rw-r--r--programs/_plutorun/_plutorun.837
-rwxr-xr-xprograms/_plutorun/_plutorun.in281
-rw-r--r--programs/_realsetup/.cvsignore1
-rw-r--r--programs/_realsetup/Makefile43
-rw-r--r--programs/_realsetup/_realsetup.836
-rwxr-xr-xprograms/_realsetup/_realsetup.in456
-rw-r--r--programs/_secretcensor/.cvsignore1
-rw-r--r--programs/_secretcensor/Makefile43
-rw-r--r--programs/_secretcensor/_secretcensor.834
-rwxr-xr-xprograms/_secretcensor/_secretcensor.in75
-rw-r--r--programs/_startklips/.cvsignore1
-rw-r--r--programs/_startklips/Makefile43
-rw-r--r--programs/_startklips/_startklips.833
-rwxr-xr-xprograms/_startklips/_startklips.in367
-rw-r--r--programs/_updown/.cvsignore2
-rw-r--r--programs/_updown/Makefile22
-rw-r--r--programs/_updown/_updown.819
-rwxr-xr-xprograms/_updown/_updown.in503
-rw-r--r--programs/_updown_espmark/Makefile22
-rw-r--r--programs/_updown_espmark/_updown_espmark.818
-rw-r--r--programs/_updown_espmark/_updown_espmark.in452
-rw-r--r--programs/auto/.cvsignore1
-rw-r--r--programs/auto/Makefile21
-rw-r--r--programs/auto/auto.8481
-rwxr-xr-xprograms/auto/auto.in660
-rw-r--r--programs/barf/.cvsignore1
-rw-r--r--programs/barf/Makefile38
-rw-r--r--programs/barf/barf.884
-rwxr-xr-xprograms/barf/barf.in296
-rw-r--r--programs/calcgoo/.cvsignore1
-rw-r--r--programs/calcgoo/Makefile41
-rw-r--r--programs/calcgoo/calcgoo.831
-rw-r--r--programs/calcgoo/calcgoo.in43
-rw-r--r--programs/eroute/.cvsignore1
-rw-r--r--programs/eroute/Makefile52
-rw-r--r--programs/eroute/eroute.5272
-rw-r--r--programs/eroute/eroute.8354
-rw-r--r--programs/eroute/eroute.c1044
-rw-r--r--programs/examples/Makefile22
-rw-r--r--programs/examples/oe.conf.in68
-rw-r--r--programs/ikeping/.cvsignore1
-rw-r--r--programs/ikeping/Makefile57
-rw-r--r--programs/ikeping/ikeping.871
-rw-r--r--programs/ikeping/ikeping.c483
-rw-r--r--programs/ipsec/.cvsignore1
-rw-r--r--programs/ipsec/Makefile28
-rw-r--r--programs/ipsec/distro.txt1
-rw-r--r--programs/ipsec/ipsec.8336
-rwxr-xr-xprograms/ipsec/ipsec.in259
-rw-r--r--programs/klipsdebug/.cvsignore1
-rw-r--r--programs/klipsdebug/Makefile80
-rw-r--r--programs/klipsdebug/klipsdebug.5138
-rw-r--r--programs/klipsdebug/klipsdebug.8164
-rw-r--r--programs/klipsdebug/klipsdebug.c436
-rw-r--r--programs/look/.cvsignore1
-rw-r--r--programs/look/Makefile38
-rw-r--r--programs/look/look.845
-rwxr-xr-xprograms/look/look.in87
-rw-r--r--programs/lwdnsq/.cvsignore4
-rw-r--r--programs/lwdnsq/CONTRACT.txt106
-rw-r--r--programs/lwdnsq/Makefile96
-rw-r--r--programs/lwdnsq/cmds.c351
-rw-r--r--programs/lwdnsq/lookup.c632
-rw-r--r--programs/lwdnsq/lwdnsq.8250
-rw-r--r--programs/lwdnsq/lwdnsq.c506
-rw-r--r--programs/lwdnsq/lwdnsq.h121
-rw-r--r--programs/lwdnsq/lwdnsq.xml.in446
-rw-r--r--programs/lwdnsq/states.fig66
-rw-r--r--programs/lwdnsq/states.pngbin6756 -> 0 bytes
-rw-r--r--programs/mailkey/.cvsignore1
-rw-r--r--programs/mailkey/Makefile41
-rw-r--r--programs/mailkey/mailkey.847
-rwxr-xr-xprograms/mailkey/mailkey.in241
-rw-r--r--programs/manual/.cvsignore1
-rw-r--r--programs/manual/Makefile38
-rw-r--r--programs/manual/manual.8267
-rwxr-xr-xprograms/manual/manual.in637
-rw-r--r--programs/openac/Makefile162
-rw-r--r--programs/openac/build.c242
-rw-r--r--programs/openac/build.h47
-rw-r--r--programs/openac/loglite.c295
-rw-r--r--programs/openac/openac.8180
-rwxr-xr-xprograms/openac/openac.c438
-rw-r--r--programs/pf_key/.cvsignore1
-rw-r--r--programs/pf_key/Makefile49
-rw-r--r--programs/pf_key/pf_key.5122
-rw-r--r--programs/pf_key/pf_key.873
-rw-r--r--programs/pf_key/pf_key.c353
-rw-r--r--programs/pluto/.cvsignore3
-rw-r--r--programs/pluto/Makefile1090
-rw-r--r--programs/pluto/PLUTO-CONVENTIONS127
-rw-r--r--programs/pluto/TODO129
-rw-r--r--programs/pluto/ac.c1018
-rw-r--r--programs/pluto/ac.h103
-rw-r--r--programs/pluto/adns.c615
-rw-r--r--programs/pluto/adns.h75
-rw-r--r--programs/pluto/alg/Config.ike_alg9
-rw-r--r--programs/pluto/alg/Makefile93
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_aes14
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_blowfish13
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_serpent13
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_sha213
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_twofish13
-rw-r--r--programs/pluto/alg/ike_alg_aes.c68
-rw-r--r--programs/pluto/alg/ike_alg_blowfish.c52
-rw-r--r--programs/pluto/alg/ike_alg_serpent.c70
-rw-r--r--programs/pluto/alg/ike_alg_sha2.c634
-rw-r--r--programs/pluto/alg/ike_alg_twofish.c85
-rw-r--r--programs/pluto/alg_info.c1205
-rw-r--r--programs/pluto/alg_info.h85
-rw-r--r--programs/pluto/asn1.c770
-rw-r--r--programs/pluto/asn1.h141
-rw-r--r--programs/pluto/ca.c694
-rw-r--r--programs/pluto/ca.h70
-rw-r--r--programs/pluto/certs.c287
-rw-r--r--programs/pluto/certs.h80
-rw-r--r--programs/pluto/connections.c4457
-rw-r--r--programs/pluto/connections.h376
-rw-r--r--programs/pluto/constants.c1356
-rw-r--r--programs/pluto/constants.h1264
-rw-r--r--programs/pluto/cookie.c67
-rw-r--r--programs/pluto/cookie.h24
-rw-r--r--programs/pluto/crl.c763
-rw-r--r--programs/pluto/crl.h87
-rw-r--r--programs/pluto/crypto.c627
-rw-r--r--programs/pluto/crypto.h108
-rw-r--r--programs/pluto/db_ops.c439
-rw-r--r--programs/pluto/db_ops.h56
-rw-r--r--programs/pluto/defs.c374
-rw-r--r--programs/pluto/defs.h145
-rw-r--r--programs/pluto/demux.c2526
-rw-r--r--programs/pluto/demux.h100
-rw-r--r--programs/pluto/dnskey.c1962
-rw-r--r--programs/pluto/dnskey.h84
-rw-r--r--programs/pluto/dsa.c476
-rw-r--r--programs/pluto/dsa.h32
-rw-r--r--programs/pluto/elgamal.c613
-rw-r--r--programs/pluto/elgamal.h35
-rw-r--r--programs/pluto/fetch.c1081
-rw-r--r--programs/pluto/fetch.h79
-rw-r--r--programs/pluto/foodgroups.c462
-rw-r--r--programs/pluto/foodgroups.h24
-rw-r--r--programs/pluto/gcryptfix.c283
-rw-r--r--programs/pluto/gcryptfix.h111
-rw-r--r--programs/pluto/id.c509
-rw-r--r--programs/pluto/id.h67
-rw-r--r--programs/pluto/ike_alg.c592
-rw-r--r--programs/pluto/ike_alg.h94
-rw-r--r--programs/pluto/ipsec.secrets.5175
-rw-r--r--programs/pluto/ipsec_doi.c5696
-rw-r--r--programs/pluto/ipsec_doi.h104
-rw-r--r--programs/pluto/kameipsec.h47
-rw-r--r--programs/pluto/kernel.c2999
-rw-r--r--programs/pluto/kernel.h200
-rw-r--r--programs/pluto/kernel_alg.c775
-rw-r--r--programs/pluto/kernel_alg.h46
-rw-r--r--programs/pluto/kernel_netlink.c1221
-rw-r--r--programs/pluto/kernel_netlink.h20
-rw-r--r--programs/pluto/kernel_noklips.c126
-rw-r--r--programs/pluto/kernel_noklips.h19
-rw-r--r--programs/pluto/kernel_pfkey.c938
-rw-r--r--programs/pluto/kernel_pfkey.h23
-rw-r--r--programs/pluto/keys.c1516
-rw-r--r--programs/pluto/keys.h114
-rw-r--r--programs/pluto/lex.c213
-rw-r--r--programs/pluto/lex.h52
-rw-r--r--programs/pluto/linux26/netlink.h90
-rw-r--r--programs/pluto/linux26/rtnetlink.h562
-rw-r--r--programs/pluto/linux26/xfrm.h233
-rw-r--r--programs/pluto/log.c841
-rw-r--r--programs/pluto/log.h236
-rw-r--r--programs/pluto/md2.c237
-rw-r--r--programs/pluto/md2.h72
-rw-r--r--programs/pluto/md5.c385
-rw-r--r--programs/pluto/md5.h75
-rw-r--r--programs/pluto/modecfg.c1078
-rw-r--r--programs/pluto/modecfg.h47
-rw-r--r--programs/pluto/mp_defs.c70
-rw-r--r--programs/pluto/mp_defs.h36
-rw-r--r--programs/pluto/nat_traversal.c869
-rw-r--r--programs/pluto/nat_traversal.h154
-rw-r--r--programs/pluto/ocsp.c1568
-rw-r--r--programs/pluto/ocsp.h85
-rw-r--r--programs/pluto/oid.c197
-rw-r--r--programs/pluto/oid.h78
-rw-r--r--programs/pluto/oid.pl123
-rw-r--r--programs/pluto/oid.txt184
-rw-r--r--programs/pluto/packet.c1244
-rw-r--r--programs/pluto/packet.h655
-rw-r--r--programs/pluto/pem.c463
-rw-r--r--programs/pluto/pem.h18
-rw-r--r--programs/pluto/pgp.c647
-rw-r--r--programs/pluto/pgp.h54
-rw-r--r--programs/pluto/pkcs1.c674
-rw-r--r--programs/pluto/pkcs1.h88
-rw-r--r--programs/pluto/pkcs7.c862
-rw-r--r--programs/pluto/pkcs7.h51
-rw-r--r--programs/pluto/pluto-style.el4
-rw-r--r--programs/pluto/pluto.81649
-rw-r--r--programs/pluto/plutomain.c684
-rw-r--r--programs/pluto/primegen.c593
-rw-r--r--programs/pluto/rcv_whack.c689
-rw-r--r--programs/pluto/rcv_whack.h17
-rw-r--r--programs/pluto/rnd.c250
-rw-r--r--programs/pluto/rnd.h21
-rw-r--r--programs/pluto/routing.txt331
-rw-r--r--programs/pluto/rsaref/pkcs11.h299
-rw-r--r--programs/pluto/rsaref/pkcs11f.h912
-rw-r--r--programs/pluto/rsaref/pkcs11t.h1685
-rw-r--r--programs/pluto/rsaref/unix.h24
-rw-r--r--programs/pluto/server.c1001
-rw-r--r--programs/pluto/server.h60
-rw-r--r--programs/pluto/sha1.c193
-rw-r--r--programs/pluto/sha1.h16
-rw-r--r--programs/pluto/smallprime.c122
-rw-r--r--programs/pluto/smartcard.c1956
-rw-r--r--programs/pluto/smartcard.h100
-rw-r--r--programs/pluto/spdb.c2329
-rw-r--r--programs/pluto/spdb.h112
-rw-r--r--programs/pluto/state.c1012
-rw-r--r--programs/pluto/state.h275
-rw-r--r--programs/pluto/timer.c537
-rw-r--r--programs/pluto/timer.h34
-rw-r--r--programs/pluto/vendor.c521
-rw-r--r--programs/pluto/vendor.h125
-rw-r--r--programs/pluto/virtual.c338
-rw-r--r--programs/pluto/virtual.h31
-rw-r--r--programs/pluto/whack.c1911
-rw-r--r--programs/pluto/whack.h319
-rw-r--r--programs/pluto/x509.c2241
-rw-r--r--programs/pluto/x509.h138
-rw-r--r--programs/pluto/xauth.c77
-rw-r--r--programs/pluto/xauth.h41
-rw-r--r--programs/proc/Makefile51
-rw-r--r--programs/proc/trap_count.535
-rw-r--r--programs/proc/trap_sendcount.533
-rw-r--r--programs/proc/version.554
-rw-r--r--programs/ranbits/.cvsignore1
-rw-r--r--programs/ranbits/Makefile39
-rw-r--r--programs/ranbits/ranbits.877
-rw-r--r--programs/ranbits/ranbits.c146
-rw-r--r--programs/rsasigkey/.cvsignore1
-rw-r--r--programs/rsasigkey/Makefile39
-rw-r--r--programs/rsasigkey/rsasigkey.8259
-rw-r--r--programs/rsasigkey/rsasigkey.c573
-rw-r--r--programs/scepclient/Makefile192
-rw-r--r--programs/scepclient/pkcs10.c220
-rw-r--r--programs/scepclient/pkcs10.h57
-rw-r--r--programs/scepclient/rsakey.c349
-rw-r--r--programs/scepclient/rsakey.h31
-rw-r--r--programs/scepclient/scep.c598
-rw-r--r--programs/scepclient/scep.h93
-rw-r--r--programs/scepclient/scepclient.8288
-rw-r--r--programs/scepclient/scepclient.c1036
-rw-r--r--programs/secrets/Makefile38
-rw-r--r--programs/secrets/secrets.820
-rw-r--r--programs/secrets/secrets.in18
-rw-r--r--programs/send-pr/.cvsignore1
-rw-r--r--programs/send-pr/Makefile39
-rw-r--r--programs/send-pr/ipsec_pr.template54
-rw-r--r--programs/send-pr/send-pr.8291
-rwxr-xr-xprograms/send-pr/send-pr.in643
-rw-r--r--programs/setup/.cvsignore1
-rw-r--r--programs/setup/Makefile22
-rw-r--r--programs/setup/setup.8142
-rwxr-xr-xprograms/setup/setup.in162
-rw-r--r--programs/showdefaults/.cvsignore1
-rw-r--r--programs/showdefaults/Makefile38
-rw-r--r--programs/showdefaults/showdefaults.834
-rwxr-xr-xprograms/showdefaults/showdefaults.in33
-rw-r--r--programs/showhostkey/.cvsignore1
-rw-r--r--programs/showhostkey/Makefile38
-rw-r--r--programs/showhostkey/showhostkey.8168
-rwxr-xr-xprograms/showhostkey/showhostkey.in180
-rw-r--r--programs/showpolicy/.cvsignore1
-rw-r--r--programs/showpolicy/Makefile38
-rw-r--r--programs/showpolicy/showpolicy.841
-rw-r--r--programs/showpolicy/showpolicy.c251
-rw-r--r--programs/spi/.cvsignore1
-rw-r--r--programs/spi/Makefile69
-rw-r--r--programs/spi/spi.5213
-rw-r--r--programs/spi/spi.8525
-rw-r--r--programs/spi/spi.c1689
-rw-r--r--programs/spigrp/.cvsignore1
-rw-r--r--programs/spigrp/Makefile52
-rw-r--r--programs/spigrp/spigrp.5116
-rw-r--r--programs/spigrp/spigrp.8174
-rw-r--r--programs/spigrp/spigrp.c491
-rw-r--r--programs/starter/Makefile182
-rw-r--r--programs/starter/README104
-rw-r--r--programs/starter/args.c623
-rw-r--r--programs/starter/args.h34
-rw-r--r--programs/starter/cmp.c105
-rw-r--r--programs/starter/cmp.h29
-rw-r--r--programs/starter/confread.c908
-rw-r--r--programs/starter/confread.h200
-rw-r--r--programs/starter/exec.c54
-rw-r--r--programs/starter/exec.h23
-rw-r--r--programs/starter/files.h47
-rw-r--r--programs/starter/interfaces.c582
-rw-r--r--programs/starter/interfaces.h41
-rw-r--r--programs/starter/invokepluto.c286
-rw-r--r--programs/starter/invokepluto.h28
-rw-r--r--programs/starter/keywords.c246
-rw-r--r--programs/starter/keywords.h169
-rw-r--r--programs/starter/keywords.txt109
-rw-r--r--programs/starter/klips.c134
-rw-r--r--programs/starter/klips.h26
-rw-r--r--programs/starter/lex.yy.c1966
-rw-r--r--programs/starter/netkey.c85
-rw-r--r--programs/starter/netkey.h24
-rw-r--r--programs/starter/parser.h57
-rw-r--r--programs/starter/parser.l190
-rw-r--r--programs/starter/parser.output351
-rw-r--r--programs/starter/parser.tab.c1832
-rw-r--r--programs/starter/parser.tab.h82
-rw-r--r--programs/starter/parser.y283
-rw-r--r--programs/starter/starter.80
-rw-r--r--programs/starter/starter.c571
-rw-r--r--programs/starter/starterwhack.c372
-rw-r--r--programs/starter/starterwhack.h32
-rw-r--r--programs/tncfg/.cvsignore1
-rw-r--r--programs/tncfg/Makefile52
-rw-r--r--programs/tncfg/tncfg.5109
-rw-r--r--programs/tncfg/tncfg.8113
-rw-r--r--programs/tncfg/tncfg.c393
359 files changed, 0 insertions, 111017 deletions
diff --git a/programs/Makefile b/programs/Makefile
deleted file mode 100644
index dbc03f416..000000000
--- a/programs/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.9 2006/08/28 11:12:36 as Exp $
-
-FREESWANSRCDIR=..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-SUBDIRS=spi eroute spigrp tncfg klipsdebug pf_key proc pluto
-SUBDIRS+=_confread _copyright _include _keycensor _plutoload _plutorun
-SUBDIRS+=_realsetup _secretcensor _startklips _updown _updown_espmark
-SUBDIRS+=auto barf ipsec look manual ranbits secrets starter
-SUBDIRS+=rsasigkey send-pr setup showdefaults showhostkey calcgoo mailkey
-SUBDIRS+=ikeping examples openac scepclient
-
-ifeq ($(USE_LWRES),true)
-SUBDIRS+=lwdnsq
-endif
-
-ifeq ($(USE_IPSECPOLICY),true)
-SUBDIRS+=showpolicy
-endif
-
-def:
- @echo "Please read doc/intro.html or INSTALL before running make"
- @false
-
-# programs
-
-cleanall distclean mostlyclean realclean install programs checkprograms check clean spotless install_file_list:
- @for d in $(SUBDIRS) ; \
- do \
- (cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1;\
- done;
-
diff --git a/programs/Makefile.program b/programs/Makefile.program
deleted file mode 100644
index 14d2d8269..000000000
--- a/programs/Makefile.program
+++ /dev/null
@@ -1,154 +0,0 @@
-
-include ${FREESWANSRCDIR}/Makefile.ver
-
-CFLAGS+=$(USERCOMPILE) -I${KLIPSINC}
-
-CFLAGS+= -Wall
-#CFLAGS+= -Wconversion
-#CFLAGS+= -Wmissing-prototypes
-CFLAGS+= -Wpointer-arith
-CFLAGS+= -Wcast-qual
-#CFLAGS+= -Wmissing-declarations
-CFLAGS+= -Wstrict-prototypes
-#CFLAGS+= -pedantic
-#CFLAGS+= -W
-#CFLAGS+= -Wwrite-strings
-CFLAGS+= -Wbad-function-cast
-
-# die if there are any warnings
-ifndef WERROR
-WERROR:= -Werror
-endif
-
-#CFLAGS+= ${WERROR}
-
-ifeq ($(USE_NAT_TRAVERSAL),true)
- CFLAGS+= -DNAT_TRAVERSAL
-endif
-
-ifneq ($(LD_LIBRARY_PATH),)
-LDFLAGS=-L$(LD_LIBRARY_PATH)
-endif
-
-MANDIR8=$(MANTREE)/man8
-MANDIR5=$(MANTREE)/man5
-
-ifndef PROGRAMDIR
-PROGRAMDIR=${LIBEXECDIR}
-endif
-
-ifndef MANPROGPREFIX
-MANPROGPREFIX=ipsec_
-endif
-
-ifndef CONFDSUBDIR
-CONFDSUBDIR=.
-endif
-
-all: $(PROGRAM)
-
-programs: all
-
-ifneq ($(PROGRAM),check)
-check: $(PROGRAM)
-endif
-
-
-ifneq ($(NOINSTALL),true)
-
-install:: $(PROGRAM) $(CONFFILES) $(EXTRA8MAN) $(EXTRA5MAN) $(EXTRA5PROC) $(LIBFILES) $(CONFDFILES)
- @mkdir -p $(PROGRAMDIR) $(MANDIR8) $(MANDIR5) $(LIBDIR) $(CONFDIR) $(CONFDDIR) $(CONFDDIR)/$(CONFDSUBDIR) $(EXAMPLECONFDIR)
- @if [ -n "$(PROGRAM)" ]; then $(INSTALL) $(INSTBINFLAGS) $(PROGRAM) $(PROGRAMDIR); fi
- @$(foreach f, $(addsuffix .8, $(PROGRAM)), \
- $(INSTALL) $(INSTMANFLAGS) $f $(MANDIR8)/$(MANPROGPREFIX)$f || exit 1; \
- )
- @$(foreach f, $(EXTRA8MAN), \
- $(INSTALL) $(INSTMANFLAGS) $f $(MANDIR8)/ipsec_$f || exit 1; \
- )
- @$(foreach f, $(EXTRA5MAN), \
- $(INSTALL) $(INSTMANFLAGS) $f $(MANDIR5)/$f || exit 1 ;\
- )
- @$(foreach f, $(EXTRA5PROC), \
- $(INSTALL) $(INSTMANFLAGS) $f $(MANDIR5)/ipsec_$f || exit 1 ;\
- )
- @$(foreach f, $(LIBFILES), \
- $(INSTALL) $(INSTCONFFLAGS) $f $(LIBDIR)/$f || exit 1 ;\
- )
- @$(foreach f, $(CONFFILES), \
- if [ ! -f $(CONFDIR)/$f ]; then $(INSTALL) $(INSTCONFFLAGS) $f $(CONFDIR)/$f || exit 1; fi;\
- $(INSTALL) $(INSTCONFFLAGS) $f $(EXAMPLECONFDIR)/$f-sample || exit 1; \
- )
- @$(foreach f, $(CONFDFILES), \
- if [ ! -f $(CONFDDIR)/$(CONFDSUBDIR)/$f ]; then $(INSTALL) $(INSTCONFFLAGS) $f $(CONFDDIR)/$(CONFDSUBDIR)/$f || exit 1; fi;\
- )
-
-install_file_list::
- @if [ -n "$(PROGRAM)" ]; then echo $(PROGRAMDIR)/$(PROGRAM); fi
- @$(foreach f, $(addsuffix .8, $(PROGRAM)), \
- echo $(MANDIR8)/${MANPROGPREFIX}$f; \
- )
- @$(foreach f, $(EXTRA8MAN), \
- echo $(MANDIR8)/ipsec_$f; \
- )
- @$(foreach f, $(EXTRA5MAN), \
- echo $(MANDIR5)/$f;\
- )
- @$(foreach f, $(EXTRA5PROC), \
- echo $(MANDIR5)/ipsec_$f; \
- )
- @$(foreach f, $(LIBFILES), \
- echo $(LIBDIR)/$f;\
- )
- @$(foreach f, $(CONFFILES), \
- echo $(CONFDIR)/$f;\
- echo $(EXAMPLECONFDIR)/$f-sample;\
- )
- @$(foreach f, $(CONFDFILES), \
- echo $(CONFDDIR)/${CONFDSUBDIR}/$f;\
- )
-
-endif
-
-# cancel the rule that compiles directly
-%: %.c
-
-%: %.o $(OBJS)
- $(CC) $(CFLAGS) -o $@ $@.o ${OBJS} $(LDFLAGS) $(LIBS)
-
-%: %.in ${FREESWANSRCDIR}/Makefile.inc ${FREESWANSRCDIR}/Makefile.ver
- cat $< | sed -e "s/xxx/$(IPSECVERSION)/" \
- -e "s:@IPSEC_DIR@:$(FINALBINDIR):" \
- -e "s:@IPSEC_EXECDIR@:$(FINALLIBEXECDIR):" \
- -e "s:@IPSEC_SBINDIR@:$(FINALSBINDIR):" \
- -e "s:@IPSEC_LIBDIR@:$(FINALLIBDIR):" \
- -e "s:@FINALCONFDIR@:$(FINALCONFDIR):" \
- -e "s:@EXAMPLECONFDIR@:$(EXAMPLECONFDIR):" \
- -e "s:@FINALDOCDIR@:$(FINALDOCDIR):" \
- -e "s:@FINALEXAMPLECONFDIR@:$(FINALEXAMPLECONFDIR):" \
- -e "s:@MODULE_GOO_LIST@:$(MODULE_GOO_LIST):" \
- -e "s:@IPSEC_CONFS@:$(FINALCONFDIR):" \
- -e "s:@IPSEC_CONFDDIR@:$(FINALCONFDDIR):" \
- -e "s:@USE_IPROUTE2@:$(USE_IPROUTE2):" \
- -e "s:@IPSEC_FIREWALLTYPE@:$(IPSEC_FIREWALLTYPE):" \
- | cat >$@
- if [ -x $< ]; then chmod +x $@; fi
- if [ "${PROGRAM}.in" = $< ]; then chmod +x $@; fi
-
-cleanall: clean
-
-distclean: clean
-
-mostlyclean: clean
-
-realclean: clean
-
-clean::
-ifneq ($(strip $(PROGRAM)),)
- @if [ -r $(PROGRAM).in ]; then rm -f $(PROGRAM); fi
- @if [ -r $(PROGRAM).c ]; then rm -f $(PROGRAM); fi
- @if [ -n "$(OBJS)" ]; then rm -f $(PROGRAM); fi
-endif
- @rm -f *.o
-
-checkprograms:
-
diff --git a/programs/_confread/.cvsignore b/programs/_confread/.cvsignore
deleted file mode 100644
index 405492384..000000000
--- a/programs/_confread/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-_confread
-ipsec.conf
-block
-clear
-private
-clear-or-private
-private-or-clear
diff --git a/programs/_confread/Makefile b/programs/_confread/Makefile
deleted file mode 100644
index 1bdc9a3f0..000000000
--- a/programs/_confread/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.2 2004/03/31 19:23:00 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_confread
-PROGRAMDIR=${LIBDIR}
-EXTRA5MAN=ipsec.conf.5
-CONFFILES=ipsec.conf
-
-CONFDSUBDIR=policies
-CONFDFILES=clear clear-or-private private-or-clear private block
-
-include ../Makefile.program
diff --git a/programs/_confread/README.conf.V2 b/programs/_confread/README.conf.V2
deleted file mode 100644
index 244e245c5..000000000
--- a/programs/_confread/README.conf.V2
+++ /dev/null
@@ -1,103 +0,0 @@
-Subject: [Design] changes to ipsec.conf
-# RCSID $Id: README.conf.V2,v 1.1 2004/03/15 20:35:27 as Exp $
-
-We are changing ipsec.conf for the 2.0 series of FreeS/WAN.
-
-OE is enabled by default. This is accomplished by automatically
-defining a conn "OEself" UNLESS the sysadmin defines one with the same
-name:
-
-conn OEself
- # authby=rsasig # default
- left=%defaultroute
- leftrsasigkey=%dnsondemand # default
- right=%opportunistic
- rightrsasigkey=%dnsondemand # default
- keyingtries=3
- ikelifetime=1h
- keylife=1h # default
- rekey=no
- # disablearrivalcheck=no # default
- auto=route
-
-This will only work if %defaultroute works.
-The leftid will be the resulting IP address (won't work if
-you haven't filled in the reverse DNS entry).
-Unlike other conns, nothing in this implicit conn is changed by conn %default.
-
-We'd like a better name. A conn name starting with % cannot be
-defined by the sysadmin, so that is out. Names that haven't grabbed
-us: OEhost, OElocalhost, OEthishost, OEforself, OE4self.
-
-There is no requirement to have /etc/ipsec.conf. If you do, the first
-significant line (non-blank, non-comment) must be (not indented):
-version 2.0
-This signifies that the file was intended for FreeS/WAN version 2.0.
-
-
-The following table shows most changes. "-" means that the option
-doesn't exist. "Recent Boilerplate" shows the effect of the "conn
-%default" in the automatically installed /etc/ipsec.conf (not
-installed if you already had one).
-
-Option Old Default Recent Boilerplate New Default
-====== =========== ================== ===========
-
-config setup:
-interfaces "" %defaultroute %defaultroute
-plutoload "" %search - [same as %search]
-plutostart "" %search - [same as %search]
-uniqueids no yes yes
-rp_filter - - 0
-plutowait yes yes no
-dump no no - [use dumpdir]
-plutobackgroundload ignored ignored -
-no_eroute_pass no no - [use packetdefault]
-
-conn %default:
-keyingtries 3 0 %forever [0 means this]
-disablearrivalcheck yes no no
-authby secret rsasig rsasig
-leftrsasigkey "" %dnsondemand %dnsondemand
-rightrsasigkey "" %dnsondemand %dnsondemand
-lifetime ==keylife ==keylife - [use keylife]
-rekeystart ==rekeymargin ==rekeymargin - [use rekeymargin]
-rekeytries ==keyingtries ==keyingtries - [use keyingtries]
-
-====== =========== ================== ===========
-Option Old Default Recent Boilerplate New Default
-
-
-The auto= mechanism has been extended to support manual conns. If you
-specify auto=manual in a conn, an "ipsec manual" will be performed on
-it at startup (ipsec setup start).
-
-
-There is a new config setup option "rp_filter". It controls
- /proc/sys/net/ipv4/conf/PHYS/rp_filter
-for each PHYSical IP interface used by FreeS/WAN. Settings are:
- %unchanged do not touch (but warn if wrong)
- 0 set to 0; default; means: no filtering
- 1 set to 1; means: loose filter
- 2 set to 1; means: strict filter
-0 is often necessary for FreeS/WAN to function. Some folks
-want other settings. Shutting down FreeS/WAN does not restore
-the original value.
-
-Currently ikelife defaults to 1 hour and keylife defaults to 8 hours.
-There have been some rumblings that these are the wrong defaults, but
-it isn't clear what would be best. Perhaps both should be closer.
-Any thoughts of what these should be? Any Road Warrior or OE conn
-should probably have carefully thought-out values explicitly
-specified. The settings don't matter much for VPN connections.
-
-keyingtries=%forever is the new improved notation for keyingtries=0.
-Eventually the 0 notation will be eliminated.
-
-Some options can now be set to %none to signify no setting. Otherwise
-there would be no way for the user to override a default setting:
- leftrsasigkey, rightrsasigkey [added in 1.98]
- interfaces
-
-Hugh Redelmeier
-hugh@mimosa.com voice: +1 416 482-8253
diff --git a/programs/_confread/_confread.8 b/programs/_confread/_confread.8
deleted file mode 100644
index 20d92a002..000000000
--- a/programs/_confread/_confread.8
+++ /dev/null
@@ -1,28 +0,0 @@
-.TH _CONFREAD 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _confread.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _confread \- internal routing to parse config file
-.SH DESCRIPTION
-.I _confread
-is an internal script used for parsing /etc/ipsec.conf into a canonical format.
-.SH "SEE ALSO"
-ipsec(8), ipsec_conf(8)
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Program written by Henry Spencer.
-.\"
-.\" $Log: _confread.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.3 2002/09/16 01:28:43 dhr
-.\"
-.\" typo
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\"
-.\"
diff --git a/programs/_confread/_confread.in b/programs/_confread/_confread.in
deleted file mode 100755
index 4561af9fe..000000000
--- a/programs/_confread/_confread.in
+++ /dev/null
@@ -1,520 +0,0 @@
-#!/bin/sh
-# configuration-file reader utility
-# Copyright (C) 1999-2002 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _confread.in,v 1.15 2006/04/20 04:42:12 as Exp $
-#
-# Extract configuration info from /etc/ipsec.conf, repackage as assignments
-# to shell variables or tab-delimited fields. Success or failure is reported
-# inline, as extra data, due to the vagaries of shell backquote handling.
-# In the absence of --varprefix, output is tab-separated fields, like:
-# = sectionname
-# : parameter value
-# ! status (empty for success, else complaint)
-# In the presence of (say) "--varprefix IPSEC", output is like:
-# IPSEC_confreadsection="sectionname"
-# IPSECparameter="value"
-# IPSEC_confreadstatus="status" (same empty/complaint convention)
-#
-# The "--search parametername" option inverts the search: instead of
-# yielding the parameters of the specified name(s), it yields the names
-# of sections with parameter <parametername> having (one of) the
-# specified value(s). In this case, --varprefix output is a list of
-# names in the <prefix>_confreadnames variable. Search values with
-# white space in them are currently not handled properly.
-#
-# Typical usage:
-# eval `ipsec _confread --varprefix IPSEC --type config setup`
-# if test " $IPSEC_confreadstatus" != " "
-# then
-# echo "$0: $IPSEC_confreadstatus -- aborting" 2>&1
-# exit 1
-# fi
-
-# absent default config file treated as empty
-config=${IPSEC_CONFS-@FINALCONFDIR@}/ipsec.conf
-if test ! -f "$config" ; then config=/dev/null ; fi
-
-include=yes
-type=conn
-fieldfmt=yes
-prefix=
-search=
-export=0
-version=
-optional=0
-me="ipsec _confread"
-
-for dummy
-do
- case "$1" in
- --config) config="$2" ; shift ;;
- --noinclude) include= ;;
- --type) type="$2" ; shift ;;
- --varprefix) fieldfmt=
- prefix="$2"
- shift ;;
- --export) export=1 ;;
- --search) search="$2" ; shift ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --optional) optional=1 ;;
- --) shift ; break ;;
- -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-if test "$include"
-then
- ipsec _include --inband $config
-else
- cat $config
-fi |
-awk 'BEGIN {
- type = "'"$type"'"
- names = "'"$*"'"
- prefix = "'"$prefix"'"
- export = "'"$export"'"
- optional = 0 + '"$optional"'
- myid = "'"$IPSECmyid"'"
- search = "'"$search"'"
- searching = 0
- if (search != "") {
- searching = 1
- searchpat = search "[ \t]*=[ \t]*"
- }
- fieldfmt = 0
- if ("'"$fieldfmt"'" == "yes")
- fieldfmt = 1
- including = 0
- if ("'"$include"'" == "yes")
- including = 1
- filename = "'"$config"'"
- lineno = 0
- originalfilename = filename
- if (fieldfmt)
- bq = eq = "\""
- else
- bq = eq = "\\\""
- failed = 0
- insection = 0
- wrongtype = 0
- indefault = 0
- outputting = 0
- sawnondefault = 0
- OFS = "\t"
- o_status = "!"
- o_parm = ":"
- o_section = "="
- o_names = "%"
- o_end = "."
- n = split(names, na, " ")
- if (n == 0)
- fail("no section names supplied")
- for (i = 1; i <= n; i++) {
- if (na[i] in wanted)
- fail("section " bq na[i] eq " requested more than once")
- wanted[na[i]] = 1
- pending[na[i]] = 1
- if (!searching && na[i] !~ /^[a-zA-Z][a-zA-Z0-9._-]*$/)
- fail("invalid section name " bq na[i] eq)
- }
-
- good = "also alsoflip type auto authby _plutodevel"
- left = " left leftsubnet leftnexthop leftfirewall lefthostaccess leftupdown"
- akey = " keyexchange auth pfs keylife rekey rekeymargin rekeyfuzz"
- akey = akey " dpdaction dpddelay dpdtimeout"
- akey = akey " pfsgroup compress"
- akey = akey " keyingtries ikelifetime disablearrivalcheck failureshunt ike"
- mkey = " spibase spi esp espenckey espauthkey espreplay_window"
- left = left " leftespenckey leftespauthkey leftahkey"
- left = left " leftespspi leftahspi leftid leftrsasigkey leftrsasigkey2"
- left = left " leftsendcert leftcert leftca leftsubnetwithin leftprotoport"
- left = left " leftgroups leftsourceip"
- mkey = mkey " ah ahkey ahreplay_window"
- right = left
- gsub(/left/, "right", right)
- n = split(good left right akey mkey, g)
- for (i = 1; i <= n; i++)
- goodnames["conn:" g[i]] = 1
-
- good = "also interfaces forwardcontrol myid"
- good = good " syslog klipsdebug plutodebug plutoopts plutostderrlog"
- good = good " plutorestartoncrash"
- good = good " dumpdir manualstart pluto"
- good = good " plutowait prepluto postpluto"
- good = good " fragicmp hidetos rp_filter uniqueids"
- good = good " overridemtu pkcs11module pkcs11keepstate pkcs11proxy"
- good = good " nocrsend strictcrlpolicy crlcheckinterval cachecrls"
- good = good " nat_traversal keep_alive force_keepalive"
- good = good " disable_port_floating virtual_private"
-
- n = split(good, g)
- for (i = 1; i <= n; i++)
- goodnames["config:" g[i]] = 1
-
- good = "auto cacert ldaphost ldapbase crluri crluri2 ocspuri"
- good = good " strictcrlpolicy"
-
- n = split(good, g)
- for (i = 1; i <= n; i++)
- goodnames["ca:" g[i]] = 1
-
- goodtypes["conn"] = 1
- goodtypes["config"] = 1
- goodtypes["ca"] = 1
-
- badchars = ""
- for (i = 1; i < 32; i++)
- badchars = badchars sprintf("%c", i)
- for (i = 127; i < 128+32; i++)
- badchars = badchars sprintf("%c", i)
- badchar = "[" badchars "]"
-
- # if searching, seen is set of sectionnames which match
- # if not searching, seen is set of parameter names found
- seen[""] = ""
- defaults[""] = ""
- usesdefault[""] = ""
- orientation = 1
-}
-
-
-
-function output(code, v1, v2) {
- if (code == o_parm) {
- if (v2 == "") # suppress empty parameters
- return
- if (privatename(v1)) # and private ones
- return
- if (v2 ~ badchar)
- fail("parameter value " bq v2 eq " contains unprintable character")
- }
-
- if (fieldfmt) {
- print code, v1, v2
- return
- }
-
- if (code == o_status) {
- v2 = v1
- v1 = "_confreadstatus"
- } else if (code == o_section) {
- v2 = v1
- v1 = "_confreadsection"
- } else if (code == o_names) {
- v2 = v1
- v1 = "_confreadnames"
- } else if (code != o_parm)
- return # currently no variable version of o_end
-
- print prefix v1 "=\"" v2 "\""
- if (export)
- print "export " prefix v1
-}
-function searchfound(sectionname, n, i, reflist) {
- # a hit in x is a hit in everybody who refers to x too
- n = split(refsto[sectionname], reflist, ";")
- for (i = 1; i <= n; i++)
- if (reflist[i] in seen)
- fail("duplicated parameter " bq search eq)
- else
- seen[reflist[i]] = 1
- seen[sectionname] = 1
-}
-function fail(msg) {
- output(o_status, ("(" filename ", line " lineno ") " msg))
- failed = 1
- while ((getline junk) > 0)
- continue
- exit
-}
-function badname(n) {
- if ((type ":" n) in goodnames)
- return 0
- if (privatename(n))
- return 0
- return 1
-}
-function privatename(n) {
- if (n ~ /^[xX][-_]/)
- return 1
- return 0
-}
-function orient(n) {
- if (orientation == -1) {
- if (n ~ /left/)
- gsub(/left/, "right", n)
- else if (n ~ /right/)
- gsub(/right/, "left", n)
- }
- return n
-}
-# in searching, referencing is transitive: xyz->from->to
-function chainref(from, to, i, reflist, listnum) {
- if (from in refsto) {
- listnum = split(refsto[from], reflist, ";")
- for (i = 1; i <= listnum; i++)
- chainref(reflist[i], to)
- }
- if (to in refsto)
- refsto[to] = refsto[to] ";" from
- else
- refsto[to] = from
-}
-
-# start of rules
-
-{
- lineno++
- # lineno is now the number of this line
-
- # we must remember indentation because comment stripping loses it
- exdented = $0 !~ /^[ \t]/
- sub(/^[ \t]+/, "") # get rid of leading white space
- sub(/[ \t]+$/, "") # get rid of trailing white space
-}
-including && $0 ~ /^#[<>:]/ {
- # _include control line
- if ($1 ~ /^#[<>]$/) {
- filename = $2
- lineno = $3 - 1
- } else if ($0 ~ /^#:/) {
- msg = substr($0, 3)
- gsub(/"/, "\\\"", msg)
- fail(msg)
- }
- next
-}
-exdented {
- # any non-leading-white-space line is a section end
- ### but not the end of relevant stuff, might be also= sections later
- ###if (insection && !indefault && !searching && outputting)
- ### output(o_end)
- insection = 0
- wrongtype = 0
- indefault = 0
- outputting = 0
-}
-/[ \t]#/ {
- # strip trailing comments including the leading whitespace
- # tricky because we must respect quotes
- q = 0
- for (i = 1; i <= NF; i++) {
- if ($i ~ /^#/ && q % 2 == 0) {
- NF = i - 1;
- break
- }
- # using $i in gsub loses whitespace?!?
- junk = $i
- q += gsub(/"/, "&", junk)
- }
-}
-$0 == "" || $0 ~ /^#/ {
- # empty lines and comments are ignored
- next
-}
-exdented && NF != 2 {
- # bad section header
- fail("section header " bq $0 eq " has wrong number of fields (" NF ")")
-}
-exdented && $1 == "version" {
- version = $2 + 0
- if (version < 2.0 || 2.0 < version)
- fail("we only support version 2.0 ipsec.conf files, not " bq version eq)
- next
-}
-version == "" {
- fail("we only support version 2 ipsec.conf files")
-}
-exdented && !($1 in goodtypes) {
- # unknown section type
- fail("section type " bq $1 eq " not recognized")
-}
-exdented && $1 != type {
- # section header, but not of the type we want
- insection = 1
- wrongtype = 1
- next
-}
-extented {
- # type fits
- wrongtype = 0
-}
-exdented && $1 == "config" && $2 != "setup" {
- fail("unknown config section " bq $2 eq)
-}
-exdented && $2 != "%default" {
- # non-default section header of our type
- sawnondefault = 1
-}
-exdented && searching && $2 != "%default" {
- # section header, during search
- insection = 1
- sectionname = $2
- usesdefault[sectionname] = 1 # tentatively
- next
-}
-exdented && !searching && $2 in wanted {
- # one of our wanted section headers
- if (!($2 in pending))
- fail("duplicate " type " section " bq $2 eq)
- delete pending[$2]
- tag = bq type " " $2 eq
- outputting = 1
- insection = 1
- orientation = wanted[$2]
- output(o_section, $2)
- next
-}
-exdented && $2 == "%default" {
- # relevant default section header
- if (sawnondefault)
- fail(bq $1 " %default" eq " sections must precede non-default ones")
- tag = bq type " " $2 eq
- indefault = 1
- next
-}
-exdented {
- # section header, but not one we want
- insection = 1
- next
-}
-!insection && !indefault {
- # starts with white space but not in a section... oops
- fail("parameter is not within a section")
-}
-!wrongtype && searching && $0 ~ searchpat {
- # search found the right parameter name
- match($0, searchpat)
- rest = substr($0, RLENGTH+1)
- if (rest ~ /^".*"$/)
- rest = substr(rest, 2, length(rest)-2)
- if (!indefault) {
- if (!usesdefault[sectionname])
- fail("duplicated parameter " bq search eq)
- usesdefault[sectionname] = 0
- } else if (search in defaults)
- fail("duplicated parameter " bq search eq)
- if (rest in wanted) { # a hit
- if (indefault)
- defaults[search] = rest
- else
- searchfound(sectionname)
- } else {
- # rather a kludge, but must check this somewhere
- if (search == "auto" && rest !~ /^(add|route|start|ignore|manual)$/)
- fail("illegal auto value " bq rest eq)
- }
- next
-}
-!searching && !outputting && !indefault {
- # uninteresting line
- next
-}
-$0 ~ /"/ && $0 !~ /^[^=]+=[ \t]*"[^"]*"$/ {
- if (!searching)
- fail("mismatched quotes in parameter value")
- else
- gsub(/"/, "", $0)
-}
-$0 !~ /^[a-zA-Z_][a-zA-Z0-9_-]*[ \t]*=/ {
- if (searching)
- next # just ignore it
- fail("syntax error or illegal parameter name")
-}
-{
- sub(/[ \t]*=[ \t]*/, "=") # get rid of white space around =
-}
-$0 ~ /^(also|alsoflip)=/ {
- v = orientation
- if ($0 ~ /^alsoflip/)
- v = -v;
- if (indefault)
- fail("%default section may not contain " bq "also" eq " or " bq "alsoflip" eq " parameter")
- sub(/^(also|alsoflip)=/, "")
- if ($0 !~ /^[a-zA-Z][a-zA-Z0-9._-]*$/)
- fail("invalid section name " bq $0 eq)
- if (!searching) {
- if ($0 in wanted)
- fail("section " bq $0 eq " requested more than once")
- wanted[$0] = v
- pending[$0] = 1
- } else
- chainref(sectionname, $0)
- next
-}
-!outputting && !indefault {
- # uninteresting line even for a search
- next
-}
-{
- equal = match($0, /[=]/)
- name = substr($0, 1, equal-1)
- if (badname(name))
- fail("unknown parameter name " bq name eq)
- value = substr($0, equal+1)
- if (value ~ /^"/)
- value = substr(value, 2, length(value)-2)
- else if (value ~ /[ \t]/)
- fail("white space within non-quoted parameter " bq name eq)
-}
-indefault {
- if (name in defaults)
- fail("duplicated default parameter " bq name eq)
- defaults[name] = value
- next
-}
-{
- name = orient(name)
- if (name in seen)
- fail("duplicated parameter " bq name eq)
- seen[name] = 1
- output(o_parm, name, value)
-}
-END {
- if (failed)
- exit 1
-
- filename = originalfilename
- unseen = ""
- for (i in pending)
- unseen = unseen " " i
- if (!optional && !searching && unseen != "")
- fail("did not find " type " section(s) " bq substr(unseen, 2) eq)
- if (!searching) {
- for (name in defaults)
- if (!(name in seen))
- output(o_parm, name, defaults[name])
- } else {
- if (defaults[search] in wanted)
- for (name in usesdefault)
- if (usesdefault[name])
- seen[name] = 1
- delete seen[""]
- if (fieldfmt)
- for (name in seen)
- output(o_section, name)
- else {
- outlist = ""
- for (name in seen)
- if (outlist == "")
- outlist = name
- else
- outlist = outlist " " name
- output(o_names, outlist)
- }
- }
- output(o_status, "")
-}'
diff --git a/programs/_confread/block.in b/programs/_confread/block.in
deleted file mode 100644
index e3a4b2dd5..000000000
--- a/programs/_confread/block.in
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file defines the set of CIDRs (network/mask-length) to which
-# communication should never be allowed.
-#
-# See @FINALDOCDIR@/policygroups.html for details.
-#
-# $Id: block.in,v 1.1 2004/03/15 20:35:27 as Exp $
-#
-
diff --git a/programs/_confread/clear-or-private.in b/programs/_confread/clear-or-private.in
deleted file mode 100644
index 800093d94..000000000
--- a/programs/_confread/clear-or-private.in
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file defines the set of CIDRs (network/mask-length) to which
-# we will communicate in the clear, or, if the other side initiates IPSEC,
-# using encryption. This behaviour is also called "Opportunistic Responder".
-#
-# See @FINALDOCDIR@/policygroups.html for details.
-#
-# $Id: clear-or-private.in,v 1.1 2004/03/15 20:35:27 as Exp $
-#
diff --git a/programs/_confread/clear.in b/programs/_confread/clear.in
deleted file mode 100644
index 46e63388e..000000000
--- a/programs/_confread/clear.in
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file defines the set of CIDRs (network/mask-length) to which
-# communication should always be in the clear.
-#
-# See @FINALDOCDIR@/policygroups.html for details.
-#
-# $Id: clear.in,v 1.1 2004/03/15 20:35:27 as Exp $
-#
diff --git a/programs/_confread/ipsec.conf.5 b/programs/_confread/ipsec.conf.5
deleted file mode 100644
index af6fae6bd..000000000
--- a/programs/_confread/ipsec.conf.5
+++ /dev/null
@@ -1,1286 +0,0 @@
-.TH IPSEC.CONF 5 "20 Jan 2006"
-.\" RCSID $Id: ipsec.conf.5,v 1.2 2006/01/22 15:33:46 as Exp $
-.SH NAME
-ipsec.conf \- IPsec configuration and connections
-.SH DESCRIPTION
-The optional
-.I ipsec.conf
-file
-specifies most configuration and control information for the
-strongSwan IPsec subsystem.
-(The major exception is secrets for authentication;
-see
-.IR ipsec.secrets (5).)
-Its contents are not security-sensitive
-.I unless
-manual keying is being done for more than just testing,
-in which case the encryption/authentication keys in the
-descriptions for the manually-keyed connections are very sensitive
-(and those connection descriptions
-are probably best kept in a separate file,
-via the include facility described below).
-.PP
-The file is a text file, consisting of one or more
-.IR sections .
-White space followed by
-.B #
-followed by anything to the end of the line
-is a comment and is ignored,
-as are empty lines which are not within a section.
-.PP
-A line which contains
-.B include
-and a file name, separated by white space,
-is replaced by the contents of that file,
-preceded and followed by empty lines.
-If the file name is not a full pathname,
-it is considered to be relative to the directory containing the
-including file.
-Such inclusions can be nested.
-Only a single filename may be supplied, and it may not contain white space,
-but it may include shell wildcards (see
-.IR sh (1));
-for example:
-.PP
-.B include
-.B "ipsec.*.conf"
-.PP
-The intention of the include facility is mostly to permit keeping
-information on connections, or sets of connections,
-separate from the main configuration file.
-This permits such connection descriptions to be changed,
-copied to the other security gateways involved, etc.,
-without having to constantly extract them from the configuration
-file and then insert them back into it.
-Note also the
-.B also
-parameter (described below) which permits splitting a single logical
-section (e.g. a connection description) into several actual sections.
-.PP
-The first significant line of the file must specify the version
-of this specification that it conforms to:
-.PP
-\fBversion 2\fP
-.PP
-A section
-begins with a line of the form:
-.PP
-.I type
-.I name
-.PP
-where
-.I type
-indicates what type of section follows, and
-.I name
-is an arbitrary name which distinguishes the section from others
-of the same type.
-(Names must start with a letter and may contain only
-letters, digits, periods, underscores, and hyphens.)
-All subsequent non-empty lines
-which begin with white space are part of the section;
-comments within a section must begin with white space too.
-There may be only one section of a given type with a given name.
-.PP
-Lines within the section are generally of the form
-.PP
-\ \ \ \ \ \fIparameter\fB=\fIvalue\fR
-.PP
-(note the mandatory preceding white space).
-There can be white space on either side of the
-.BR = .
-Parameter names follow the same syntax as section names,
-and are specific to a section type.
-Unless otherwise explicitly specified,
-no parameter name may appear more than once in a section.
-.PP
-An empty
-.I value
-stands for the system default value (if any) of the parameter,
-i.e. it is roughly equivalent to omitting the parameter line entirely.
-A
-.I value
-may contain white space only if the entire
-.I value
-is enclosed in double quotes (\fB"\fR);
-a
-.I value
-cannot itself contain a double quote,
-nor may it be continued across more than one line.
-.PP
-Numeric values are specified to be either an ``integer''
-(a sequence of digits) or a ``decimal number''
-(sequence of digits optionally followed by `.' and another sequence of digits).
-.PP
-There is currently one parameter which is available in any type of
-section:
-.TP
-.B also
-the value is a section name;
-the parameters of that section are appended to this section,
-as if they had been written as part of it.
-The specified section must exist, must follow the current one,
-and must have the same section type.
-(Nesting is permitted,
-and there may be more than one
-.B also
-in a single section,
-although it is forbidden to append the same section more than once.)
-This allows, for example, keeping the encryption keys
-for a connection in a separate file
-from the rest of the description, by using both an
-.B also
-parameter and an
-.B include
-line.
-.PP
-Parameter names beginning with
-.B x-
-(or
-.BR X- ,
-or
-.BR x_ ,
-or
-.BR X_ )
-are reserved for user extensions and will never be assigned meanings
-by IPsec.
-Parameters with such names must still observe the syntax rules
-(limits on characters used in the name;
-no white space in a non-quoted value;
-no newlines or double quotes within the value).
-All other as-yet-unused parameter names are reserved for future IPsec
-improvements.
-.PP
-A section with name
-.B %default
-specifies defaults for sections of the same type.
-For each parameter in it,
-any section of that type which does not have a parameter of the same name
-gets a copy of the one from the
-.B %default
-section.
-There may be multiple
-.B %default
-sections of a given type,
-but only one default may be supplied for any specific parameter name,
-and all
-.B %default
-sections of a given type must precede all non-\c
-.B %default
-sections of that type.
-.B %default
-sections may not contain the
-.B also
-parameter.
-.PP
-Currently there are three types of sections:
-a
-.B config
-section specifies general configuration information for IPsec, a
-.B conn
-section specifies an IPsec connection, while a
-.B ca
-section specifies special properties a certification authority.
-.SH "CONN SECTIONS"
-A
-.B conn
-section contains a
-.IR "connection specification" ,
-defining a network connection to be made using IPsec.
-The name given is arbitrary, and is used to identify the connection to
-.IR ipsec_auto (8)
-and
-.IR ipsec_manual (8).
-Here's a simple example:
-.PP
-.ne 10
-.nf
-.ft B
-.ta 1c
-conn snt
- left=10.11.11.1
- leftsubnet=10.0.1.0/24
- leftnexthop=172.16.55.66
- right=192.168.22.1
- rightsubnet=10.0.2.0/24
- rightnexthop=172.16.88.99
- keyingtries=%forever
-.ft
-.fi
-.PP
-A note on terminology...
-In automatic keying, there are two kinds of communications going on:
-transmission of user IP packets, and gateway-to-gateway negotiations for
-keying, rekeying, and general control.
-The data path (a set of ``IPsec SAs'') used for user packets is herein
-referred to as the ``connection'';
-the path used for negotiations (built with ``ISAKMP SAs'') is referred to as
-the ``keying channel''.
-.PP
-To avoid trivial editing of the configuration file to suit it to each system
-involved in a connection,
-connection specifications are written in terms of
-.I left
-and
-.I right
-participants,
-rather than in terms of local and remote.
-Which participant is considered
-.I left
-or
-.I right
-is arbitrary;
-IPsec figures out which one it is being run on based on internal information.
-This permits using identical connection specifications on both ends.
-There are cases where there is no symmetry; a good convention is to
-use
-.I left
-for the local side and
-.I right
-for the remote side (the first letters are a good mnemonic).
-.PP
-Many of the parameters relate to one participant or the other;
-only the ones for
-.I left
-are listed here, but every parameter whose name begins with
-.B left
-has a
-.B right
-counterpart,
-whose description is the same but with
-.B left
-and
-.B right
-reversed.
-.PP
-Parameters are optional unless marked ``(required)'';
-a parameter required for manual keying need not be included for
-a connection which will use only automatic keying, and vice versa.
-.SS "CONN PARAMETERS: GENERAL"
-The following parameters are relevant to both automatic and manual keying.
-Unless otherwise noted,
-for a connection to work,
-in general it is necessary for the two ends to agree exactly
-on the values of these parameters.
-.TP 14
-.B type
-the type of the connection; currently the accepted values
-are
-.B tunnel
-(the default)
-signifying a host-to-host, host-to-subnet, or subnet-to-subnet tunnel;
-.BR transport ,
-signifying host-to-host transport mode;
-.BR passthrough ,
-signifying that no IPsec processing should be done at all;
-.BR drop ,
-signifying that packets should be discarded; and
-.BR reject ,
-signifying that packets should be discarded and a diagnostic ICMP returned.
-.TP
-.B left
-(required)
-the IP address of the left participant's public-network interface,
-in any form accepted by
-.IR ipsec_ttoaddr (3)
-or one of several magic values.
-If it is
-.BR %defaultroute ,
-and
-the
-.B config
-.B setup
-section's,
-.B interfaces
-specification contains
-.BR %defaultroute,
-.B left
-will be filled in automatically with the local address
-of the default-route interface (as determined at IPsec startup time);
-this also overrides any value supplied for
-.BR leftnexthop .
-(Either
-.B left
-or
-.B right
-may be
-.BR %defaultroute ,
-but not both.)
-The value
-.B %any
-signifies an address to be filled in (by automatic keying) during
-negotiation.
-The value
-.B %opportunistic
-signifies that both
-.B left
-and
-.B leftnexthop
-are to be filled in (by automatic keying) from DNS data for
-.BR left 's
-client.
-The values
-.B %group
-and
-.B %opportunisticgroup
-makes this a policy group conn: one that will be instantiated
-into a regular or opportunistic conn for each CIDR block listed in the
-policy group file with the same name as the conn.
-.TP
-.B leftsubnet
-private subnet behind the left participant, expressed as
-\fInetwork\fB/\fInetmask\fR
-(actually, any form acceptable to
-.IR ipsec_ttosubnet (3));
-if omitted, essentially assumed to be \fIleft\fB/32\fR,
-signifying that the left end of the connection goes to the left participant only
-.TP
-.B leftnexthop
-next-hop gateway IP address for the left participant's connection
-to the public network;
-defaults to
-.B %direct
-(meaning
-.IR right ).
-If the value is to be overridden by the
-.B left=%defaultroute
-method (see above),
-an explicit value must
-.I not
-be given.
-If that method is not being used,
-but
-.B leftnexthop
-is
-.BR %defaultroute ,
-and
-.B interfaces=%defaultroute
-is used in the
-.B config
-.B setup
-section,
-the next-hop gateway address of the default-route interface
-will be used.
-The magic value
-.B %direct
-signifies a value to be filled in (by automatic keying)
-with the peer's address.
-Relevant only locally, other end need not agree on it.
-.TP
-.B leftupdown
-what ``updown'' script to run to adjust routing and/or firewalling
-when the status of the connection
-changes (default
-.BR "ipsec _updown" ).
-May include positional parameters separated by white space
-(although this requires enclosing the whole string in quotes);
-including shell metacharacters is unwise.
-See
-.IR ipsec_pluto (8)
-for details.
-Relevant only locally, other end need not agree on it.
-.TP
-.B leftfirewall
-whether the left participant is doing forwarding-firewalling
-(including masquerading) for traffic from \fIleftsubnet\fR,
-which should be turned off (for traffic to the other subnet)
-once the connection is established;
-acceptable values are
-.B yes
-and (the default)
-.BR no .
-May not be used in the same connection description with
-.BR leftupdown .
-Implemented as a parameter to the default
-.I updown
-script.
-See notes below.
-Relevant only locally, other end need not agree on it.
-.PP
-If one or both security gateways are doing forwarding firewalling
-(possibly including masquerading),
-and this is specified using the firewall parameters,
-tunnels established with IPsec are exempted from it
-so that packets can flow unchanged through the tunnels.
-(This means that all subnets connected in this manner must have
-distinct, non-overlapping subnet address blocks.)
-This is done by the default
-.I updown
-script (see
-.IR ipsec_pluto (8)).
-.PP
-The implementation of this makes certain assumptions about firewall setup,
-notably the use of the old
-.I ipfwadm
-interface to the firewall.
-In situations calling for more control,
-it may be preferable for the user to supply his own
-.I updown
-script,
-which makes the appropriate adjustments for his system.
-.SS "CONN PARAMETERS: AUTOMATIC KEYING"
-The following parameters are relevant only to automatic keying,
-and are ignored in manual keying.
-Unless otherwise noted,
-for a connection to work,
-in general it is necessary for the two ends to agree exactly
-on the values of these parameters.
-.TP 14
-.B auto
-what operation, if any, should be done automatically at IPsec startup;
-currently-accepted values are
-.B add
-(signifying an
-.B ipsec auto
-.BR \-\-add ),
-.B route
-(signifying that plus an
-.B ipsec auto
-.BR \-\-route ),
-.B start
-(signifying that plus an
-.B ipsec auto
-.BR \-\-up ),
-.B manual
-(signifying an
-.B ipsec
-.B manual
-.BR \-\-up ),
-and
-.B ignore
-(also the default) (signifying no automatic startup operation).
-See the
-.B config
-.B setup
-discussion below.
-Relevant only locally, other end need not agree on it
-(but in general, for an intended-to-be-permanent connection,
-both ends should use
-.B auto=start
-to ensure that any reboot causes immediate renegotiation).
-.TP
-.B auth
-whether authentication should be done as part of
-ESP encryption, or separately using the AH protocol;
-acceptable values are
-.B esp
-(the default) and
-.BR ah .
-.TP
-.B authby
-how the two security gateways should authenticate each other;
-acceptable values are
-.B secret
-for shared secrets,
-.B rsasig
-for RSA digital signatures (the default),
-.B secret|rsasig
-for either, and
-.B never
-if negotiation is never to be attempted or accepted (useful for shunt-only conns).
-Digital signatures are superior in every way to shared secrets.
-.TP
-.B compress
-whether IPComp compression of content is proposed on the connection
-(link-level compression does not work on encrypted data,
-so to be effective, compression must be done \fIbefore\fR encryption);
-acceptable values are
-.B yes
-and
-.B no
-(the default).
-The two ends need not agree.
-A value of
-.B yes
-causes IPsec to propose both compressed and uncompressed,
-and prefer compressed.
-A value of
-.B no
-prevents IPsec from proposing compression;
-a proposal to compress will still be accepted.
-.TP
-.B disablearrivalcheck
-whether KLIPS's normal tunnel-exit check
-(that a packet emerging from a tunnel has plausible addresses in its header)
-should be disabled;
-acceptable values are
-.B yes
-and
-.B no
-(the default).
-Tunnel-exit checks improve security and do not break any normal configuration.
-Relevant only locally, other end need not agree on it.
-.TP
-.B dpdaction
-controls the use of the Dead Peer Detection protocol (DPD, RFC 3706) where
-R_U_THERE IKE notification messages are periodically sent in order to check the
-liveliness of the IPsec peer. The default is..
-.B none
-which disables the active sending of R_U_THERE notifications.
-Nevertheless pluto will always send the DPD Vendor ID during connection set up
-in order to signal the readiness to act passively as a responder if the peer
-wants to use DPD. The values
-.B clear
-and
-.B hold
-both activate DPD. If no activity is detected, all connections with a dead peer
-are stopped and unrouted (
-.B clear
-) or put in the hold state (
-.B hold
-).
-.TP
-.B dpddelay
-defines the period time interval with which R_U_THERE messages are sent to the peer.
-.TP
-.B dpdtimeout
-defines the timeout interval, after which all connections to a peer are deleted
-in case of inactivity.
-.TP
-.B failureshunt
-what to do with packets when negotiation fails.
-The default is
-.BR none :
-no shunt;
-.BR passthrough ,
-.BR drop ,
-and
-.B reject
-have the obvious meanings.
-.TP
-.B ikelifetime
-how long the keying channel of a connection (buzzphrase: ``ISAKMP SA'')
-should last before being renegotiated;
-acceptable values as for
-.B keyexchange
-method of key exchange;
-the default and currently the only accepted value is
-.B ike
-.TP
-.B keylife
-(default set by
-.IR ipsec_pluto (8),
-currently
-.BR 3h ,
-maximum
-.BR 24h ).
-The two-ends-disagree case is similar to that of
-.BR keylife .
-.TP
-.B keyingtries
-how many attempts (a whole number or \fB%forever\fP) should be made to
-negotiate a connection, or a replacement for one, before giving up
-(default
-.BR %forever ).
-The value \fB%forever\fP
-means ``never give up'' (obsolete: this can be written \fB0\fP).
-Relevant only locally, other end need not agree on it.
-.TP
-.B keylife
-how long a particular instance of a connection
-(a set of encryption/authentication keys for user packets) should last,
-from successful negotiation to expiry;
-acceptable values are an integer optionally followed by
-.BR s
-(a time in seconds)
-or a decimal number followed by
-.BR m ,
-.BR h ,
-or
-.B d
-(a time
-in minutes, hours, or days respectively)
-(default
-.BR 1h ,
-maximum
-.BR 24h ).
-Normally, the connection is renegotiated (via the keying channel)
-before it expires.
-The two ends need not exactly agree on
-.BR keylife ,
-although if they do not,
-there will be some clutter of superseded connections on the end
-which thinks the lifetime is longer.
-.TP
-.B leftca
-the distinguished name of a certificate authority which is required to
-lie in the trust path going from the left participant's certificate up
-to the root certification authority.
-.TP
-.B leftcert
-the path to the left participant's X.509 certificate. The file can be coded either in
-PEM or DER format. OpenPGP certificates are supported as well.
-Both absolute paths or paths relative to
-.B /etc/ipsec.d/certs
-are accepted. By default
-.B leftcert
-sets
-.B leftid
-to the distinguished name of the certificate's subject and
-.B leftca
-to the distinguished name of the certificate's issuer.
-The left participant's ID can be overriden by specifying a
-.B leftid
-value which must be certified by the certificate, though.
-.TP
-.B leftgroups
-a comma separated list of group names. If the
-.B leftgroups
-parameter is present then the peer must be a member of at least one
-of the groups defined by the parameter. Group membership must be certified
-by a valid attribute certificate stored in \fI/etc/ipsec.d/acerts\fP thas has been
-issued to the peer by a trusted Authorization Authority stored in
-\fI/etc/ipsec.d/aacerts\fP.
-.TP
-.B leftid
-how
-the left participant
-should be identified for authentication;
-defaults to
-.BR left .
-Can be an IP address (in any
-.IR ipsec_ttoaddr (3)
-syntax)
-or a fully-qualified domain name preceded by
-.B @
-(which is used as a literal string and not resolved).
-The magic value
-.B %myid
-stands for the current setting of \fImyid\fP.
-This is set in \fBconfig setup\fP or by \fIipsec_whack\fP(8)), or, if not set,
-it is the IP address in \fB%defaultroute\fP (if that is supported by a TXT record in its reverse domain), or otherwise
-it is the system's hostname (if that is supported by a TXT record in its forward domain), or otherwise it is undefined.
-.TP
-.B leftrsasigkey
-the left participant's
-public key for RSA signature authentication,
-in RFC 2537 format using
-.IR ipsec_ttodata (3)
-encoding.
-The magic value
-.B %none
-means the same as not specifying a value (useful to override a default).
-The value
-.B %cert
-(the default)
-means that the key is extracted from a certificate.
-The value
-.B %dnsondemand
-means the key is to be fetched from DNS at the time it is needed.
-The value
-.B %dnsonload
-means the key is to be fetched from DNS at the time
-the connection description is read from
-.IR ipsec.conf ;
-currently this will be treated as
-.B %none
-if
-.B right=%any
-or
-.BR right=%opportunistic .
-The value
-.B %dns
-is currently treated as
-.B %dnsonload
-but will change to
-.B %dnsondemand
-in the future.
-The identity used for the left participant
-must be a specific host, not
-.B %any
-or another magic value.
-.B Caution:
-if two connection descriptions
-specify different public keys for the same
-.BR leftid ,
-confusion and madness will ensue.
-.TP
-.B leftrsasigkey2
-if present, a second public key.
-Either key can authenticate the signature, allowing for key rollover.
-.TP
-.B leftsourceip
-.TP
-.B leftsubnetwithin
-.TP
-.B pfs
-whether Perfect Forward Secrecy of keys is desired on the connection's
-keying channel
-(with PFS, penetration of the key-exchange protocol
-does not compromise keys negotiated earlier);
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-.TP
-.B rekey
-whether a connection should be renegotiated when it is about to expire;
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-The two ends need not agree,
-but while a value of
-.B no
-prevents Pluto from requesting renegotiation,
-it does not prevent responding to renegotiation requested from the other end,
-so
-.B no
-will be largely ineffective unless both ends agree on it.
-.TP
-.B rekeyfuzz
-maximum percentage by which
-.B rekeymargin
-should be randomly increased to randomize rekeying intervals
-(important for hosts with many connections);
-acceptable values are an integer,
-which may exceed 100,
-followed by a `%'
-(default set by
-.IR ipsec_pluto (8),
-currently
-.BR 100% ).
-The value of
-.BR rekeymargin ,
-after this random increase,
-must not exceed
-.BR keylife .
-The value
-.B 0%
-will suppress time randomization.
-Relevant only locally, other end need not agree on it.
-.TP
-.B rekeymargin
-how long before connection expiry or keying-channel expiry
-should attempts to
-negotiate a replacement
-begin; acceptable values as for
-.B keylife
-(default
-.BR 9m ).
-Relevant only locally, other end need not agree on it.
-.SS "CONN PARAMETERS: MANUAL KEYING"
-The following parameters are relevant only to manual keying,
-and are ignored in automatic keying.
-Unless otherwise noted,
-for a connection to work,
-in general it is necessary for the two ends to agree exactly
-on the values of these parameters.
-A manually-keyed
-connection must specify at least one of AH or ESP.
-.TP 14
-.B spi
-(this or
-.B spibase
-required for manual keying)
-the SPI number to be used for the connection (see
-.IR ipsec_manual (8));
-must be of the form \fB0x\fIhex\fB\fR,
-where
-.I hex
-is one or more hexadecimal digits
-(note, it will generally be necessary to make
-.I spi
-at least
-.B 0x100
-to be acceptable to KLIPS,
-and use of SPIs in the range
-.BR 0x100 - 0xfff
-is recommended)
-.TP 14
-.B spibase
-(this or
-.B spi
-required for manual keying)
-the base number for the SPIs to be used for the connection (see
-.IR ipsec_manual (8));
-must be of the form \fB0x\fIhex\fB0\fR,
-where
-.I hex
-is one or more hexadecimal digits
-(note, it will generally be necessary to make
-.I spibase
-at least
-.B 0x100
-for the resulting SPIs
-to be acceptable to KLIPS,
-and use of numbers in the range
-.BR 0x100 - 0xff0
-is recommended)
-.TP
-.B esp
-ESP encryption/authentication algorithm to be used
-for the connection, e.g.
-.B 3des-md5-96
-(must be suitable as a value of
-.IR ipsec_spi (8)'s
-.B \-\-esp
-option);
-default is not to use ESP
-.TP
-.B espenckey
-ESP encryption key
-(must be suitable as a value of
-.IR ipsec_spi (8)'s
-.B \-\-enckey
-option)
-(may be specified separately for each direction using
-.B leftespenckey
-(leftward SA)
-and
-.B rightespenckey
-parameters)
-.TP
-.B espauthkey
-ESP authentication key
-(must be suitable as a value of
-.IR ipsec_spi (8)'s
-.B \-\-authkey
-option)
-(may be specified separately for each direction using
-.B leftespauthkey
-(leftward SA)
-and
-.B rightespauthkey
-parameters)
-.TP
-.B espreplay_window
-ESP replay-window setting,
-an integer from
-.B 0
-(the
-.IR ipsec_manual
-default, which turns off replay protection) to
-.BR 64 ;
-relevant only if ESP authentication is being used
-.TP
-.B leftespspi
-SPI to be used for the leftward ESP SA, overriding
-automatic assignment using
-.B spi
-or
-.BR spibase ;
-typically a hexadecimal number beginning with
-.B 0x
-.TP
-.B ah
-AH authentication algorithm to be used
-for the connection, e.g.
-.B hmac-md5-96
-(must be suitable as a value of
-.IR ipsec_spi (8)'s
-.B \-\-ah
-option);
-default is not to use AH
-.TP
-.B ahkey
-(required if
-.B ah
-is present) AH authentication key
-(must be suitable as a value of
-.IR ipsec_spi (8)'s
-.B \-\-authkey
-option)
-(may be specified separately for each direction using
-.B leftahkey
-(leftward SA)
-and
-.B rightahkey
-parameters)
-.TP
-.B ahreplay_window
-AH replay-window setting,
-an integer from
-.B 0
-(the
-.I ipsec_manual
-default, which turns off replay protection) to
-.B 64
-.TP
-.B leftahspi
-SPI to be used for the leftward AH SA, overriding
-automatic assignment using
-.B spi
-or
-.BR spibase ;
-typically a hexadecimal number beginning with
-.B 0x
-.SH "CA SECTIONS"
-This are optional sections that can be used to assign special
-parameters to a Certification Authority (CA).
-.TP 10
-.B auto
-currently can have either the value
-.B ignore
-or
-.B add
-.
-.TP
-.B cacert
-defines a path to the CA certificate either relative to
-\fI/etc/ipsec.d/cacerts\fP or as an absolute path.
-.TP
-.B crluri
-defines a CRL distribution point (ldap, http, or file URI)
-.TP
-.B crluri2
-defines an alternative CRL distribution point (ldap, http, or file URI)
-.TP
-.B ldaphost
-defines an ldap host.
-.TP
-.B ocspuri
-defines an OCSP URI.
-.SH "CONFIG SECTIONS"
-At present, the only
-.B config
-section known to the IPsec software is the one named
-.BR setup ,
-which contains information used when the software is being started
-(see
-.IR ipsec_setup (8)).
-Here's an example:
-.PP
-.ne 8
-.nf
-.ft B
-.ta 1c
-config setup
- interfaces="ipsec0=eth1 ipsec1=ppp0"
- klipsdebug=none
- plutodebug=all
- manualstart=
-.ft
-.fi
-.PP
-Parameters are optional unless marked ``(required)''.
-The currently-accepted
-.I parameter
-names in a
-.B config
-.B setup
-section are:
-.TP 14
-.B myid
-the identity to be used for
-.BR %myid .
-.B %myid
-is used in the implicit policy group conns and can be used as
-an identity in explicit conns.
-If unspecified,
-.B %myid
-is set to the IP address in \fB%defaultroute\fP (if that is supported by a TXT record in its reverse domain), or otherwise
-the system's hostname (if that is supported by a TXT record in its forward domain), or otherwise it is undefined.
-An explicit value generally starts with ``\fB@\fP''.
-.TP
-.B interfaces
-virtual and physical interfaces for IPsec to use:
-a single
-\fIvirtual\fB=\fIphysical\fR pair, a (quoted!) list of pairs separated
-by white space, or
-.BR %none .
-One of the pairs may be written as
-.BR %defaultroute ,
-which means: find the interface \fId\fR that the default route points to,
-and then act as if the value was ``\fBipsec0=\fId\fR''.
-.B %defaultroute
-is the default;
-.B %none
-must be used to denote no interfaces.
-If
-.B %defaultroute
-is used (implicitly or explicitly)
-information about the default route and its interface is noted for
-use by
-.IR ipsec_manual (8)
-and
-.IR ipsec_auto (8).)
-.TP
-.B forwardcontrol
-whether
-.I setup
-should turn IP forwarding on
-(if it's not already on) as IPsec is started,
-and turn it off again (if it was off) as IPsec is stopped;
-acceptable values are
-.B yes
-and (the default)
-.BR no .
-For this to have full effect, forwarding must be
-disabled before the hardware interfaces are brought
-up (e.g.,
-.B "net.ipv4.ip_forward\ =\ 0"
-in Red Hat 6.x
-.IR /etc/sysctl.conf ),
-because IPsec doesn't get control early enough to do that.
-.TP
-.B rp_filter
-whether and how
-.I setup
-should adjust the reverse path filtering mechanism for the
-physical devices to be used.
-Values are \fB%unchanged\fP (to leave it alone)
-or \fB0\fP, \fB1\fP, \fB2\fP (values to set it to).
-\fI/proc/sys/net/ipv4/conf/PHYS/rp_filter\fP
-is badly documented; it must be \fB0\fP in many cases
-for ipsec to function.
-The default value for the parameter is \fB0\fP.
-.TP
-.B syslog
-the
-.IR syslog (2)
-``facility'' name and priority to use for
-startup/shutdown log messages,
-default
-.BR daemon.error .
-.TP
-.B klipsdebug
-how much KLIPS debugging output should be logged.
-An empty value,
-or the magic value
-.BR none ,
-means no debugging output (the default).
-The magic value
-.B all
-means full output.
-Otherwise only the specified types of output
-(a quoted list, names separated by white space) are enabled;
-for details on available debugging types, see
-.IR ipsec_klipsdebug (8).
-.TP
-.B plutodebug
-how much Pluto debugging output should be logged.
-An empty value,
-or the magic value
-.BR none ,
-means no debugging output (the default).
-The magic value
-.B all
-means full output.
-Otherwise only the specified types of output
-(a quoted list, names without the
-.B \-\-debug\-
-prefix,
-separated by white space) are enabled;
-for details on available debugging types, see
-.IR ipsec_pluto (8).
-.TP
-.B plutoopts
-additional options to pass to pluto upon startup. See
-.IR ipsec_pluto (8).
-.TP
-.B plutostderrlog
-do not use syslog, but rather log to stderr, and direct stderr to the
-argument file.
-.TP
-.B dumpdir
-in what directory should things started by
-.I setup
-(notably the Pluto daemon) be allowed to
-dump core?
-The empty value (the default) means they are not
-allowed to.
-.TP
-.B manualstart
-which manually-keyed connections to set up at startup
-(empty, a name, or a quoted list of names separated by white space);
-see
-.IR ipsec_manual (8).
-Default is none.
-.TP
-.B pluto
-whether to start Pluto or not;
-Values are
-.B yes
-(the default)
-or
-.B no
-(useful only in special circumstances).
-.TP
-.B plutowait
-should Pluto wait for each
-negotiation attempt that is part of startup to
-finish before proceeding with the next?
-Values are
-.B yes
-or
-.BR no
-(the default).
-.TP
-.B prepluto
-shell command to run before starting Pluto
-(e.g., to decrypt an encrypted copy of the
-.I ipsec.secrets
-file).
-It's run in a very simple way;
-complexities like I/O redirection are best hidden within a script.
-Any output is redirected for logging,
-so running interactive commands is difficult unless they use
-.I /dev/tty
-or equivalent for their interaction.
-Default is none.
-.TP
-.B postpluto
-shell command to run after starting Pluto
-(e.g., to remove a decrypted copy of the
-.I ipsec.secrets
-file).
-It's run in a very simple way;
-complexities like I/O redirection are best hidden within a script.
-Any output is redirected for logging,
-so running interactive commands is difficult unless they use
-.I /dev/tty
-or equivalent for their interaction.
-Default is none.
-.TP
-.B fragicmp
-whether a tunnel's need to fragment a packet should be reported
-back with an ICMP message,
-in an attempt to make the sender lower his PMTU estimate;
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-.TP
-.B hidetos
-whether a tunnel packet's TOS field should be set to
-.B 0
-rather than copied from the user packet inside;
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-.TP
-.B uniqueids
-whether a particular participant ID should be kept unique,
-with any new (automatically keyed)
-connection using an ID from a different IP address
-deemed to replace all old ones using that ID;
-acceptable values are
-.B yes
-(the default)
-and
-.BR no .
-Participant IDs normally \fIare\fR unique,
-so a new (automatically-keyed) connection using the same ID is
-almost invariably intended to replace an old one.
-.TP
-.B overridemtu
-value that the MTU of the ipsec\fIn\fR interface(s) should be set to,
-overriding IPsec's (large) default.
-This parameter is needed only in special situations.
-.TP
-.B nat_traversal
-.TP
-.B crlcheckinterval
-.TP
-.B strictcrlpolicy
-.TP
-.B pkcs11module
-.TP
-.B pkcs11keepstate
-
-.SH CHOOSING A CONNECTION
-.PP
-When choosing a connection to apply to an outbound packet caught with a
-.BR %trap,
-the system prefers the one with the most specific eroute that
-includes the packet's source and destination IP addresses.
-Source subnets are examined before destination subnets.
-For initiating, only routed connections are considered. For responding,
-unrouted but added connections are considered.
-.PP
-When choosing a connection to use to respond to a negotiation which
-doesn't match an ordinary conn, an opportunistic connection
-may be instantiated. Eventually, its instance will be /32 -> /32, but
-for earlier stages of the negotiation, there will not be enough
-information about the client subnets to complete the instantiation.
-.SH FILES
-.nf
-/etc/ipsec.conf
-/etc/ipsec.d/cacerts
-/etc/ipsec.d/certs
-/etc/ipsec.d/crls
-/etc/ipsec.d/aacerts
-/etc/ipsec.d/acerts
-
-.SH SEE ALSO
-ipsec(8), ipsec_ttoaddr(8), ipsec_auto(8), ipsec_manual(8), ipsec_rsasigkey(8)
-.SH HISTORY
-Written for the FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer. Extended for the strongSwan project
-<http://www.strongswan.org>
-by Andreas Steffen.
-.SH BUGS
-.PP
-When
-.B type
-or
-.B failureshunt
-is set to
-.B drop
-or
-.BR reject,
-strongSwan blocks outbound packets using eroutes, but assumes inbound
-blocking is handled by the firewall. strongSwan offers firewall hooks
-via an ``updown'' script. However, the default
-.B ipsec _updown
-provides no help in controlling a modern firewall.
-.PP
-Including attributes of the keying channel
-(authentication methods,
-.BR ikelifetime ,
-etc.)
-as an attribute of a connection,
-rather than of a participant pair, is dubious and incurs limitations.
-.PP
-.IR Ipsec_manual
-is not nearly as generous about the syntax of subnets,
-addresses, etc. as the usual strongSwan user interfaces.
-Four-component dotted-decimal must be used for all addresses.
-It
-.I is
-smart enough to translate bit-count netmasks to dotted-decimal form.
-.PP
-It would be good to have a line-continuation syntax,
-especially for the very long lines involved in
-RSA signature keys.
-.PP
-The ability to specify different identities,
-.BR authby ,
-and public keys for different automatic-keyed connections
-between the same participants is misleading;
-this doesn't work dependably because the identity of the participants
-is not known early enough.
-This is especially awkward for the ``Road Warrior'' case,
-where the remote IP address is specified as
-.BR 0.0.0.0 ,
-and that is considered to be the ``participant'' for such connections.
-.PP
-In principle it might be necessary to control MTU on an
-interface-by-interface basis,
-rather than with the single global override that
-.B overridemtu
-provides.
-.PP
-A number of features which \fIcould\fR be implemented in
-both manual and automatic keying
-actually are not yet implemented for manual keying.
-This is unlikely to be fixed any time soon.
-.PP
-If conns are to be added before DNS is available,
-\fBleft=\fP\fIFQDN\fP,
-\fBleftnextop=\fP\fIFQDN\fP,
-and
-.B leftrsasigkey=%dnsonload
-will fail.
-.IR ipsec_pluto (8)
-does not actually use the public key for our side of a conn but it
-isn't generally known at a add-time which side is ours (Road Warrior
-and Opportunistic conns are currently exceptions).
-.PP
-The \fBmyid\fP option does not affect explicit \fB ipsec auto \-\-add\fP or \fBipsec auto \-\-replace\fP commands for implicit conns.
diff --git a/programs/_confread/ipsec.conf.in b/programs/_confread/ipsec.conf.in
deleted file mode 100644
index 296986459..000000000
--- a/programs/_confread/ipsec.conf.in
+++ /dev/null
@@ -1,44 +0,0 @@
-# /etc/ipsec.conf - strongSwan IPsec configuration file
-
-# RCSID $Id: ipsec.conf.in,v 1.7 2006/01/31 13:09:10 as Exp $
-
-# Manual: ipsec.conf.5
-# Help: http://www.strongswan.org/docs/readme.htm
-
-version 2.0 # conforms to second version of ipsec.conf specification
-
-# basic configuration
-
-config setup
- # Debug-logging controls: "none" for (almost) none, "all" for lots.
- # plutodebug=all
- # crlcheckinterval=600
- # strictcrlpolicy=yes
- # cachecrls=yes
- # nat_traversal=yes
-
-# Uncomment to activate Opportunistic Encryption (OE)
-# include /etc/ipsec.d/examples/oe.conf
-
-# Add connections here.
-
-# Sample VPN connections
-
-#conn sample-self-signed
-# left=%defaultroute
-# leftsubnet=10.1.0.0/16
-# leftcert=selfCert.der
-# leftsendcert=never
-# right=192.168.0.2
-# rightsubnet=10.2.0.0/16
-# rightcert=peerCert.der
-# auto=start
-
-#conn sample-with-ca-cert
-# left=%defaultroute
-# leftsubnet=10.1.0.0/16
-# leftcert=myCert.pem
-# right=192.168.0.2
-# rightsubnet=10.2.0.0/16
-# rightid="C=CH, O=Linux strongSwan CN=peer name"
-# auto=start
diff --git a/programs/_confread/private-or-clear.in b/programs/_confread/private-or-clear.in
deleted file mode 100644
index c66b1d29f..000000000
--- a/programs/_confread/private-or-clear.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file defines the set of CIDRs (network/mask-length) to which
-# communication should be private, if possible, but in the clear otherwise.
-#
-# If the target has a TXT (later IPSECKEY) record that specifies
-# authentication material, we will require private (i.e. encrypted)
-# communications. If no such record is found, communications will be
-# in the clear.
-#
-# See @FINALDOCDIR@/policygroups.html for details.
-#
-# $Id: private-or-clear.in,v 1.1 2004/03/15 20:35:27 as Exp $
-#
-
-0.0.0.0/0
diff --git a/programs/_confread/private.in b/programs/_confread/private.in
deleted file mode 100644
index 9d4bd6c67..000000000
--- a/programs/_confread/private.in
+++ /dev/null
@@ -1,6 +0,0 @@
-# This file defines the set of CIDRs (network/mask-length) to which
-# communication should always be private (i.e. encrypted).
-# See @FINALDOCDIR@/policygroups.html for details.
-#
-# $Id: private.in,v 1.1 2004/03/15 20:35:27 as Exp $
-#
diff --git a/programs/_confread/randomize b/programs/_confread/randomize
deleted file mode 100755
index 26d80a8f3..000000000
--- a/programs/_confread/randomize
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/sh
-# internal utility for putting random keys into sample configuration file
-# Copyright (C) 1998, 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: randomize,v 1.1 2004/03/15 20:35:27 as Exp $
-
-awk '/`[0-9]+`/ {
- match($0, /`[0-9]+`/)
- n = substr($0, RSTART+1, RLENGTH-2)
- cmd = "./ranbits --quick " n
- cmd | getline key
- cmd | getline eof
- close(cmd)
- sub(/`[0-9]+`/, key, $0)
- print
- next
-}
-{ print }' $*
diff --git a/programs/_copyright/.cvsignore b/programs/_copyright/.cvsignore
deleted file mode 100644
index 23ebcb381..000000000
--- a/programs/_copyright/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_copyright
diff --git a/programs/_copyright/Makefile b/programs/_copyright/Makefile
deleted file mode 100644
index 52c594b68..000000000
--- a/programs/_copyright/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_copyright
-PROGRAMDIR=${LIBDIR}
-LIBS=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:07 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_copyright/_copyright.8 b/programs/_copyright/_copyright.8
deleted file mode 100644
index 87e4adc98..000000000
--- a/programs/_copyright/_copyright.8
+++ /dev/null
@@ -1,32 +0,0 @@
-.TH _COPYRIGHT 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _copyright.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _copyright \- prints FreeSWAN copyright
-.SH DESCRIPTION
-.I _copyright
-outputs the FreeSWAN copyright, and version numbers for "ipsec --copyright"
-.SH "SEE ALSO"
-ipsec(8)
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Michael Richardson. Program written by Henry Spencer.
-.\"
-.\" $Log: _copyright.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_copyright/_copyright.c b/programs/_copyright/_copyright.c
deleted file mode 100644
index 0fb360f40..000000000
--- a/programs/_copyright/_copyright.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * copyright reporter
- * (just avoids having the info in more than one place in the source)
- * Copyright (C) 2001 Henry Spencer.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: _copyright.c,v 1.1 2004/03/15 20:35:27 as Exp $
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <freeswan.h>
-
-char usage[] = "Usage: ipsec _copyright";
-struct option opts[] = {
- {"help", 0, NULL, 'h',},
- {"version", 0, NULL, 'v',},
- {0, 0, NULL, 0, },
-};
-
-char me[] = "ipsec _copyright"; /* for messages */
-
-int
-main(int argc, char *argv[])
-{
- int opt;
- extern int optind;
- int errflg = 0;
- const char *version = ipsec_version_code();
- const char **notice = ipsec_copyright_notice();
- const char **co;
-
- while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
- switch (opt) {
- case 'h': /* help */
- printf("%s\n", usage);
- exit(0);
- break;
- case 'v': /* version */
- printf("%s %s\n", me, version);
- exit(0);
- break;
- case '?':
- default:
- errflg = 1;
- break;
- }
- if (errflg || optind != argc) {
- fprintf(stderr, "%s\n", usage);
- exit(2);
- }
-
- for (co = notice; *co != NULL; co++)
- printf("%s\n", *co);
- exit(0);
-}
diff --git a/programs/_include/.cvsignore b/programs/_include/.cvsignore
deleted file mode 100644
index ab6204115..000000000
--- a/programs/_include/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_include
diff --git a/programs/_include/Makefile b/programs/_include/Makefile
deleted file mode 100644
index 6b5f11682..000000000
--- a/programs/_include/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_include
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:11 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_include/_include.8 b/programs/_include/_include.8
deleted file mode 100644
index 56ffa0723..000000000
--- a/programs/_include/_include.8
+++ /dev/null
@@ -1,35 +0,0 @@
-.TH _INCLUDE 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _include.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _include \- internal script to process config files
-.SH DESCRIPTION
-.I _include
-is used by
-.I _confread
-to process
-.B include
-directives in /etc/ipsec.conf.
-.SH "SEE ALSO"
-ipsec(8), ipsec__confread(8)
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Program written by Henry Spencer.
-.\"
-.\" $Log: _include.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_include/_include.in b/programs/_include/_include.in
deleted file mode 100755
index 10a8a49e4..000000000
--- a/programs/_include/_include.in
+++ /dev/null
@@ -1,102 +0,0 @@
-#! /bin/sh
-# implements nested file inclusion for control files, including wildcarding
-# Copyright (C) 1998, 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _include.in,v 1.2 2004/03/15 21:03:06 as Exp $
-#
-# Output includes marker lines for file changes:
-# "#< filename lineno" signals entry into that file
-# "#> filename lineno" signals return to that file
-# The lineno is the line number of the *next* line.
-#
-# Errors are reported with a "#:message" line rather than on stderr.
-#
-# Lines which look like marker and report lines are never passed through.
-
-IPSEC_NAME="strongSwan"
-
-usage="Usage: $0 file ..."
-me="ipsec _include"
-
-for dummy
-do
- case "$1" in
- --inband) ;; # back compatibility
- --help) echo "$usage" ; exit 0 ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --) shift ; break ;;
- -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-case $# in
-0) echo "$usage" >&2 ; exit 2 ;;
-esac
-
-for f
-do
- if test ! -r "$f"
- then
- if test ! "$f" = "/etc/ipsec.conf"
- then
- echo "#:cannot open configuration file \'$f\'"
- if test "$f" = "/etc/ipsec.secrets"
- then
- echo "#:Your secrets file will be created when you start $IPSEC_NAME for the first time."
- fi
- exit 1
- else
- exit 1
- fi
- fi
-done
-
-awk 'BEGIN {
- wasfile = ""
-}
-FNR == 1 {
- print ""
- print "#<", FILENAME, 1
- lineno = 0
- wasfile = FILENAME
-}
-{
- lineno++
- # lineno is now the number of this line
-}
-/^#[<>:]/ {
- next
-}
-/^include[ \t]+/ {
- orig = $0
- sub(/[ \t]+#.*$/, "")
- if (NF != 2) {
- msg = "(" FILENAME ", line " lineno ")"
- msg = msg " include syntax error in \"" orig "\""
- print "#:" msg
- exit 1
- }
- newfile = $2
- if (newfile !~ /^\// && FILENAME ~ /\//) {
- prefix = FILENAME
- sub("[^/]+$", "", prefix)
- newfile = prefix newfile
- }
- system("ipsec _include " newfile)
- print ""
- print "#>", FILENAME, lineno + 1
- next
-}
-{ print }' $*
diff --git a/programs/_keycensor/.cvsignore b/programs/_keycensor/.cvsignore
deleted file mode 100644
index 97d0bb2bf..000000000
--- a/programs/_keycensor/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_keycensor
diff --git a/programs/_keycensor/Makefile b/programs/_keycensor/Makefile
deleted file mode 100644
index bc495328f..000000000
--- a/programs/_keycensor/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_keycensor
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:15 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_keycensor/_keycensor.8 b/programs/_keycensor/_keycensor.8
deleted file mode 100644
index 89a97a9f9..000000000
--- a/programs/_keycensor/_keycensor.8
+++ /dev/null
@@ -1,33 +0,0 @@
-.TH _KEYCENSOR 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _keycensor.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _keycensor \- internal routine to remove sensitive information
-.SH DESCRIPTION
-.I _keycensor
-is used by
-.B ipsec barf
-to process the /etc/ipsec.secrets file, removing private key info.
-.SH "SEE ALSO"
-ipsec(8), ipsec_barf(8)
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program by Henry Spencer.
-.\"
-.\" $Log: _keycensor.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_keycensor/_keycensor.in b/programs/_keycensor/_keycensor.in
deleted file mode 100755
index 7d6f257e5..000000000
--- a/programs/_keycensor/_keycensor.in
+++ /dev/null
@@ -1,52 +0,0 @@
-#! /bin/sh
-# implements key censoring for barf
-# Copyright (C) 1999, 2002 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _keycensor.in,v 1.1 2004/03/15 20:35:27 as Exp $
-
-usage="Usage: $0 [file ...]"
-me="ipsec _keycensor"
-
-for dummy
-do
- case "$1" in
- --help) echo "$usage" ; exit 0 ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --) shift ; break ;;
- -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-awk ' /(sig|enc|auth)key[ \t]*=[ \t]*[^%]/ {
- i = match($0, /key[ \t]*=[ \t]*/)
- i += RLENGTH
- cold = substr($0, 1, i-1)
- hot = substr($0, i)
- sub(/[ \t]+(#.*)?$/, "", hot)
- q = "'"'"'" # single quote
- if (hot ~ q)
- cooled = "[cannot be condensed]"
- else if (hot ~ /^0s/)
- cooled = "[keyid " substr(hot, 3, 9) "]"
- else {
- run = "echo " q hot q " | md5sum"
- run | getline
- close(run)
- cooled = "[sums to " substr($1, 1, 4) "...]"
- }
- print cold cooled
- next
- }
- { print }' $*
diff --git a/programs/_plutoload/.cvsignore b/programs/_plutoload/.cvsignore
deleted file mode 100644
index cbcf7e699..000000000
--- a/programs/_plutoload/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_plutoload
diff --git a/programs/_plutoload/Makefile b/programs/_plutoload/Makefile
deleted file mode 100644
index af9ffee18..000000000
--- a/programs/_plutoload/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_plutoload
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:19 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_plutoload/_plutoload.8 b/programs/_plutoload/_plutoload.8
deleted file mode 100644
index ba421b6c3..000000000
--- a/programs/_plutoload/_plutoload.8
+++ /dev/null
@@ -1,33 +0,0 @@
-.TH _PLUTOLOAD 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _plutoload.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _plutoload \- internal script to start pluto
-.SH DESCRIPTION
-.I _plutoload
-is called by
-.B _plutorun
-to actually start the pluto executable.
-.SH "SEE ALSO"
-ipsec(8), ipsec_setup(8), ipsec__realsetup(8), ipsec__plutorun(8)
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program by Henry Spencer.
-.\"
-.\" $Log: _plutoload.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_plutoload/_plutoload.in b/programs/_plutoload/_plutoload.in
deleted file mode 100755
index 73841197d..000000000
--- a/programs/_plutoload/_plutoload.in
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/bin/sh
-# Pluto database-loading script
-# Copyright (C) 1998, 1999, 2001 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _plutoload.in,v 1.2 2004/03/31 16:15:10 as Exp $
-#
-# exit status is 13 for protocol violation, that of Pluto otherwise
-
-me='ipsec _plutoload' # for messages
-
-for dummy
-do
- case "$1" in
- --load) plutoload="$2" ; shift ;;
- --start) plutostart="$2" ; shift ;;
- --wait) plutowait="$2" ; shift ;;
- --post) postpluto="$2" ; shift ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-# load ca information
-eval `ipsec _confread --varprefix PLUTO --type ca --search auto add start`
-if test " $PLUTO_confreadstatus" != " "
-then
- echo "auto=add/start search: $PLUTO_confreadstatus"
- echo "unable to determine what ca information to add -- adding none"
- caload=
-else
- caload="$PLUTO_confreadnames"
-fi
-
-# searches, if needed
-# the way the searches were done ensures plutoload >= plutoroute >= plutostart
-
-# search for things to "ipsec auto --add": auto in "add" "route" "start"
-eval `ipsec _confread --varprefix PLUTO --search auto add route start`
-if test " $PLUTO_confreadstatus" != " "
-then
- echo "auto=add/route/start search: $PLUTO_confreadstatus"
- echo "unable to determine what conns to add -- adding none"
- plutoload=
-else
- plutoload="$PLUTO_confreadnames"
-fi
-
-# search for things to "ipsec auto --route": auto in "route" "start"
-eval `ipsec _confread --varprefix PLUTO --search auto route start`
-if test " $PLUTO_confreadstatus" != " "
-then
- echo "auto=route/start search: $PLUTO_confreadstatus"
- echo "unable to determine what conns to route -- routing none"
- plutoroute=
-else
- plutoroute="$PLUTO_confreadnames"
-fi
-
-# search for things to "ipsec auto --up": auto in "start"
-eval `ipsec _confread --varprefix PLUTO --search auto start`
-if test " $PLUTO_confreadstatus" != " "
-then
- echo "auto=start search: $PLUTO_confreadstatus"
- echo "unable to determine what conns to start -- starting none"
- plutostart=
-else
- plutostart="$PLUTO_confreadnames"
-fi
-
-# await Pluto's readiness (not likely to be an issue, but...)
-eofed=y
-while read saying
-do
- case "$saying" in
- 'Pluto initialized') eofed= ; break ;; # NOTE BREAK OUT
- *) echo "pluto unexpectedly said \`$saying'" ;;
- esac
-done
-if test "$eofed"
-then
- echo "pluto died unexpectedly!?!"
- exit 13
-fi
-
-# ca database load
-for tu in $caload
-do
- ipsec auto --type ca --add $tu ||
- echo "...could not add ca \"$tu\""
-done
-
-# conn database load
-for tu in $plutoload
-do
- ipsec auto --add $tu ||
- echo "...could not add conn \"$tu\""
-done
-
-# enable listening
-ipsec auto --ready
-
-# execute any post-startup cleanup
-if test " $postpluto" != " "
-then
- $postpluto
- st=$?
- if test " $st" -ne 0
- then
- echo "...postpluto command exited with status $st"
- fi
-fi
-
-# quickly establish routing
-for tu in $plutoroute
-do
- ipsec auto --route $tu ||
- echo "...could not route conn \"$tu\""
-done
-
-# tunnel initiation, which may take a while
-async=
-if test " $plutowait" = " no"
-then
- async="--asynchronous"
-fi
-for tu in $plutostart
-do
- ipsec auto --up $async $tu ||
- echo "...could not start conn \"$tu\""
-done
-
-# report any further utterances, and watch for exit status
-eofed=y
-while read saying
-do
- case "$saying" in
- exit) eofed= ; break ;; # NOTE BREAK OUT
- *) echo "pluto unexpectedly says \`$saying'" ;;
- esac
-done
-if test "$eofed"
-then
- echo "pluto died without exit status!?!"
- exit 13
-fi
-if read status
-then
- exit $status
-else
- echo "pluto yielded no exit status!?!"
- exit 13
-fi
diff --git a/programs/_plutorun/.cvsignore b/programs/_plutorun/.cvsignore
deleted file mode 100644
index 13e0ae1a1..000000000
--- a/programs/_plutorun/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_plutorun
diff --git a/programs/_plutorun/Makefile b/programs/_plutorun/Makefile
deleted file mode 100644
index b0928797c..000000000
--- a/programs/_plutorun/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_plutorun
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:26 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_plutorun/_plutorun.8 b/programs/_plutorun/_plutorun.8
deleted file mode 100644
index 9de6927dc..000000000
--- a/programs/_plutorun/_plutorun.8
+++ /dev/null
@@ -1,37 +0,0 @@
-.TH _PLUTORUN 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _plutorun.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _plutorun \- internal script to start pluto
-.SH DESCRIPTION
-.I _plutorun
-is called by
-.B _realsetup
-to configure and bring up
-.B ipsec_pluto(8).
-It calls
-.B _plutoload
-to invoke pluto, and watches to makes sure that pluto is restarted if it fails.
-.SH "SEE ALSO"
-ipsec(8), ipsec_setup(8), ipsec__realsetup(8), ipsec__plutoload(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program written by Henry Spencer.
-.\"
-.\" $Log: _plutorun.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_plutorun/_plutorun.in b/programs/_plutorun/_plutorun.in
deleted file mode 100755
index b02afeefb..000000000
--- a/programs/_plutorun/_plutorun.in
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/bin/sh
-# Pluto control daemon
-# Copyright (C) 1998, 1999, 2001 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _plutorun.in,v 1.9 2005/10/16 13:28:15 as Exp $
-
-me='ipsec _plutorun' # for messages
-
-info=/var/run/ipsec.info
-
-popts=
-stderrlog=
-plutorestartoncrash=true
-
-wherelog=daemon.error
-pidfile=/var/run/pluto.pid
-verb="Starting"
-for dummy
-do
- case "$1" in
- --re) verb="Restarting" ;;
- --plutorestartoncrash) plutorestartoncrash="$2"; shift ;;
- --debug) plutodebug="$2" ; shift ;;
- --uniqueids) uniqueids="$2" ; shift ;;
- --nat_traversal) nat_traversal="$2" ; shift ;;
- --keep_alive) keep_alive="$2" ; shift ;;
- --force_keepalive) force_keepalive="$2" ; shift ;;
- --disable_port_floating) disable_port_floating="$2" ; shift ;;
- --virtual_private) virtual_private="$2" ; shift ;;
- --nocrsend) nocrsend="$2" ; shift ;;
- --strictcrlpolicy) strictcrlpolicy="$2" ; shift ;;
- --crlcheckinterval) crlcheckinterval="$2"; shift ;;
- --cachecrls) cachecrls="$2" ; shift ;;
- --pkcs11module) pkcs11module="$2"; shift ;;
- --pkcs11keepstate) pkcs11keepstate="$2"; shift ;;
- --pkcs11proxy) pkcs11proxy="$2"; shift ;;
- --dump) dumpdir="$2" ; shift ;;
- --opts) popts="$2" ; shift ;;
- --stderrlog) stderrlog="$2" ; shift ;;
- --wait) plutowait="$2" ; shift ;;
- --pre) prepluto="$2" ; shift ;;
- --post) postpluto="$2" ; shift ;;
- --log) wherelog="$2" ; shift ;;
- --pid) pidfile="$2" ; shift ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-# initially we are in the foreground, with parent looking after logging
-
-# precautions
-if test -f $pidfile
-then
- echo "pluto appears to be running already (\`$pidfile' exists), will not start another"
- exit 1
-fi
-if test ! -e /dev/urandom
-then
- echo "cannot start Pluto, system lacks \`/dev/urandom'!?!"
- exit 1
-fi
-
-# sort out options
-for d in $plutodebug
-do
- popts="$popts --debug-$d"
-done
-case "$uniqueids" in
-yes) popts="$popts --uniqueids" ;;
-no|'') ;;
-*) echo "unknown uniqueids value (not yes/no) \`$IPSECuniqueids'" ;;
-esac
-case "$nocrsend" in
-yes) popts="$popts --nocrsend" ;;
-no|'') ;;
-*) echo "unknown nocrsend value (not yes/no) \`$IPSECnocrsend'" ;;
-esac
-case "$strictcrlpolicy" in
-yes) popts="$popts --strictcrlpolicy" ;;
-no|'') ;;
-*) echo "unknown strictcrlpolicy value (not yes/no) \`$IPSECstrictcrlpolicy'" ;;
-esac
-case "$cachecrls" in
-yes) popts="$popts --cachecrls" ;;
-no|'') ;;
-*) echo "unknown cachecrls value (not yes/no) \`$IPSECcachecrls'" ;;
-esac
-case "$nat_traversal" in
-yes) popts="$popts --nat_traversal" ;;
-no|'') ;;
-*) echo "unknown nat_traversal value (not yes/no) \`$IPSECnat_traversal'" ;;
-esac
-[ -n "$keep_alive" ] && popts="$popts --keep_alive $keep_alive"
-case "$force_keepalive" in
-yes) popts="$popts --force_keepalive" ;;
-no|'') ;;
-*) echo "unknown force_keepalive value (not yes/no) \`$IPSECforce_keepalive'" ;;
-esac
-case "$disable_port_floating" in
-yes) popts="$popts --disable_port_floating" ;;
-no|'') ;;
-*) echo "unknown disable_port_floating (not yes/no) \`$disable_port_floating'" ;;
-esac
-case "$pkcs11keepstate" in
-yes) popts="$popts --pkcs11keepstate" ;;
-no|'') ;;
-*) echo "unknown pkcs11keepstate value (not yes/no) \`$IPSECpkcs11keepstate'" ;;
-esac
-case "$pkcs11proxy" in
-yes) popts="$popts --pkcs11proxy" ;;
-no|'') ;;
-*) echo "unknown pkcs11proxy value (not yes/no) \`$IPSECpkcs11proxy'" ;;
-esac
-
-[ -n "$virtual_private" ] && popts="$popts --virtual_private $virtual_private"
-
-# add crl check interval
-if test ${crlcheckinterval:-0} -gt 0
-then
- popts="$popts --crlcheckinterval $crlcheckinterval"
-fi
-
-if test -n "$pkcs11module"
-then
- popts="$popts --pkcs11module $pkcs11module"
-fi
-
-if test -n "$stderrlog"
-then
- popts="$popts --stderrlog 2>>$stderrlog"
-
- if test -f $stderrlog
- then
- if test ! -w $stderrlog
- then
- echo Cannot write to \"$stderrlog\".
- exit 1
- fi
- else
- if test ! -w "`dirname $stderrlog`"
- then
- echo Cannot write to directory to create \"$stderrlog\".
- exit 1
- fi
- fi
-
- echo "Plutorun started on "`date` >$stderrlog
-fi
-
-# set up dump directory
-if test " $dumpdir" = " "
-then
- ulimit -c 0 # preclude core dumps
-elif test ! -d "$dumpdir"
-then
- echo "dumpdir \`$dumpdir' does not exist, ignored"
- ulimit -c 0 # preclude core dumps
-elif cd $dumpdir # put them where desired
-then
- ulimit -c unlimited # permit them
-else
- echo "cannot cd to dumpdir \`$dumpdir', ignored"
- ulimit -c 0 # preclude them
-fi
-
-# execute any preliminaries
-if test " $prepluto" != " "
-then
- $prepluto
- st=$?
- if test " $st" -ne 0
- then
- echo "...prepluto command exited with status $st"
- fi
-fi
-
-IPSEC_SECRETS=${IPSEC_CONFS}/ipsec.secrets
-if test ! -f "${IPSEC_SECRETS}"
-then
- ( logger -p authpriv.info -t ipsec__plutorun No file ${IPSEC_SECRETS}, generating key.
- ipsec scepclient --out pkcs1 --out cert-self --quiet
- echo -e "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n" > ${IPSEC_SECRETS}
- chmod 600 ${IPSEC_SECRETS}
- echo ": RSA myKey.der" >> ${IPSEC_SECRETS}
-
- # tell pluto to go re-read the file
- ipsec auto --rereadsecrets
- ) &
-fi
-
-#
-# make sure that the isakmp port is open!
-#
-if test -f /etc/sysconfig/ipchains
-then
- if egrep -q 500:500 /etc/sysconfig/ipchains
- then
- :
- else
- ipchains -I input 1 -p udp -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 500:500 -j ACCEPT
- # if it redhat, then save the rules again.
- if [ -f /etc/redhat-release ]
- then
- sh /etc/rc.d/init.d/ipchains save
- fi
- fi
-fi
-
-# spin off into the background, with our own logging
-echo "$verb Pluto subsystem..." | logger -p authpriv.error -t ipsec__plutorun
-execdir=${IPSEC_EXECDIR-@IPSEC_EXECDIR@}
-libdir=${IPSEC_LIBDIR-@IPSEC_LIBDIR@}
-until (
- if test -s $info
- then
- . $info
- export defaultroutephys defaultroutevirt defaultrouteaddr defaultroutenexthop
- fi
- # eval allows $popts to contain redirection and other magic
- eval $execdir/pluto --nofork --secretsfile "$IPSEC_SECRETS" --policygroupsdir "${IPSEC_CONFS}/ipsec.d/policies" $popts
- status=$?
- echo "exit"
- echo $status
- ) | $libdir/_plutoload --wait "$plutowait" --post "$postpluto"
-do
- status=$?
- case "$status" in
- 13) echo "internal failure in pluto scripts, impossible to carry on"
- exit 1
- ;;
- 10) echo "pluto apparently already running (?!?), giving up"
- exit 1
- ;;
- 137) echo "pluto killed by SIGKILL, terminating without restart or unlock"
- exit 0
- ;;
- 143) echo "pluto killed by SIGTERM, terminating without restart"
- # pluto now does its own unlock for this
- exit 0
- ;;
- *) st=$status
- if $plutorestartoncrash
- then
- :
- else
- exit 0
- fi
-
- if test $st -gt 128
- then
- st="$st (signal `expr $st - 128`)"
- fi
- echo "!pluto failure!: exited with error status $st"
- echo "restarting IPsec after pause..."
- (
- sleep 10
- ipsec setup _autorestart
- ) </dev/null >/dev/null 2>&1 &
- exit 1
- ###sleep 10
- ###rm -rf $pidfile
- #### and go around the loop again
- ;;
- esac
-done </dev/null 2>&1 |
- logger -s -p $wherelog -t ipsec__plutorun >/dev/null 2>/dev/null &
-
-exit 0
diff --git a/programs/_realsetup/.cvsignore b/programs/_realsetup/.cvsignore
deleted file mode 100644
index 54941b8a3..000000000
--- a/programs/_realsetup/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_realsetup
diff --git a/programs/_realsetup/Makefile b/programs/_realsetup/Makefile
deleted file mode 100644
index c339007e0..000000000
--- a/programs/_realsetup/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_realsetup
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:34 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_realsetup/_realsetup.8 b/programs/_realsetup/_realsetup.8
deleted file mode 100644
index 51b647115..000000000
--- a/programs/_realsetup/_realsetup.8
+++ /dev/null
@@ -1,36 +0,0 @@
-.TH _REALSETUP 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _realsetup.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _realsetup \- internal routine to start FreeS/WAN.
-.SH DESCRIPTION
-.I _realsetup
-is called by the system init scripts to start the FreeS/WAN
-system. It starts
-.B KLIPS
-(the kernel component) and
-.B pluto
-(the userspace keying component).
-.SH "SEE ALSO"
-ipsec(8), ipsec__klipsstart(8), ipsec__plutorun(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program by Henry Spencer.
-.\"
-.\" $Log: _realsetup.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_realsetup/_realsetup.in b/programs/_realsetup/_realsetup.in
deleted file mode 100755
index 91b6e98d3..000000000
--- a/programs/_realsetup/_realsetup.in
+++ /dev/null
@@ -1,456 +0,0 @@
-#!/bin/sh
-# IPsec startup and shutdown command
-# Copyright (C) 1998, 1999, 2001 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _realsetup.in,v 1.10 2005/09/25 21:30:52 as Exp $
-
-IPSEC_NAME=strongSwan
-
-me='ipsec setup' # for messages
-
-# Misc. paths (some of this should perhaps be overrideable from ipsec.conf).
-plutopid=/var/run/pluto.pid
-subsyslock=/var/lock/subsys/ipsec
-lock=/var/run/ipsec_setup.pid
-info=/var/run/ipsec.info
-sysflags=/proc/sys/net/ipsec
-modules=/proc/modules
-ipforward=/proc/sys/net/ipv4/ip_forward
-ipsecversion=/proc/net/ipsec_version
-kamepfkey=/proc/net/pfkey
-
-# make sure output of (e.g.) ifconfig is in English
-unset LANG LANGUAGE LC_ALL LC_MESSAGES
-
-# check we were called properly
-if test " $IPSEC_confreadsection" != " setup"
-then
- echo "$me: $0 must be called by ipsec_setup" >&2
- exit 1
-fi
-# defaults for "config setup" items
-
-IPSECinterfaces=${IPSECinterfaces:-%defaultroute}
- if test " $IPSECinterfaces" = " %none" ; then IPSECinterfaces= ; fi
-# IPSECforwardcontrol "no"
-# IPSECsyslog "daemon.error"
-# IPSECklipsdebug "none"
-# IPSECplutodebug "none"
-# IPSECdumpdir "" (no dump)
-# IPSECmanualstart ""
-# IPSECpluto "yes"
-IPSECplutowait=${IPSECplutowait:-no}
-# IPSECprepluto ""
-# IPSECpostpluto ""
-# IPSECfragicmp "yes"
-# IPSEChidetos "yes"
-IPSECrp_filter=${IPSECrp_filter:-0}
-IPSECuniqueids=${IPSECuniqueids:-yes}
-IPSECcrlcheckinterval=${IPSECcrlcheckinterval:-0}
-# IPSECpkcs11module ""
-# IPSECoverridemtu ""
-
-# Shall we trace?
-execute="true"
-display="false"
-for i in $IPSEC_setupflags
-do
- case "$i" in
- "--showonly") execute="false" ; display=true ;;
- "--show") display=true ;;
- esac
-done
-
-if $display
-then
- echo " " PATH="$PATH"
-fi
-
-perform() {
- if $display
- then
- echo " " "$*"
- fi
-
- if $execute
- then
- eval "$*"
- fi
-}
-
-# function to set up manually-keyed connections
-manualconns() {
- if test " $IPSECmanualstart" != " "
- then
- for tu in $IPSECmanualstart
- do
- perform ipsec manual --up $tu
- done
- fi
-
- # search for things to "ipsec manual --up": auto == "manual"
- eval `ipsec _confread --varprefix MANUALSTART --search auto manual`
- if test " $MANUALSTART_confreadstatus" != " "
- then
- echo "auto=manual search: $MANUALSTART_confreadstatus"
- echo "unable to determine what conns to manual --up; none done"
- elif test " $MANUALSTART_confreadnames" != " "
- then
- for tu in $MANUALSTART_confreadnames
- do
- perform ipsec manual --up $tu
- done
- fi
-}
-
-# for no-stdout logging:
-LOGONLY="logger -p $IPSECsyslog -t ipsec_setup"
-
-# What an ugly string.
-# Must be a string, not a function, because it is nested
-# within another sequence (for plutorun).
-# Luckily there are NO substitutions in it.
-KILLKLIPS='ifl=` ifconfig | sed -n -e "/^ipsec/s/ .*//p" ` ;
- test "X$ifl" != "X" &&
- for i in $ifl ;
- do
- ifconfig $i down ;
- ipsec tncfg --detach --virtual $i ;
- done ;
- test -r /proc/net/ipsec_klipsdebug && ipsec klipsdebug --none ;
- ipsec eroute --clear ;
- ipsec spi --clear ;
- for alg in aes serpent twofish blowfish sha2 ;
- do
- lsmod 2>&1 | grep "^ipsec_$alg" > /dev/null && rmmod ipsec_$alg ;
- done ;
- lsmod 2>&1 | grep "^ipsec" > /dev/null && rmmod ipsec'
-
-if test -f $kamepfkey
-then
- KILLKLIPS='
- if ip xfrm state > /dev/null 2>&1 ;
- then
- ip xfrm state flush ;
- ip xfrm policy flush ;
- elif type setkey > /dev/null 2>&1 ;
- then
- setkey -F ;
- setkey -FP ;
- fi'
-fi
-
-
-
-# do it
-case "$1" in
- start|--start|_autostart)
- # First, does it seem to be going already?
- perform test ! -f $lock "||" "{" \
- echo "\"$IPSEC_NAME IPsec apparently already running, start aborted\"" ";" \
- exit 1 ";" \
- "}"
-
- # announcement
- # (Warning, changes to this log message may affect barf.)
- version="`ipsec --version | awk 'NR == 1 { print $(3) }' | sed -e 's/^U\(.*\)\/K(.*/\1/'`"
- case "$1" in
- start|--start) perform echo "\"Starting $IPSEC_NAME IPsec $version...\"" ;;
- _autostart) perform echo "\"Restarting $IPSEC_NAME IPsec $version...\"" ;;
- esac
-
- # preliminaries
- perform rm -f $lock
-
- for f in /dev/random /dev/urandom
- do
- perform test -r $f "||" "{" \
- echo "\"...unable to start $IPSEC_NAME IPsec, no $f!\"" ";" \
- exit 1 ";" \
- "}"
- done
-
- # the meaning of $$ at a different runtime is questionable!
- perform echo '$$' ">" $lock
- perform test -s $lock "||" "{" \
- echo "\"...unable to create $lock, aborting start!\"" ";" \
- rm -f $lock ";" \
- exit 1 ";" \
- "}"
-
- perform ">" $info
-
- # here we go
- perform ipsec _startklips \
- --info $info \
- --debug "\"$IPSECklipsdebug\"" \
- --omtu "\"$IPSECoverridemtu\"" \
- --fragicmp "\"$IPSECfragicmp\"" \
- --hidetos "\"$IPSEChidetos\"" \
- --rpfilter "\"$IPSECrp_filter\"" \
- --log "\"$IPSECsyslog\"" \
- $IPSECinterfaces "||" \
- "{" rm -f $lock ";" exit 1 ";" "}"
-
- perform test -f $ipsecversion "||" \
- test -f $kamepfkey "||" "{" \
- echo "\"OOPS, should have aborted! Broken shell!\"" ";" \
- exit 1 ";" \
- "}"
-
- # misc pre-Pluto setup
-
- perform test -d `dirname $subsyslock` "&&" touch $subsyslock
-
- if test " $IPSECforwardcontrol" = " yes"
- then
- perform grep '"^0"' $ipforward ">" /dev/null "&&" "{" \
- echo "\"enabling IP forwarding:\"" "|" $LOGONLY ";" \
- echo "\"ipforwardingwas=$fw\"" ">>" $info ";" \
- echo 1 ">" $ipforward ";" \
- "}"
- fi
- manualconns
-
- plutorestartoncrash=""
- case "$IPSECplutorestartoncrash" in
- true|[yY]|yes|restart) plutorestartoncrash="--plutorestartoncrash true";;
- false|[nN]|no|die) plutorestartoncrash="--plutorestartoncrash false" ;;
- esac
-
- # Pluto
- case "$1" in
- start|--start) re= ;;
- _autostart) re=--re ;;
- esac
- if test " $IPSECpluto" != " no"
- then
- perform ipsec _plutorun $re \
- --debug "\"$IPSECplutodebug\"" \
- --uniqueids "\"$IPSECuniqueids\"" \
- --nocrsend "\"$IPSECnocrsend\"" \
- --strictcrlpolicy "\"$IPSECstrictcrlpolicy\"" \
- --cachecrls "\"$IPSECcachecrls\"" \
- --nat_traversal "\"$IPSECnat_traversal\"" \
- --keep_alive "\"$IPSECkeep_alive\"" \
- --force_keepalive "\"$IPSECforce_keepalive\"" \
- --disable_port_floating "\"$IPSECdisable_port_floating\"" \
- --virtual_private "\"$IPSECvirtual_private\"" \
- --crlcheckinterval "\"$IPSECcrlcheckinterval\"" \
- --pkcs11module "\"$IPSECpkcs11module\"" \
- --pkcs11keepstate "\"$IPSECpkcs11keepstate\"" \
- --pkcs11proxy "\"$IPSECpkcs11proxy\"" \
- --dump "\"$IPSECdumpdir\"" \
- --opts "\"$IPSECplutoopts\"" \
- --stderrlog "\"$IPSECplutostderrlog\"" \
- --wait "\"$IPSECplutowait\"" \
- --pre "\"$IPSECprepluto\"" \
- --post "\"$IPSECpostpluto\"" \
- --log "\"$IPSECsyslog\"" $plutorestartoncrash \
- --pid "\"$plutopid\"" "||" "{" \
- $KILLKLIPS ";" \
- rm -f $lock ";" \
- exit 1 ";" \
- "}"
- fi
-
- # done!
- perform echo "\"...$IPSEC_NAME IPsec started\"" "|" $LOGONLY
- ;;
-
- stop|--stop|_autostop) # _autostop is same as stop
- # Shut things down.
- perform echo "\"Stopping $IPSEC_NAME IPsec...\""
- perform \
- if test -r $lock ";" \
- then \
- status=0 ";" \
- . $info ";" \
- else \
- echo "\"stop ordered, but IPsec does not appear to be running!\"" ";" \
- echo "\"doing cleanup anyway...\"" ";" \
- status=1 ";" \
- fi
- if test " $IPSECforwardcontrol" = " yes"
- then
- perform test "\"X\$ipforwardingwas\"" = "\"X0\"" "&&" "{" \
- echo "\"disabling IP forwarding:\"" "|" $LOGONLY ";" \
- echo 0 ">" $ipforward ";" \
- "}"
- fi
-
- perform test -f $plutopid "&&" "{" \
- if ps -p '`' cat $plutopid '`' ">" /dev/null ";" \
- then \
- ipsec whack --shutdown "|" grep -v "^002" ";" \
- sleep 1 ";" \
- if test -s $plutopid ";" \
- then \
- echo "\"Attempt to shut Pluto down failed! Trying kill:\"" ";" \
- kill '`' cat $plutopid '`' ";" \
- sleep 5 ";" \
- fi ";" \
- else \
- echo "\"Removing orphaned $plutopid:\"" ";" \
- fi ";" \
- rm -f $plutopid ";" \
- "}"
-
- perform $KILLKLIPS
-
- perform test -d `dirname $subsyslock` "&&" rm -f $subsyslock
-
- perform rm -f $info $lock
- perform echo "...$IPSEC_NAME IPsec stopped" "|" $LOGONLY
- perform exit \$status
- ;;
-
- status|--status)
- if test " $IPSEC_setupflags" != " "
- then
- echo "$me $1 does not support $IPSEC_setupflags"
- exit 1
- fi
-
- if test -f $info
- then
- hasinfo=yes
- fi
-
- if test -f $lock
- then
- haslock=yes
- fi
-
- if test -f $subsyslock
- then
- hassublock=yes
- fi
-
- if test -s $plutopid
- then
- if ps -p `cat $plutopid` >/dev/null
- then
- plutokind=normal
- elif ps -C pluto >/dev/null
- then
- plutokind=illicit
- fi
- elif ps -C pluto >/dev/null
- then
- plutokind=orphaned
- else
- plutokind=no
- fi
-
- if test -r /proc/net/ipsec_eroute
- then
- if test " `wc -l </proc/net/ipsec_eroute`" -gt 0
- then
- eroutes=yes
- fi
- fi
-
- if test -r $ipsecversion
- then
- klips=yes
- elif test -r $modules
- then
- klips=maybe
- else
- klips=none
- fi
-
- if test "$haslock"
- then
- echo "IPsec running"
- # might not be a subsystem lock dir, ignore that issue
- if test "$plutokind" = "normal" -a "$klips" = "yes" -a "$hasinfo"
- then
- echo "pluto pid `cat $plutopid`"
- exit 0
- fi
- echo "but..."
- if test "$plutokind" != "normal"
- then
- echo "$plutokind Pluto running!"
- fi
- if test ! "$hasinfo"
- then
- echo "$info file missing!"
- fi
- case $klips in
- maybe) echo "KLIPS module is not loaded!" ;;
- none) echo "no KLIPS in kernel!" ;;
- esac
- if test "$eroutes"
- then
- echo "some eroutes exist"
- fi
- exit 1
- else
- echo "IPsec stopped"
- if test ! "$hassublock" -a ! "$hasinfo" -a "$plutokind" = "no" \
- -a ! "$eroutes"
- then
- exit 0
- fi
- echo "but..."
- if test "$hassublock"
- then
- echo "has subsystem lock ($subsyslock)!"
- fi
- if test "$hasinfo"
- then
- echo "has $info file!"
- fi
- if test "$plutokind" != "normal"
- then
- echo "$plutokind Pluto is running!"
- fi
- if test "$eroutes"
- then
- echo "some eroutes exist!"
- fi
- exit 1
- fi
- ;;
-
- --version)
- if test " $IPSEC_setupflags" != " "
- then
- echo "$me $1 does not support $IPSEC_setupflags"
- exit 1
- fi
-
- echo "$me $IPSEC_VERSION"
- exit 0
- ;;
-
- --help)
- if test " $IPSEC_setupflags" != " "
- then
- echo "$me $1 does not support $IPSEC_setupflags"
- exit 1
- fi
-
- echo "Usage: $me {--start|--stop|--restart|--status}"
- exit 0
- ;;
-
- *)
- echo "Usage: $me {--start|--stop|--restart|--status}" >&2
- exit 2
-esac
-
-exit 0
diff --git a/programs/_secretcensor/.cvsignore b/programs/_secretcensor/.cvsignore
deleted file mode 100644
index 202d856fe..000000000
--- a/programs/_secretcensor/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_secretcensor
diff --git a/programs/_secretcensor/Makefile b/programs/_secretcensor/Makefile
deleted file mode 100644
index 3df15286e..000000000
--- a/programs/_secretcensor/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_secretcensor
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:38 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_secretcensor/_secretcensor.8 b/programs/_secretcensor/_secretcensor.8
deleted file mode 100644
index d502bbd37..000000000
--- a/programs/_secretcensor/_secretcensor.8
+++ /dev/null
@@ -1,34 +0,0 @@
-.TH _SECRETCENSOR 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _secretcensor.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _secretcensor \- internal routing to sanitize files
-.SH DESCRIPTION
-.I _secretcensor
-is called by
-.B ipsec barf
-to process the /etc/ipsec.secrets file to remove the private key components
-from the file prior to revealing the contents.
-.SH "SEE ALSO"
-ipsec(8), ipsec_barf(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program by Henry Spencer.
-.\"
-.\" $Log: _secretcensor.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_secretcensor/_secretcensor.in b/programs/_secretcensor/_secretcensor.in
deleted file mode 100755
index 150c13cbc..000000000
--- a/programs/_secretcensor/_secretcensor.in
+++ /dev/null
@@ -1,75 +0,0 @@
-#! /bin/sh
-# implements secret censoring for barf
-# Copyright (C) 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _secretcensor.in,v 1.1 2004/03/15 20:35:27 as Exp $
-
-usage="Usage: $0 [file ...]"
-me="ipsec _secretcensor"
-
-for dummy
-do
- case "$1" in
- --help) echo "$usage" ; exit 0 ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --) shift ; break ;;
- -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-awk ' function cool(hot, q, cooled, run) {
- # warning: may destroy input line!
- q = "'"'"'" # single quote
- if (hot ~ q)
- return "[cannot be summed]"
- if (hot ~ /^0s/)
- return "[keyid " substr(hot, 3, 9) "]"
- run = "echo " q hot q " | md5sum"
- run | getline
- close(run)
- return "[sums to " substr($1, 1, 4) "...]"
- }
- /"/ {
- i = match($0, /"[^"]+"/)
- cold1 = substr($0, 1, i)
- cold2 = substr($0, i+RLENGTH-1)
- hot = substr($0, i+1, RLENGTH-2)
- print cold1 cool(hot) cold2
- next
- }
- /#pubkey=/ {
- i = match($0, /^.*#pubkey=/)
- i += RLENGTH-1
- cold = substr($0, 1, i)
- hot = substr($0, i+1)
- print cold cool(hot)
- next
- }
- /#IN KEY / {
- i = match($0, /^.*[ \t][^ \t]/)
- i += RLENGTH-2
- cold = substr($0, 1, i)
- hot = substr($0, i+1)
- print cold cool("0s" hot)
- next
- }
- /^[ \t]+(Modulus|P[a-z]+Exponent|Prime[12]|Exponent[12]|Coefficient):/ {
- i = match($0, /^[^:]*:[ \t]*/)
- i += RLENGTH-1
- cold = substr($0, 1, i)
- print cold "[...]"
- next
- }
- { print }' $*
diff --git a/programs/_startklips/.cvsignore b/programs/_startklips/.cvsignore
deleted file mode 100644
index a206fe65f..000000000
--- a/programs/_startklips/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-_startklips
diff --git a/programs/_startklips/Makefile b/programs/_startklips/Makefile
deleted file mode 100644
index 9df701b0e..000000000
--- a/programs/_startklips/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_startklips
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/08/02 16:01:42 mcr
-# moved user visible programs to $PREFIX/libexec, while moving
-# private files to $PREFIX/lib.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/_startklips/_startklips.8 b/programs/_startklips/_startklips.8
deleted file mode 100644
index 066699085..000000000
--- a/programs/_startklips/_startklips.8
+++ /dev/null
@@ -1,33 +0,0 @@
-.TH _STARTKLIPS 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _startklips.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec _startklips \- internal script to bring up kernel components
-.SH DESCRIPTION
-.I _startklips
-brings up the FreeS/WAN kernel component. This involves loading any
-required modules, attaching and configuring the ipsecX pseudo-devices and
-attaching the pseudo-devices to the physical devices.
-.SH "SEE ALSO"
-ipsec(8), ipsec_tncfg(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program by Henry Spencer.
-.\"
-.\" $Log: _startklips.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/_startklips/_startklips.in b/programs/_startklips/_startklips.in
deleted file mode 100755
index 7f85a94de..000000000
--- a/programs/_startklips/_startklips.in
+++ /dev/null
@@ -1,367 +0,0 @@
-#!/bin/sh
-# KLIPS startup script
-# Copyright (C) 1998, 1999, 2001, 2002 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _startklips.in,v 1.6 2005/05/06 22:11:33 as Exp $
-
-me='ipsec _startklips' # for messages
-
-# KLIPS-related paths
-sysflags=/proc/sys/net/ipsec
-modules=/proc/modules
-# full rp_filter path is $rpfilter1/interface/$rpfilter2
-rpfilter1=/proc/sys/net/ipv4/conf
-rpfilter2=rp_filter
-# %unchanged or setting (0, 1, or 2)
-rpfiltercontrol=0
-ipsecversion=/proc/net/ipsec_version
-moduleplace=/lib/modules/`uname -r`/kernel/net/ipsec
-bareversion=`uname -r | sed -e 's/^\(2\.[0-9]\.[1-9][0-9]*-[1-9][0-9]*\(\.[0-9][0-9]*\)*\(\.x\)*\).*$/\1/'`
-moduleinstplace=/lib/modules/$bareversion/kernel/net/ipsec
-modulename=ipsec.o
-klips=true
-netkey=/proc/net/pfkey
-
-info=/dev/null
-log=daemon.error
-for dummy
-do
- case "$1" in
- --log) log="$2" ; shift ;;
- --info) info="$2" ; shift ;;
- --debug) debug="$2" ; shift ;;
- --omtu) omtu="$2" ; shift ;;
- --fragicmp) fragicmp="$2" ; shift ;;
- --hidetos) hidetos="$2" ; shift ;;
- --rpfilter) rpfiltercontrol="$2" ; shift ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-
-
-# some shell functions, to clarify the actual code
-
-# set up a system flag based on a variable
-# sysflag value shortname default flagname
-sysflag() {
- case "$1" in
- '') v="$3" ;;
- *) v="$1" ;;
- esac
- if test ! -f $sysflags/$4
- then
- if test " $v" != " $3"
- then
- echo "cannot do $2=$v, $sysflags/$4 does not exist"
- exit 1
- else
- return # can't set, but it's the default anyway
- fi
- fi
- case "$v" in
- yes|no) ;;
- *) echo "unknown (not yes/no) $2 value \`$1'"
- exit 1
- ;;
- esac
- case "$v" in
- yes) echo 1 >$sysflags/$4 ;;
- no) echo 0 >$sysflags/$4 ;;
- esac
-}
-
-# set up a Klips interface
-klipsinterface() {
- # pull apart the interface spec
- virt=`expr $1 : '\([^=]*\)=.*'`
- phys=`expr $1 : '[^=]*=\(.*\)'`
- case "$virt" in
- ipsec[0-9]) ;;
- *) echo "invalid interface \`$virt' in \`$1'" ; exit 1 ;;
- esac
-
- # figure out ifconfig for interface
- addr=
- eval `ifconfig $phys |
- awk '$1 == "inet" && $2 ~ /^addr:/ && $NF ~ /^Mask:/ {
- gsub(/:/, " ", $0)
- print "addr=" $3
- other = $5
- if ($4 == "Bcast")
- print "type=broadcast"
- else if ($4 == "P-t-P")
- print "type=pointopoint"
- else if (NF == 5) {
- print "type="
- other = ""
- } else
- print "type=unknown"
- print "otheraddr=" other
- print "mask=" $NF
- }'`
- if test " $addr" = " "
- then
- echo "unable to determine address of \`$phys'"
- exit 1
- fi
- if test " $type" = " unknown"
- then
- echo "\`$phys' is of an unknown type"
- exit 1
- fi
- if test " $omtu" != " "
- then
- mtu="mtu $omtu"
- else
- mtu=
- fi
- echo "KLIPS $virt on $phys $addr/$mask $type $otheraddr $mtu" | logonly
-
- if $klips
- then
- # attach the interface and bring it up
- ipsec tncfg --attach --virtual $virt --physical $phys
- ifconfig $virt inet $addr $type $otheraddr netmask $mask $mtu
- fi
-
- # if %defaultroute, note the facts
- if test " $2" != " "
- then
- (
- echo "defaultroutephys=$phys"
- echo "defaultroutevirt=$virt"
- echo "defaultrouteaddr=$addr"
- if test " $2" != " 0.0.0.0"
- then
- echo "defaultroutenexthop=$2"
- fi
- ) >>$info
- else
- echo '#dr: no default route' >>$info
- fi
-
- # check for rp_filter trouble
- checkif $phys # thought to be a problem only on phys
-}
-
-# check an interface for problems
-checkif() {
- $klips || return 0
- rpf=$rpfilter1/$1/$rpfilter2
- if test -f $rpf
- then
- r="`cat $rpf`"
- if test " $r" != " 0"
- then
- case "$r-$rpfiltercontrol" in
- 0-%unchanged|0-0|1-1|2-2)
- # happy state
- ;;
- *-%unchanged)
- echo "WARNING: $1 has route filtering turned on; KLIPS may not work ($rpf is $r)"
- ;;
- [012]-[012])
- echo "WARNING: changing route filtering on $1 (changing $rpf from $r to $rpfiltercontrol)"
- echo "$rpfiltercontrol" >$rpf
- ;;
- [012]-*)
- echo "ERROR: unknown rpfilter setting: $rpfiltercontrol"
- ;;
- *)
- echo "ERROR: unknown $rpf value $r"
- ;;
- esac
- fi
- fi
-}
-
-# interfaces=%defaultroute: put ipsec0 on top of default route's interface
-defaultinterface() {
- phys=`netstat -nr |
- awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $NF }'`
- if test " $phys" = " "
- then
- echo "no default route, %defaultroute cannot cope!!!"
- exit 1
- fi
- if test `echo " $phys" | wc -l` -gt 1
- then
- echo "multiple default routes, %defaultroute cannot cope!!!"
- exit 1
- fi
- next=`netstat -nr |
- awk '$1 == "0.0.0.0" && $3 == "0.0.0.0" { print $2 }'`
- klipsinterface "ipsec0=$phys" $next
-}
-
-# log only to syslog, not to stdout/stderr
-logonly() {
- logger -p $log -t ipsec_setup
-}
-
-# sort out which module is appropriate, changing it if necessary
-setmodule() {
- wantgoo="`ipsec calcgoo /proc/ksyms`"
- module=$moduleplace/$modulename
- if test -f $module
- then
- goo="`nm -ao $module | ipsec calcgoo`"
- if test " $wantgoo" = " $goo"
- then
- return # looks right
- fi
- fi
- if test -f $moduleinstplace/$wantgoo
- then
- echo "insmod failed, but found matching template module $wantgoo."
- echo "Copying $moduleinstplace/$wantgoo to $module."
- rm -f $module
- mkdir -p $moduleplace
- cp -p $moduleinstplace/$wantgoo $module
- # "depmod -a" gets done by caller
- fi
-}
-
-
-
-# main line
-
-# load module if possible
-if test ! -f $ipsecversion && test ! -f $netkey
-then
- # statically compiled KLIPS not found; try to load the module
- insmod ipsec
-fi
-
-if test ! -f $ipsecversion && test ! -f $netkey
-then
- modprobe -v af_key
-fi
-
-if test -f $netkey
-then
- klips=false
- if test -f $modules
- then
- modprobe -qv ah4
- modprobe -qv esp4
- modprobe -qv ipcomp
- modprobe -qv xfrm4_tunnel
- modprobe -qv xfrm_user
- fi
-fi
-
-if test ! -f $ipsecversion && $klips
-then
- if test -r $modules # kernel does have modules
- then
- setmodule
- unset MODPATH MODULECONF # no user overrides!
- depmod -a >/dev/null 2>&1
- modprobe -v ipsec
- fi
- if test ! -f $ipsecversion
- then
- echo "kernel appears to lack KLIPS"
- exit 1
- fi
-fi
-
-# load all compiled algo modules
-if $klips
-then
- for alg in aes serpent twofish blowfish sha2
- do
- if test -f $moduleinstplace/alg/ipsec_$alg.o
- then
- modprobe ipsec_$alg
- fi
- done
-fi
-
-# figure out debugging flags
-case "$debug" in
-'') debug=none ;;
-esac
-if test -r /proc/net/ipsec_klipsdebug
-then
- echo "KLIPS debug \`$debug'" | logonly
- case "$debug" in
- none) ipsec klipsdebug --none ;;
- all) ipsec klipsdebug --all ;;
- *) ipsec klipsdebug --none
- for d in $debug
- do
- ipsec klipsdebug --set $d
- done
- ;;
- esac
-elif $klips
-then
- if test " $debug" != " none"
- then
- echo "klipsdebug=\`$debug' ignored, KLIPS lacks debug facilities"
- fi
-fi
-
-# figure out misc. kernel config
-if test -d $sysflags
-then
- sysflag "$fragicmp" "fragicmp" yes icmp
- echo 1 >$sysflags/inbound_policy_check # no debate
- sysflag no "no_eroute_pass" no no_eroute_pass # obsolete parm
- sysflag no "opportunistic" no opportunistic # obsolete parm
- sysflag "$hidetos" "hidetos" yes tos
-elif $klips
-then
- echo "WARNING: cannot adjust KLIPS flags, no $sysflags directory!"
- # carry on
-fi
-
-if $klips; then
- # clear tables out in case dregs have been left over
- ipsec eroute --clear
- ipsec spi --clear
-elif test $netkey
-then
- if ip xfrm state > /dev/null 2>&1
- then
- ip xfrm state flush
- ip xfrm policy flush
- elif type setkey > /dev/null 2>&1
- then
- setkey -F
- setkey -FP
- else
- echo "WARNING: cannot flush state/policy database -- \`$1'" |
- logger -s -p $log -t ipsec_setup
- fi
-fi
-
-# figure out interfaces
-for i
-do
- case "$i" in
- ipsec*=?*) klipsinterface "$i" ;;
- %defaultroute) defaultinterface ;;
- *) echo "interface \`$i' not understood"
- exit 1
- ;;
- esac
-done
-
-exit 0
diff --git a/programs/_updown/.cvsignore b/programs/_updown/.cvsignore
deleted file mode 100644
index 81e2e4f86..000000000
--- a/programs/_updown/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-_updown
-_updown.in
diff --git a/programs/_updown/Makefile b/programs/_updown/Makefile
deleted file mode 100644
index e0aaab488..000000000
--- a/programs/_updown/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.3 2006/04/17 06:48:49 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_updown
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
diff --git a/programs/_updown/_updown.8 b/programs/_updown/_updown.8
deleted file mode 100644
index 5107d3694..000000000
--- a/programs/_updown/_updown.8
+++ /dev/null
@@ -1,19 +0,0 @@
-.TH _UPDOWN 8 "27 Apr 2006"
-.\"
-.\" RCSID $Id: _updown.8,v 1.2 2006/04/17 06:48:49 as Exp $
-.\"
-.SH NAME
-ipsec _updown \- route and firewall manipulation script
-.SH SYNOPSIS
-.I _updown
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing entries for IPsec operation.
-It can also be used to insert and delete dynamic iptables firewall rules.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program written by Henry Spencer. Extended
-for the Linux strongSwan project <http://www.strongswan.org/> by Andreas
-Steffen.
diff --git a/programs/_updown/_updown.in b/programs/_updown/_updown.in
deleted file mode 100755
index 8db74f737..000000000
--- a/programs/_updown/_updown.in
+++ /dev/null
@@ -1,503 +0,0 @@
-#! /bin/sh
-# iproute2 version, default updown script
-#
-# Copyright (C) 2003-2004 Nigel Meteringham
-# Copyright (C) 2003-2004 Tuomo Soini
-# Copyright (C) 2002-2004 Michael Richardson
-# Copyright (C) 2005-2006 Andreas Steffen <andreas.steffen@strongswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _updown.in,v 1.2 2006/04/17 15:06:29 as Exp $
-
-# CAUTION: Installing a new version of strongSwan will install a new
-# copy of this script, wiping out any custom changes you make. If
-# you need changes, make a copy of this under another name, and customize
-# that, and use the (left/right)updown parameters in ipsec.conf to make
-# strongSwan use yours instead of this default one.
-
-# things that this script gets (from ipsec_pluto(8) man page)
-#
-# PLUTO_VERSION
-# indicates what version of this interface is being
-# used. This document describes version 1.1. This
-# is upwardly compatible with version 1.0.
-#
-# PLUTO_VERB
-# specifies the name of the operation to be performed
-# (prepare-host, prepare-client, up-host, up-client,
-# down-host, or down-client). If the address family
-# for security gateway to security gateway communica­
-# tions is IPv6, then a suffix of -v6 is added to the
-# verb.
-#
-# PLUTO_CONNECTION
-# is the name of the connection for which we are
-# routing.
-#
-# PLUTO_NEXT_HOP
-# is the next hop to which packets bound for the peer
-# must be sent.
-#
-# PLUTO_INTERFACE
-# is the name of the ipsec interface to be used.
-#
-# PLUTO_REQID
-# is the requid of the ESP policy
-#
-# PLUTO_ME
-# is the IP address of our host.
-#
-# PLUTO_MY_ID
-# is the ID of our host.
-#
-# PLUTO_MY_CLIENT
-# is the IP address / count of our client subnet. If
-# the client is just the host, this will be the
-# host's own IP address / max (where max is 32 for
-# IPv4 and 128 for IPv6).
-#
-# PLUTO_MY_CLIENT_NET
-# is the IP address of our client net. If the client
-# is just the host, this will be the host's own IP
-# address.
-#
-# PLUTO_MY_CLIENT_MASK
-# is the mask for our client net. If the client is
-# just the host, this will be 255.255.255.255.
-#
-# PLUTO_MY_SOURCEIP
-# if non-empty, then the source address for the route will be
-# set to this IP address.
-#
-# PLUTO_MY_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_MY_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on our side.
-#
-# PLUTO_PEER
-# is the IP address of our peer.
-#
-# PLUTO_PEER_ID
-# is the ID of our peer.
-#
-# PLUTO_PEER_CA
-# is the CA which issued the cert of our peer.
-#
-# PLUTO_PEER_CLIENT
-# is the IP address / count of the peer's client sub­
-# net. If the client is just the peer, this will be
-# the peer's own IP address / max (where max is 32
-# for IPv4 and 128 for IPv6).
-#
-# PLUTO_PEER_CLIENT_NET
-# is the IP address of the peer's client net. If the
-# client is just the peer, this will be the peer's
-# own IP address.
-#
-# PLUTO_PEER_CLIENT_MASK
-# is the mask for the peer's client net. If the
-# client is just the peer, this will be
-# 255.255.255.255.
-#
-# PLUTO_PEER_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_PEER_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on the peer side.
-#
-
-# uncomment to log VPN connections
-VPN_LOGGING=1
-#
-# tag put in front of each log entry:
-TAG=vpn
-#
-# syslog facility and priority used:
-FAC_PRIO=local0.notice
-#
-# to create a special vpn logging file, put the following line into
-# the syslog configuration file /etc/syslog.conf:
-#
-# local0.notice -/var/log/vpn
-#
-
-# check interface version
-case "$PLUTO_VERSION" in
-1.[0|1]) # Older Pluto?!? Play it safe, script may be using new features.
- echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
- echo "$0: called by obsolete Pluto?" >&2
- exit 2
- ;;
-1.*) ;;
-*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
- exit 2
- ;;
-esac
-
-# check parameter(s)
-case "$1:$*" in
-':') # no parameters
- ;;
-iptables:iptables) # due to (left/right)firewall; for default script only
- ;;
-custom:*) # custom parameters (see above CAUTION comment)
- ;;
-*) echo "$0: unknown parameters \`$*'" >&2
- exit 2
- ;;
-esac
-
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
- doroute add
- ip route flush cache
-}
-downroute() {
- doroute delete
- ip route flush cache
-}
-
-addsource() {
- st=0
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
- then
- it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: addsource \`$it' failed ($oops)" >&2
- fi
- fi
- return $st
-}
-
-doroute() {
- st=0
- parms="$PLUTO_PEER_CLIENT"
-
- parms2=
- if [ -n "$PLUTO_NEXT_HOP" ]
- then
- parms2="via $PLUTO_NEXT_HOP"
- fi
- parms2="$parms2 dev $PLUTO_INTERFACE"
-
- if [ -z "$PLUTO_MY_SOURCEIP" ]
- then
- if [ -f /etc/sysconfig/defaultsource ]
- then
- . /etc/sysconfig/defaultsource
- fi
-
- if [ -f /etc/conf.d/defaultsource ]
- then
- . /etc/conf.d/defaultsource
- fi
-
- if [ -n "$DEFAULTSOURCE" ]
- then
- PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
- fi
- fi
-
- parms3=
- if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
- then
- addsource
- parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
- fi
-
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # opportunistic encryption work around
- # need to provide route that eclipses default, without
- # replacing it.
- it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
- ip route $1 128.0.0.0/1 $parms2 $parms3"
- ;;
- *) it="ip route $1 $parms $parms2 $parms3"
- ;;
- esac
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: doroute \`$it' failed ($oops)" >&2
- fi
- return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
- IPSEC_POLICY_IN=""
- IPSEC_POLICY_OUT=""
-else
- IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
- IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
- IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
-
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
- S_MY_PORT="--sport $PLUTO_MY_PORT"
- D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
- S_PEER_PORT="--sport $PLUTO_PEER_PORT"
- D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
-# the big choice
-case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
- # delete possibly-existing route (preliminary to adding a route)
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # need to provide route that eclipses default, without
- # replacing it.
- parms1="0.0.0.0/1"
- parms2="128.0.0.0/1"
- it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
- oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
- ;;
- *)
- parms="$PLUTO_PEER_CLIENT"
- it="ip route delete $parms 2>&1"
- oops="`ip route delete $parms 2>&1`"
- ;;
- esac
- status="$?"
- if test " $oops" = " " -a " $status" != " 0"
- then
- oops="silent error, exit status $status"
- fi
- case "$oops" in
- *'RTNETLINK answers: No such process'*)
- # This is what route (currently -- not documented!) gives
- # for "could not find such a route".
- oops=
- status=0
- ;;
- esac
- if test " $oops" != " " -o " $status" != " 0"
- then
- echo "$0: \`$it' failed ($oops)" >&2
- fi
- exit $status
- ;;
-route-host:*|route-client:*)
- # connection to me or my client subnet being routed
- uproute
- ;;
-unroute-host:*|unroute-client:*)
- # connection to me or my client subnet being unrouted
- downroute
- ;;
-up-host:)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-host:)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-up-client:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-client:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-up-host:iptables)
- # connection to me, with (left/right)firewall=yes, coming up
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
- iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- # log IPsec host connection setup
- if [ $VPN_LOGGING ]
- then
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- fi
- ;;
-down-host:iptables)
- # connection to me, with (left/right)firewall=yes, going down
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
- iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- # log IPsec host connection teardown
- if [ $VPN_LOGGING ]
- then
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- fi
- ;;
-up-client:iptables)
- # connection to client subnet, with (left/right)firewall=yes, coming up
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
- then
- iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
- $IPSEC_POLICY_OUT -j ACCEPT
- iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $IPSEC_POLICY_IN -j ACCEPT
- fi
- #
- # a virtual IP requires an INPUT and OUTPUT rule on the host
- # or sometimes host access via the internal IP is needed
- if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
- then
- iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $IPSEC_POLICY_IN -j ACCEPT
- iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
- $IPSEC_POLICY_OUT -j ACCEPT
- fi
- #
- # log IPsec client connection setup
- if [ $VPN_LOGGING ]
- then
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- fi
- ;;
-down-client:iptables)
- # connection to client subnet, with (left/right)firewall=yes, going down
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
- then
- iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
- $IPSEC_POLICY_OUT -j ACCEPT
- iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $IPSEC_POLICY_IN -j ACCEPT
- fi
- #
- # a virtual IP requires an INPUT and OUTPUT rule on the host
- # or sometimes host access via the internal IP is needed
- if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
- then
- iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $IPSEC_POLICY_IN -j ACCEPT
- iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT \
- $IPSEC_POLICY_OUT -j ACCEPT
- fi
- #
- # log IPsec client connection teardown
- if [ $VPN_LOGGING ]
- then
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- fi
- ;;
-#
-# IPv6
-#
-prepare-host-v6:*|prepare-client-v6:*)
- ;;
-route-host-v6:*|route-client-v6:*)
- # connection to me or my client subnet being routed
- #uproute_v6
- ;;
-unroute-host-v6:*|unroute-client-v6:*)
- # connection to me or my client subnet being unrouted
- #downroute_v6
- ;;
-up-host-v6:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-host-v6:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-up-client-v6:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-client-v6:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
- exit 1
- ;;
-esac
diff --git a/programs/_updown_espmark/Makefile b/programs/_updown_espmark/Makefile
deleted file mode 100644
index bd9cd38cb..000000000
--- a/programs/_updown_espmark/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2005/04/07 21:34:19 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=_updown_espmark
-PROGRAMDIR=${LIBDIR}
-
-include ../Makefile.program
diff --git a/programs/_updown_espmark/_updown_espmark.8 b/programs/_updown_espmark/_updown_espmark.8
deleted file mode 100644
index 91eaa5cb7..000000000
--- a/programs/_updown_espmark/_updown_espmark.8
+++ /dev/null
@@ -1,18 +0,0 @@
-.TH _UPDOWN_ESPMARK 8 "7 Apr 2005"
-.\"
-.\" RCSID $Id: _updown_espmark.8,v 1.1 2005/04/07 21:34:19 as Exp $
-.\"
-.SH NAME
-ipsec _updown_espmark \- manages routes and firewall rules
-.SH SYNOPSIS
-.I _updown_espmark
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing and iptables firewall entries for
-IPsec operation. The incoming ESP traffic must be marked by a static rule
-in the mangle table. The default value for the mark is 50.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux strongSwan project <http://www.strongswan.org/>
-by Andreas Steffen. Original program written by Henry Spencer.
diff --git a/programs/_updown_espmark/_updown_espmark.in b/programs/_updown_espmark/_updown_espmark.in
deleted file mode 100644
index 3627d470d..000000000
--- a/programs/_updown_espmark/_updown_espmark.in
+++ /dev/null
@@ -1,452 +0,0 @@
-#! /bin/sh
-# iproute2 version, default updown script
-#
-# Copyright (C) 2003-2004 Nigel Meteringham
-# Copyright (C) 2003-2004 Tuomo Soini
-# Copyright (C) 2002-2004 Michael Richardson
-# Copyright (C) 2005 Andreas Steffen <andreas.steffen@strongsec.com>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: _updown_espmark.in,v 1.4 2005/09/14 14:33:05 as Exp $
-
-
-
-# CAUTION: Installing a new version of strongSwan will install a new
-# copy of this script, wiping out any custom changes you make. If
-# you need changes, make a copy of this under another name, and customize
-# that, and use the (left/right)updown parameters in ipsec.conf to make
-# FreeS/WAN use yours instead of this default one.
-
-# things that this script gets (from ipsec_pluto(8) man page)
-#
-#
-# PLUTO_VERSION
-# indicates what version of this interface is being
-# used. This document describes version 1.1. This
-# is upwardly compatible with version 1.0.
-#
-# PLUTO_VERB
-# specifies the name of the operation to be performed
-# (prepare-host, prepare-client, up-host, up-client,
-# down-host, or down-client). If the address family
-# for security gateway to security gateway communica­
-# tions is IPv6, then a suffix of -v6 is added to the
-# verb.
-#
-# PLUTO_CONNECTION
-# is the name of the connection for which we are
-# routing.
-#
-# PLUTO_NEXT_HOP
-# is the next hop to which packets bound for the peer
-# must be sent.
-#
-# PLUTO_INTERFACE
-# is the name of the ipsec interface to be used.
-#
-# PLUTO_ME
-# is the IP address of our host.
-#
-# PLUTO_MY_ID
-# is the ID of our host.
-#
-# PLUTO_MY_CLIENT
-# is the IP address / count of our client subnet. If
-# the client is just the host, this will be the
-# host's own IP address / max (where max is 32 for
-# IPv4 and 128 for IPv6).
-#
-# PLUTO_MY_CLIENT_NET
-# is the IP address of our client net. If the client
-# is just the host, this will be the host's own IP
-# address.
-#
-# PLUTO_MY_CLIENT_MASK
-# is the mask for our client net. If the client is
-# just the host, this will be 255.255.255.255.
-#
-# PLUTO_MY_SOURCEIP
-# if non-empty, then the source address for the route will be
-# set to this IP address.
-#
-# PLUTO_MY_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_MY_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on our side.
-#
-# PLUTO_PEER
-# is the IP address of our peer.
-#
-# PLUTO_PEER_ID
-# is the ID of our peer.
-#
-# PLUTO_PEER_CA
-# is the CA which issued the cert of our peer.
-#
-# PLUTO_PEER_CLIENT
-# is the IP address / count of the peer's client sub­
-# net. If the client is just the peer, this will be
-# the peer's own IP address / max (where max is 32
-# for IPv4 and 128 for IPv6).
-#
-# PLUTO_PEER_CLIENT_NET
-# is the IP address of the peer's client net. If the
-# client is just the peer, this will be the peer's
-# own IP address.
-#
-# PLUTO_PEER_CLIENT_MASK
-# is the mask for the peer's client net. If the
-# client is just the peer, this will be
-# 255.255.255.255.
-#
-# PLUTO_PEER_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_PEER_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on the peer side.
-#
-
-# logging of VPN connections
-#
-# tag put in front of each log entry:
-TAG=vpn
-#
-# syslog facility and priority used:
-FAC_PRIO=local0.notice
-#
-# to create a special vpn logging file, put the following line into
-# the syslog configuration file /etc/syslog.conf:
-#
-# local0.notice -/var/log/vpn
-#
-
-# check interface version
-case "$PLUTO_VERSION" in
-1.[0]) # Older Pluto?!? Play it safe, script may be using new features.
- echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
- echo "$0: called by obsolete Pluto?" >&2
- exit 2
- ;;
-1.*) ;;
-*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
- exit 2
- ;;
-esac
-
-# check parameter(s)
-case "$1:$*" in
-':') # no parameters
- ;;
-ipfwadm:ipfwadm) # due to (left/right)firewall; for default script only
- ;;
-custom:*) # custom parameters (see above CAUTION comment)
- ;;
-*) echo "$0: unknown parameters \`$*'" >&2
- exit 2
- ;;
-esac
-
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
- doroute add
- ip route flush cache
-}
-downroute() {
- doroute delete
- ip route flush cache
-}
-
-addsource() {
- st=0
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
- then
- it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: addsource \`$it' failed ($oops)" >&2
- fi
- fi
- return $st
-}
-
-doroute() {
- st=0
- parms="$PLUTO_PEER_CLIENT"
-
- parms2=
- if [ -n "$PLUTO_NEXT_HOP" ]
- then
- parms2="via $PLUTO_NEXT_HOP"
- fi
- parms2="$parms2 dev $PLUTO_INTERFACE"
-
- if [ -z "$PLUTO_MY_SOURCEIP" ]
- then
- if [ -f /etc/sysconfig/defaultsource ]
- then
- . /etc/sysconfig/defaultsource
- fi
-
- if [ -f /etc/conf.d/defaultsource ]
- then
- . /etc/conf.d/defaultsource
- fi
-
- if [ -n "$DEFAULTSOURCE" ]
- then
- PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
- fi
- fi
-
- parms3=
- if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
- then
- addsource
- parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
- fi
-
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # opportunistic encryption work around
- # need to provide route that eclipses default, without
- # replacing it.
- it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
- ip route $1 128.0.0.0/1 $parms2 $parms3"
- ;;
- *) it="ip route $1 $parms $parms2 $parms3"
- ;;
- esac
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: doroute \`$it' failed ($oops)" >&2
- fi
- return $st
-}
-
-# define ESP mark
-ESP_MARK=50
-
-# add the following static rule to the INPUT chain in the mangle table
-# iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
-
-# NAT traversal via UDP encapsulation is supported with the rule
-# iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
-
-# in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
- CHECK_MARK=""
-else
- CHECK_MARK="-m mark --mark $ESP_MARK"
-fi
-
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
- S_MY_PORT="--sport $PLUTO_MY_PORT"
- D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
- S_PEER_PORT="--sport $PLUTO_PEER_PORT"
- D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
-# the big choice
-case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
- # delete possibly-existing route (preliminary to adding a route)
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # need to provide route that eclipses default, without
- # replacing it.
- parms1="0.0.0.0/1"
- parms2="128.0.0.0/1"
- it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
- oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
- ;;
- *)
- parms="$PLUTO_PEER_CLIENT"
- it="ip route delete $parms 2>&1"
- oops="`ip route delete $parms 2>&1`"
- ;;
- esac
- status="$?"
- if test " $oops" = " " -a " $status" != " 0"
- then
- oops="silent error, exit status $status"
- fi
- case "$oops" in
- *'RTNETLINK answers: No such process'*)
- # This is what route (currently -- not documented!) gives
- # for "could not find such a route".
- oops=
- status=0
- ;;
- esac
- if test " $oops" != " " -o " $status" != " 0"
- then
- echo "$0: \`$it' failed ($oops)" >&2
- fi
- exit $status
- ;;
-route-host:*|route-client:*)
- # connection to me or my client subnet being routed
- uproute
- ;;
-unroute-host:*|unroute-client:*)
- # connection to me or my client subnet being unrouted
- downroute
- ;;
-up-host:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
- iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- ;;
-down-host:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
- iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- ;;
-up-client:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $CHECK_MARK -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- ;;
-down-client:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $CHECK_MARK -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- ;;
-up-client:ipfwadm)
- # connection to client subnet, with (left/right)firewall=yes, coming up
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
- -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
- ;;
-down-client:ipfwadm)
- # connection to client subnet, with (left/right)firewall=yes, going down
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
- -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
- ;;
-#
-# IPv6
-#
-prepare-host-v6:*|prepare-client-v6:*)
- ;;
-route-host-v6:*|route-client-v6:*)
- # connection to me or my client subnet being routed
- #uproute_v6
- ;;
-unroute-host-v6:*|unroute-client-v6:*)
- # connection to me or my client subnet being unrouted
- #downroute_v6
- ;;
-up-host-v6:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-host-v6:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-up-client-v6:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-client-v6:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
- exit 1
- ;;
-esac
diff --git a/programs/auto/.cvsignore b/programs/auto/.cvsignore
deleted file mode 100644
index 865faf10c..000000000
--- a/programs/auto/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-auto
diff --git a/programs/auto/Makefile b/programs/auto/Makefile
deleted file mode 100644
index 035dbf708..000000000
--- a/programs/auto/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.2 2006/02/10 11:28:38 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=auto
-
-include ../Makefile.program
diff --git a/programs/auto/auto.8 b/programs/auto/auto.8
deleted file mode 100644
index 21b5fd11b..000000000
--- a/programs/auto/auto.8
+++ /dev/null
@@ -1,481 +0,0 @@
-.TH IPSEC_AUTO 8 "17 December 2004"
-.\" RCSID $Id: auto.8,v 1.6 2004/12/17 22:34:38 as Exp $
-.SH NAME
-ipsec auto \- control automatically-keyed IPsec connections
-.SH SYNOPSIS
-.B ipsec
-.B auto
-[
-.B \-\-show
-] [
-.B \-\-showonly
-] [
-.B \-\-asynchronous
-]
-.br
-\ \ \ [
-.B \-\-config
-configfile
-] [
-.B \-\-verbose
-] [
-.B \-\-type conn
-]
-.br
-\ \ \ operation
-connection
-.sp
-.B ipsec
-.B auto
-[
-.B \-\-show
-] [
-.B \-\-showonly
-]
-.br
-\ \ \ [
-.B \-\-config
-configfile
-] [
-.B \-\-verbose
-]
-.B \-\-type ca
-.br
-\ \ \ operation
-ca
-.sp
-.B ipsec
-.B auto
-[
-.B \-\-show
-] [
-.B \-\-showonly
-] operation
-.SH DESCRIPTION
-.I Auto
-manipulates automatically-keyed strongSwan IPsec connections,
-setting them up and shutting them down
-based on the information in the IPsec configuration file.
-In the normal usage,
-.I connection
-is the name of a connection specification in the configuration file;
-.I ca
-is the name of a Certification Authority (CA) specification in the configuration file;
-.I operation
-is
-.BR \-\-add ,
-.BR \-\-delete ,
-.BR \-\-replace ,
-.BR \-\-up ,
-.BR \-\-down ,
-.BR \-\-route ,
-or
-.BR \-\-unroute .
-The
-.BR \-\-status
-and
-.BR \-\-statusall
-.I operations
-may take a
-.I connection
-name.
-The
-.BR \-\-ready ,
-.BR \-\-rereadsecrets ,
-.BR \-\-rereadgroups ,
-.BR \-\-rereadcacerts ,
-.BR \-\-rereadaacerts ,
-.BR \-\-rereadocspcerts ,
-.BR \-\-rereadacerts ,
-.BR \-\-rereadcrls ,
-.BR \-\-rereadall ,
-.BR \-\-listalgs ,
-.BR \-\-listpubkeys ,
-.BR \-\-listcerts ,
-.BR \-\-listcacerts ,
-.BR \-\-listaacerts ,
-.BR \-\-listocspcerts ,
-.BR \-\-listacerts ,
-.BR \-\-listgroups ,
-.BR \-\-listcainfos ,
-.BR \-\-listcrls ,
-.BR \-\-listocsp ,
-.BR \-\-listcards ,
-.BR \-\-listall ,
-and
-.BR \-\-purgeocsp
-.I operations
-do not take a connection name.
-.I Auto
-generates suitable
-commands and feeds them to a shell for execution.
-.PP
-The
-.B \-\-add
-operation adds a connection or ca specification to the internal database
-within
-.IR pluto ;
-it will fail if
-.I pluto
-already has a specification by that name.
-The
-.B \-\-delete
-operation deletes a connection or ca specification from
-.IR pluto 's
-internal database (also tearing down any connections based on it);
-it will fail if the specification does not exist.
-The
-.B \-\-replace
-operation is equivalent to
-.B \-\-delete
-(if there is already a specification by the given name)
-followed by
-.BR \-\-add ,
-and is a convenience for updating
-.IR pluto 's
-internal specification to match an external one.
-(Note that a
-.B \-\-rereadsecrets
-may also be needed.)
-The
-.B \-\-rereadgroups
-operation causes any changes to the policy group files to take effect
-(this is currently a synonym for
-.BR \-\-ready ,
-but that may change).
-None of the other operations alters the internal database.
-.PP
-The
-.B \-\-up
-operation asks
-.I pluto
-to establish a connection based on an entry in its internal database.
-The
-.B \-\-down
-operation tells
-.I pluto
-to tear down such a connection.
-.PP
-Normally,
-.I pluto
-establishes a route to the destination specified for a connection as
-part of the
-.B \-\-up
-operation.
-However, the route and only the route can be established with the
-.B \-\-route
-operation.
-Until and unless an actual connection is established,
-this discards any packets sent there,
-which may be preferable to having them sent elsewhere based on a more
-general route (e.g., a default route).
-.PP
-Normally,
-.IR pluto 's
-route to a destination remains in place when a
-.B \-\-down
-operation is used to take the connection down
-(or if connection setup, or later automatic rekeying, fails).
-This permits establishing a new connection (perhaps using a
-different specification; the route is altered as necessary)
-without having a ``window'' in which packets might go elsewhere
-based on a more general route.
-Such a route can be removed using the
-.B \-\-unroute
-operation
-(and is implicitly removed by
-.BR \-\-delete ).
-.PP
-The
-.B \-\-ready
-operation tells
-.I pluto
-to listen for connection-setup requests from other hosts.
-Doing an
-.B \-\-up
-operation before doing
-.B \-\-ready
-on both ends is futile and will not work,
-although this is now automated as part of IPsec startup and
-should not normally be an issue.
-.PP
-The
-.B \-\-status
-operation asks
-.I pluto
-for current connection status either for all connections
-(no connection argument) or a for specified
-.I connection
-name. For more detailed information use
-.B \-\-statusall
-\. The output format is ad-hoc and likely to change.
-.PP
-The
-.B \-\-rereadsecrets
-operation tells
-.I pluto
-to re-read the
-.I /etc/ipsec.secrets
-secret-keys file,
-which it normally reads only at startup time.
-(This is currently a synonym for
-.BR \-\-ready ,
-but that may change.)
-.PP
-The
-.B \-\-rereadcacerts
-operation reads all certificate files contained in the
-.IR /etc/ipsec.d/cacerts
-directory and adds them to
-.IR pluto 's
-list of Certification Authority (CA) certificates.
-.PP
-The
-.B \-\-rereadaacerts
-operation reads all certificate files contained in the
-.IR /etc/ipsec.d/aacerts
-directory and adds them to
-.IR pluto 's
-list of Authorization Authority (AA) certificates.
-.PP
-The
-.B \-\-rereadocspcerts
-operation reads all certificate files contained in the
-.IR /etc/ipsec.d/ocspcerts
-directory and adds them to
-.IR pluto 's
-list of OCSP signer certificates.
-.PP
-The
-.B \-\-rereadacerts
-operation reads all certificate files contained in the
-.IR /etc/ipsec.d/acerts
-directory and adds them to
-.IR pluto 's
-list of attribute certificates.
-.PP
-The
-.B \-\-rereadcrls
-operation reads all certificate revocation list (CRL) files
-contained in the
-.IR /etc/ipsec.d/crls
-directory and adds them to
-.IR pluto 's
-list of CRLs.
-.PP
-The
-.B \-\-rereadall
-operation is equivalent to the execution of
-.BR \-\-rereadsecrets ,
-.BR \-\-rereadcacerts ,
-.BR \-\-rereadaacerts ,
-.BR \-\-rereadocspcerts ,
-.BR \-\-rereadacerts ,
-and
-.BR \-\-rereadcrls .
-.PP
-The
-.B \-\-listalgs
-operation lists all registed IKE encryption and hash algorithms,
-that are available to
-.IR pluto ,
-as well as the Diffie-Hellman (DH) groups.
-.PP
-The
-.B \-\-listpubkeys
-operation lists all RSA public keys either received from peers
-via the IKE protocol embedded in authenticated certificate payloads
-or loaded locally using the
-.BR rightcert \ /
-.BR leftcert
-or
-.BR rightrsasigkey \ /
-.BR leftrsasigkey
-parameters in
-.IR ipsec.conf (5).
-.PP
-The
-.B \-\-listcerts
-operation lists all X.509 and OpenPGP certificates loaded locally using the
-.BR rightcert
-and
-.BR leftcert
-parameters in
-.IR ipsec.conf (5).
-.PP
-The
-.B \-\-listcacerts
-operation lists all X.509 CA certificates either loaded locally from the
-.IR /etc/ipsec.d/cacerts
-directory or received in PKCS#7-wrapped certificate payloads via
-the IKE protocol.
-.PP
-The
-.B \-\-listaacerts
-operation lists all X.509 AA certificates loaded locally from the
-.IR /etc/ipsec.d/aacerts
-directory.
-.PP
-The
-.B \-\-listocspcerts
-operation lists all OCSP signer certificates either loaded locally from the
-.IR /etc/ipsec.d/ocspcerts
-directory or received via the Online Certificate Status Protocol
-from an OCSP server.
-.PP
-The
-.B \-\-listacerts
-operation lists all X.509 attribute certificates loaded locally from the
-.IR /etc/ipsec.d/acerts
-directory.
-.PP
-The
-.B \-\-listgropus
-operation lists all groups that are either used in connection definitions in
-.IR ipsec.conf (5)
-or are embedded in loaded X.509 attributes certificates.
-.PP
-The
-.B \-\-listcainfos
-operation lists the certification authority information specified in the ca
-sections of
-.IR ipsec.conf (5).
-.PP
-The
-.B \-\-listcrls
-operation lists all Certificate Revocation Lists (CRLs) either loaded
-locally from the
-.IR /etc/ipsec.d/crls
-directory or fetched dynamically from an HTTP or LDAP server.
-.PP
-The
-.B \-\-listocsp
-operation lists the certicates status information fetched from
-OCSP servers.
-.PP
-The
-.B \-\-purgeocsp
-operation deletes any cached certificate status information and pending
-OCSP fetch requests.
-.PP
-The
-.B \-\-listcards
-operation lists information about attached smartcards or crypto tokens.
-.PP
-The
-.B \-\-listall
-operation is equivalent to the execution of
-.BR \-\-listalgs ,
-.BR \-\-listpubkeys ,
-.BR \-\-listcerts ,
-.BR \-\-listcacerts ,
-.BR \-\-listaacerts ,
-.BR \-\-listocspcerts ,
-.BR \-\-listacerts ,
-.BR \-\-listgroups ,
-.BR \-\-listcainfos ,
-.BR \-\-listcrls ,
-.BR \-\-listocsp ,
-and
-.BR \-\-listcards .
-.PP
-The
-.B \-\-show
-option turns on the
-.B \-x
-option of the shell used to execute the commands,
-so each command is shown as it is executed.
-.PP
-The
-.B \-\-showonly
-option causes
-.I auto
-to show the commands it would run, on standard output,
-and not run them.
-.PP
-The
-.B \-\-asynchronous
-option, applicable only to the
-.B up
-operation,
-tells
-.I pluto
-to attempt to establish the connection,
-but does not delay to report results.
-This is especially useful to start multiple connections in parallel
-when network links are slow.
-.PP
-The
-.B \-\-verbose
-option instructs
-.I auto
-to pass through all output from
-.IR ipsec_whack (8),
-including log output that is normally filtered out as uninteresting.
-.PP
-The
-.B \-\-config
-option specifies a non-standard location for the IPsec
-configuration file (default
-.IR /etc/ipsec.conf ).
-.PP
-See
-.IR ipsec.conf (5)
-for details of the configuration file.
-Apart from the basic parameters which specify the endpoints and routing
-of a connection (\fBleft\fR
-and
-.BR right ,
-plus possibly
-.BR leftsubnet ,
-.BR leftnexthop ,
-.BR leftfirewall ,
-their
-.B right
-equivalents,
-and perhaps
-.BR type ),
-an
-.I auto
-connection almost certainly needs a
-.B keyingtries
-parameter (since the
-.B keyingtries
-default is poorly chosen).
-.SH FILES
-.ta \w'/var/run/ipsec.info'u+4n
-/etc/ipsec.conf default IPSEC configuration file
-.br
-/var/run/ipsec.info \fB%defaultroute\fR information
-.SH SEE ALSO
-ipsec.conf(5), ipsec(8), ipsec_pluto(8), ipsec_whack(8), ipsec_manual(8)
-.SH HISTORY
-Written for the FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-Extended for the strongSwan project
-<http://www.strongswan.org>
-by Andreas Steffen.
-.SH BUGS
-Although an
-.B \-\-up
-operation does connection setup on both ends,
-.B \-\-down
-tears only one end of the connection down
-(although the orphaned end will eventually time out).
-.PP
-There is no support for
-.B passthrough
-connections.
-.PP
-A connection description which uses
-.B %defaultroute
-for one of its
-.B nexthop
-parameters but not the other may be falsely
-rejected as erroneous in some circumstances.
-.PP
-The exit status of
-.B \-\-showonly
-does not always reflect errors discovered during processing of the request.
-(This is fine for human inspection, but not so good for use in scripts.)
diff --git a/programs/auto/auto.in b/programs/auto/auto.in
deleted file mode 100755
index 05568f9b5..000000000
--- a/programs/auto/auto.in
+++ /dev/null
@@ -1,660 +0,0 @@
-#! /bin/sh
-# user interface to automatic keying and Pluto in general
-# Copyright (C) 1998, 1999, 2000 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: auto.in,v 1.17 2006/04/20 04:42:12 as Exp $
-
-me='ipsec auto'
-usage="Usage:
- $me [--showonly] [--asynchronous] --up connectionname
- $me [--showonly] [-- type conn|ca] --{add|delete|replace|down} name
- $me [--showonly] --{route|unroute} connectionname
- $me [--showonly] --ready
- $me [--showonly] --{status|statusall} [connectionname]
- $me [--showonly] --{rereadsecrets|rereadgroups}
- $me [--showonly] --{rereadcacerts|rereadaacerts|rereadocspcerts}
- $me [--showonly] --{rereadacerts|rereadcrls|rereadall}
- $me [--showonly] [--utc] --{listalgs|listpubkeys|listcerts}
- $me [--showonly] [--utc] --{listcacerts|listaacerts|listocspcerts}
- $me [--showonly] [--utc] --{listacerts|listgroups|listcainfos}
- $me [--showonly] [--utc] --{listcrls|listocsp|listcards|listall}
- $me [--showonly] --purgeocsp
-
- other options: [--config ipsecconfigfile] [--verbose] [--show]"
-
-showonly=
-config=
-info=/var/run/ipsec.info
-shopts=
-noinclude=
-async=
-logfilter='$1 != "002"'
-op=
-argc=
-utc=
-type="conn"
-name="--name"
-
-for dummy
-do
- case "$1" in
- --help) echo "$usage" ; exit 0 ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --show) shopts=-x ;;
- --showonly) showonly=yes ;;
- --utc) utc="$1" ;;
- --config) config="--config $2" ; shift ;;
- --noinclude) noinclude=--noinclude ;;
- --asynchronous) async="--asynchronous" ;;
- --verbose) logfilter='1' ;;
- --type) type="$2" ; shift ;;
- --up|--down|--add|--delete|--replace|--route|--unroute)
- if test " $op" != " "
- then
- echo "$usage" >&2
- exit 2
- fi
- op="$1"
- argc=1
- if test "$type" = "ca"
- then
- name="--caname"
- case "$op" in
- --add|--delete|--replace) ;;
- --*) echo "$op option not supported for --type ca";
- exit 3 ;;
- esac
- fi
- ;;
- --status|--statusall)
- if test " $op" != " "
- then
- echo "$usage" >&2
- exit 2
- fi
- op="$1"
- argc=1
- if test $# -eq 1
- then
- argc=0; name=
- fi
- ;;
- --ready|--rereadsecrets|--rereadgroups|\
- --rereadcacerts|--rereadaacerts|--rereadocspcerts|\
- --rereadacerts|--rereadcrls|--rereadall|\
- --listalgs|--listpubkeys|--listcerts|\
- --listcacerts|--listaacerts|--listocspcerts|\
- --listacerts|--listgroups|--listcainfos|\
- --listcrls|--listocsp|--listcards|--listall|\
- --purgeocsp)
- if test " $op" != " "
- then
- echo "$usage" >&2
- exit 2
- fi
- op="$1"
- argc=0
- ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-names=
-case "$op" in
---*) if test " $argc" -ne $#
- then
- echo "$usage" >&2
- exit 2
- fi
- names="$*"
- ;;
-*) echo "$usage" >&2 ; exit 2 ;;
-esac
-
-
-runit() {
- if test "$showonly"
- then
- cat
- else
- (
- echo '('
- cat
- echo ')'
- echo 'echo = $?'
- ) | sh $shopts |
- awk "/^= / { exit \$2 } $logfilter { print }"
- fi
-}
-
-case "$op" in
---ready) echo "ipsec whack --listen" | runit ; exit ;;
---rereadsecrets) echo "ipsec whack --rereadsecrets" | runit ; exit ;;
---rereadgroups) echo "ipsec whack --listen" | runit ; exit ;;
---rereadcacerts) echo "ipsec whack --rereadcacerts" | runit ; exit ;;
---rereadaacerts) echo "ipsec whack --rereadaacerts" | runit ; exit ;;
---rereadocspcerts) echo "ipsec whack --rereadocspcerts" | runit ; exit ;;
---rereadacerts) echo "ipsec whack --rereadacerts" | runit ; exit ;;
---rereadcrls) echo "ipsec whack --rereadcrls" | runit ; exit ;;
---rereadall) echo "ipsec whack --rereadall" | runit ; exit ;;
---listalgs) echo "ipsec whack --listalgs" | runit ; exit ;;
---listpubkeys) echo "ipsec whack $utc --listpubkeys" | runit ; exit ;;
---listcerts) echo "ipsec whack $utc --listcerts" | runit ; exit ;;
---listcacerts) echo "ipsec whack $utc --listcacerts" | runit ; exit ;;
---listaacerts) echo "ipsec whack $utc --listaacerts" | runit ; exit ;;
---listocspcerts) echo "ipsec whack $utc --listocspcerts" | runit ; exit ;;
---listacerts) echo "ipsec whack $utc --listacerts" | runit ; exit ;;
---listgroups) echo "ipsec whack $utc --listgroups" | runit ; exit ;;
---listcainfos) echo "ipsec whack $utc --listcainfos" | runit ; exit ;;
---listcrls) echo "ipsec whack $utc --listcrls" | runit ; exit ;;
---listocsp) echo "ipsec whack $utc --listocsp" | runit ; exit ;;
---listcards) echo "ipsec whack $utc --listcards" | runit ; exit ;;
---listall) echo "ipsec whack $utc --listall" | runit ; exit ;;
---purgeocsp) echo "ipsec whack $utc --purgeocsp" | runit ; exit ;;
---up) echo "ipsec whack $async --name $names --initiate" | runit ; exit ;;
---down) echo "ipsec whack --name $names --terminate" | runit ; exit ;;
---delete) echo "ipsec whack $name $names --delete" | runit ; exit ;;
---route) echo "ipsec whack --name $names --route" | runit ; exit ;;
---unroute) echo "ipsec whack --name $names --unroute" | runit ; exit ;;
---status) echo "ipsec whack $name $names --status" | runit ; exit ;;
---statusall) echo "ipsec whack $name $names --statusall" | runit ; exit ;;
-esac
-
-if test -s $info
-then
- . $info
-fi
-
-ipsec _confread $config $noinclude --type $type $names |
-awk -v section="$type" ' BEGIN {
- FS = "\t"
- op = "'"$op"'"
- err = "cat >&2"
- draddr = "'"$defaultrouteaddr"'"
- drnexthop = "'"$defaultroutenexthop"'"
- failed = 0
- s[""] = ""
- init()
- print "PATH=\"'"$PATH"'\""
- print "export PATH"
- flip["left"] = "right"
- flip["right"] = "left"
- }
- function init(n) {
- for (n in s)
- delete s[n]
- name = ""
- seensome = 0
- }
- $1 == ":" {
- s[$2] = $3
- seensome = 1
- next
- }
- $1 == "!" {
- if ($2 != "")
- fail($2)
- next
- }
- $1 == "=" {
- if (name == "")
- name = $2
- next
- }
- $1 == "." {
- if (section == "ca")
- output_ca()
- else
- output()
- init()
- next
- }
- {
- fail("internal error, unknown type code " v($1))
- }
- function fail(m) {
- print "ipsec_auto: fatal error in " v(name) ": " m |err
- failed = 1
- exit
- }
- function yesno(k) {
- if ((k in s) && s[k] != "yes" && s[k] != "no")
- fail("parameter " v(k) " must be \"yes\" or \"no\"")
- }
- function setdefault(k, val) {
- if (!(k in s))
- s[k] = val
- }
- function was(new, old) {
- if (!(new in s) && (old in s))
- s[new] = s[old]
- }
- function need(k) {
- if (!(k in s))
- fail("connection has no " v(k) " parameter specified")
- if (s[k] == "")
- fail("parameter " v(k) " value must be non-empty")
- }
- function integer(k) {
- if (!(k in s))
- return
- if (s[k] !~ /^[0-9]+$/)
- fail("parameter " v(k) " value must be integer")
- }
- function duration(k, n, t) {
- if (!(k in s))
- return
- t = s[k]
- n = substr(t, 1, length(t)-1)
- if (t ~ /^[0-9]+$/)
- s[k] = t
- else if (t ~ /^[0-9]+s$/)
- s[k] = n
- else if (t ~ /^[0-9]+(\.[0-9]+)?m$/)
- s[k] = int(n*60)
- else if (t ~ /^[0-9]+(\.[0-9]+)?h$/)
- s[k] = int(n*3600)
- else if (t ~ /^[0-9]+(\.[0-9]+)?d$/)
- s[k] = int(n*3600*24)
- else
- fail("parameter " v(k) " not valid time, must be nnn[smhd]")
- }
- function nexthopset(dir, val, k) {
- k = dir "nexthop"
- if (k in s)
- fail("non-default value of " k " is being overridden")
- if (val != "")
- s[k] = val
- else if (k in s)
- delete s[k]
- }
- function id(dir, k) {
- k = dir "id"
- if (!(k in s))
- k = dir
- return s[k]
- }
- function whackkey(dir, which, flag, rk, n) {
- if (id(dir) == "%opportunistic")
- return
- rk = s[dir which]
- if (rk == "%dnsondemand")
- {
- kod="--dnskeyondemand"
- return
- }
- if (rk == "" || rk == "%none" || rk == "%cert" || rk == "0x00")
- return
- n = "\"\\\"" name "\\\" " dir which"\""
- if (rk == "%dns" || rk == "%dnsonload")
- {
- if (id(flip[dir]) == "%opportunistic" || s[flip[dir]] == "%any")
- return
- print "ipsec whack --label", n, flag,
- "--keyid", q(id(dir)), "\\"
- }
- else
- {
- print "ipsec whack --label", n, flag,
- "--keyid", q(id(dir)),
- "--pubkeyrsa", q(rk), "\\"
- }
- print "\t|| exit $?"
- }
- function q(str) { # quoting for shell
- return "\"" str "\""
- }
- function qs(k) { # utility abbreviation for q(s[k])
- return q(s[k])
- }
- function v(str) { # quoting for human viewing
- return "\"" str "\""
- }
- function output() {
- if (!seensome)
- fail("internal error, output called inappropriately")
-
- setdefault("type", "tunnel")
- type_flags = ""
- t = s["type"]
- if (t == "tunnel") {
- # do NOT default subnets to side/32, despite what
- # the docs say...
- type_flags = "--tunnel"
- } else if (t == "transport") {
- if ("leftsubnet" in s)
- fail("type=transport incompatible with leftsubnet")
- if ("rightsubnet" in s)
- fail("type=transport incompatible with rightsubnet")
- type_flags = ""
- } else if (t == "passthrough") {
- type_flags = "--pass"
- } else if (t == "drop") {
- type_flags = "--drop"
- } else if (t == "reject") {
- type_flags = "--reject"
- } else
- fail("unknown type " v(t))
-
- setdefault("failureshunt", "none")
- t = s["failureshunt"]
- if (t == "passthrough")
- type_flags = type_flags " --failpass";
- else if (t == "drop")
- type_flags = type_flags " --faildrop";
- else if (t == "reject")
- type_flags = type_flags " --failreject";
- else if (t != "none")
- fail("unknown failureshunt value " v(t))
-
- need("left")
- need("right")
- if (s["left"] == "%defaultroute") {
- if (s["right"] == "%defaultroute")
- fail("left and right cannot both be %defaultroute")
- if (draddr == "")
- fail("%defaultroute requested but not known")
- s["left"] = draddr
- nexthopset("left", drnexthop)
- } else if (s["right"] == "%defaultroute") {
- if (draddr == "")
- fail("%defaultroute requested but not known")
- s["right"] = draddr
- nexthopset("right", drnexthop)
- }
-
- setdefault("keyexchange", "ike")
- if (s["keyexchange"] != "ike")
- fail("only know how to do keyexchange=ike")
- setdefault("auth", "esp")
- if (("auth" in s) && s["auth"] != "esp" && s["auth"] != "ah")
- fail("only know how to do auth=esp or auth=ah")
- yesno("pfs")
-
- setdefault("pfs", "yes")
- duration("dpddelay")
- duration("dpdtimeout")
- if ("dpdaction" in s)
- {
- setdefault("dpddelay",30)
- setdefault("dpdtimeout",120)
- }
- yesno("compress")
- setdefault("compress", "no")
- setdefault("keylife", "1h")
- duration("keylife")
- yesno("rekey")
- setdefault("rekey", "yes")
- setdefault("rekeymargin", "9m")
- duration("rekeymargin")
- setdefault("keyingtries", "%forever")
- if (s["keyingtries"] == "%forever")
- s["keyingtries"] = 0
- integer("keyingtries")
- if ("rekeyfuzz" in s) {
- if (s["rekeyfuzz"] !~ /%$/)
- fail("rekeyfuzz must be nnn%")
- r = s["rekeyfuzz"]
- s["rekeyfuzz"] = substr(r, 1, length(r)-1)
- integer("rekeyfuzz")
- }
- duration("ikelifetime")
- setdefault("disablearrivalcheck", "no")
-
- setdefault("leftsendcert", "always")
- setdefault("rightsendcert", "always")
-
- setdefault("leftnexthop", "%direct")
- setdefault("rightnexthop", "%direct")
- if (s["leftnexthop"] == s["left"])
- fail("left and leftnexthop must not be the same")
- if (s["rightnexthop"] == s["right"])
- fail("right and rightnexthop must not be the same")
- if (s["leftnexthop"] == "%defaultroute") {
- if (drnexthop == "")
- fail("%defaultroute requested but not known")
- s["leftnexthop"] = drnexthop
- }
- if (s["rightnexthop"] == "%defaultroute") {
- if (drnexthop == "")
- fail("%defaultroute requested but not known")
- s["rightnexthop"] = drnexthop
- }
-
- if ("leftfirewall" in s && "leftupdown" in s)
- fail("cannot have both leftfirewall and leftupdown")
- if ("rightfirewall" in s && "rightupdown" in s)
- fail("cannot have both rightfirewall and rightupdown")
- setdefault("leftupdown", "ipsec _updown")
- setdefault("rightupdown", "ipsec _updown")
- setdefault("lefthostaccess", "no")
- setdefault("righthostaccess", "no")
- yesno("lefthostaccess")
- yesno("righthostaccess")
- lha = ""
- if (s["lefthostaccess"] == "yes")
- lha = "--hostaccess"
- rha = ""
- if (s["righthostaccess"] == "yes")
- rha = "--hostaccess"
- setdefault("leftfirewall", "no")
- setdefault("rightfirewall", "no")
- yesno("leftfirewall")
- yesno("rightfirewall")
- if (s["leftfirewall"] == "yes")
- s["leftupdown"] = s["leftupdown"] " iptables"
- if (s["rightfirewall"] == "yes")
- s["rightupdown"] = s["rightupdown"] " iptables"
-
- setdefault("authby", "rsasig")
- t = s["authby"]
- if (t == "rsasig" || t == "secret|rsasig" || t == "rsasig|secret") {
- authtype = "--rsasig"
- type_flags = "--encrypt " type_flags
- if (!("leftcert" in s)) {
- setdefault("leftrsasigkey", "%cert")
- if (id("left") == "%any" &&
- !(s["leftrsasigkey"] == "%cert" ||
- s["leftrsasigkey"] == "0x00") )
- fail("ID " v(id("left")) " cannot have RSA key")
- }
- if (!("rightcert" in s)) {
- setdefault("rightrsasigkey", "%cert")
- if (id("right") == "%any" &&
- !(s["rightrsasigkey"] == "%cert" ||
- s["rightrsasigkey"] == "0x00") )
- fail("ID " v(id("right")) " cannot have RSA key")
- }
- if (t != "rsasig")
- authtype = authtype " --psk"
- } else if (t == "secret") {
- authtype = "--psk"
- type_flags = "--encrypt " type_flags
- } else if (t == "never") {
- authtype = ""
- } else {
- fail("unknown authby value " v(t))
- }
-
- settings = type_flags
- setdefault("ike", "3des-sha,3des-md5")
- if (s["ike"] != "")
- settings = settings " --ike " qs("ike")
- setdefault("esp", "3des")
- if (s["esp"] != "")
- settings = settings " --esp " qs("esp")
- if (s["auth"] == "ah")
- settings = settings " --authenticate"
- if (s["pfs"] == "yes") {
- settings = settings " --pfs"
- if (s["pfsgroup"] != "")
- settings = settings " --pfsgroup " qs("pfsgroup")
- }
-
- if (s["dpdaction"])
- settings = settings " --dpdaction " qs("dpdaction")
- if (s["dpddelay"])
- settings = settings " --dpddelay " qs("dpddelay")
- if (s["dpdtimeout"])
- settings = settings " --dpdtimeout " qs("dpdtimeout")
-
- if (s["compress"] == "yes")
- settings = settings " --compress"
- if (op == "--replace")
- settings = settings " --delete"
- if ("ikelifetime" in s)
- settings = settings " --ikelifetime " qs("ikelifetime")
- if (s["disablearrivalcheck"] == "yes")
- settings = settings " --disablearrivalcheck"
- settings = settings " " authtype
-
- lc = ""
- rc = ""
- if ("leftsubnet" in s)
- lc = "--client " qs("leftsubnet")
- if ("rightsubnet" in s)
- rc = "--client " qs("rightsubnet")
- if ("leftsubnetwithin" in s)
- lc = lc " --clientwithin " qs("leftsubnetwithin")
- if ("rightsubnetwithin" in s)
- rc = rc " --clientwithin " qs("rightsubnetwithin")
- lp = ""
- rp = ""
- if ("leftprotoport" in s)
- lp = "--clientprotoport " qs("leftprotoport")
- if ("rightprotoport" in s)
- rp = "--clientprotoport " qs("rightprotoport")
- lud = "--updown " qs("leftupdown")
- rud = "--updown " qs("rightupdown")
-
- lid = ""
- if ("leftid" in s)
- lid = "--id " qs("leftid")
- rid = ""
- if ("rightid" in s)
- rid = "--id " qs("rightid")
- lsip = ""
- if ("leftsourceip" in s)
- lsip = "--srcip " qs("leftsourceip")
- rsip = ""
- if ("rightsourceip" in s)
- rsip = "--srcip " qs("rightsourceip")
- lscert = ""
- if ("leftsendcert" in s)
- lscert = "--sendcert " qs("leftsendcert")
- rscert = ""
- if ("rightsendcert" in s)
- rscert = "--sendcert " qs("rightsendcert")
- lcert = ""
- if ("leftcert" in s)
- lcert = "--cert " qs("leftcert")
- rcert = ""
- if ("rightcert" in s)
- rcert = "--cert " qs("rightcert")
- lca = ""
- if ("leftca" in s)
- lca = "--ca " qs("leftca")
- rca = ""
- if ("rightca" in s)
- rca = "--ca " qs("rightca")
- lgr = ""
- if ("leftgroups" in s)
- lgr = "--groups " qs("leftgroups")
- rgr = ""
- if ("rightgroups" in s)
- rgr = "--groups " qs("rightgroups")
- fuzz = ""
- if ("rekeyfuzz" in s)
- fuzz = "--rekeyfuzz " qs("rekeyfuzz")
- rk = ""
- if (s["rekey"] == "no")
- rk = "--dontrekey"
- pd = ""
- if ("_plutodevel" in s)
- pd = "--plutodevel " s["_plutodevel"] # not qs()
-
- lkod = ""
- rkod = ""
- if (authtype != "--psk") {
- kod = ""
- whackkey("left", "rsasigkey", "")
- whackkey("left", "rsasigkey2", "--addkey")
- lkod = kod
- kod = ""
- whackkey("right", "rsasigkey", "")
- whackkey("right", "rsasigkey2", "--addkey")
- rkod = kod
- }
- print "ipsec whack --name", name, settings, "\\"
- print "\t--host", qs("left"), lc, lp, "--nexthop",
- qs("leftnexthop"), lud, lha, lid, lkod, lscert, lcert, lca, lsip, lgr, "\\"
- print "\t--to", "--host", qs("right"), rc, rp, "--nexthop",
- qs("rightnexthop"), rud, rha, rid, rkod, rscert, rcert, rca, rsip, rgr, "\\"
- print "\t--ipseclifetime", qs("keylife"),
- "--rekeymargin", qs("rekeymargin"), "\\"
- print "\t--keyingtries", qs("keyingtries"), fuzz, rk, pd, "\\"
- print "\t|| exit $?"
- }
- function output_ca() {
- if (!seensome)
- fail("internal error, output called inappropriately")
- settings = ""
- if (op == "--replace")
- settings = "--delete"
- cacert = ""
- if ("cacert" in s)
- cacert = "--cacert " qs("cacert")
- ldaphost = ""
- if ("ldaphost" in s)
- ldaphost = "--ldaphost " qs("ldaphost")
- ldapbase = ""
- if ("ldapbase" in s)
- ldapbase = "--ldapbase " qs("ldapbase")
- crluri = ""
- if ("crluri" in s)
- crluri = "--crluri " qs("crluri")
- crluri2 = ""
- if ("crluri2" in s)
- crluri2 = "--crluri2 " qs("crluri2")
- ocspuri = ""
- if ("ocspuri" in s)
- ocspuri = "--ocspuri " qs("ocspuri")
- yesno("strictcrlpolicy")
- setdefault("strictcrlpolicy", "no")
- if (s["strictcrlpolicy"] == "yes")
- settings = settings " --strictcrlpolicy"
- yesno("cachecrls")
- setdefault("cachecrls", "no")
- if (s["cachecrls"] == "yes")
- settings = settings " --cachecrls"
-
- print "ipsec whack --caname", name, settings, cacert, ldaphost, ldapbase,
- crluri, crluri2, ocspuri, "\\"
- print "\t|| exit $?"
- }
- END {
- if (failed) {
- print "# fatal error discovered, force failure using \"false\" command"
- print "false"
- exit 1 # just on general principles
- }
- if (seensome) {
- if (section == "ca")
- output_ca()
- else
- output()
- }
- }' | runit
diff --git a/programs/barf/.cvsignore b/programs/barf/.cvsignore
deleted file mode 100644
index bca77a6ee..000000000
--- a/programs/barf/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-barf
diff --git a/programs/barf/Makefile b/programs/barf/Makefile
deleted file mode 100644
index 6a20d4ee2..000000000
--- a/programs/barf/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=barf
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/barf/barf.8 b/programs/barf/barf.8
deleted file mode 100644
index e692a4e5f..000000000
--- a/programs/barf/barf.8
+++ /dev/null
@@ -1,84 +0,0 @@
-.TH IPSEC_BARF 8 "17 March 2002"
-.\" RCSID $Id: barf.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.SH NAME
-ipsec barf \- spew out collected IPsec debugging information
-.SH SYNOPSIS
-.B ipsec
-.B barf
-[
-.B \-\-short
-]
-.sp
-.SH DESCRIPTION
-.I Barf
-outputs (on standard output) a collection of debugging information
-(contents of files, selections from logs, etc.)
-related to the IPsec encryption/authentication system.
-It is primarily a convenience for remote debugging,
-a single command which packages up (and labels) all information
-that might be relevant to diagnosing a problem in IPsec.
-.PP
-.PP
-The
-.B \-\-short
-option limits the length of
-the log portion of
-.IR barf 's
-output, which can otherwise be extremely voluminous
-if debug logging is turned on.
-.PP
-.I Barf
-censors its output,
-replacing keys
-and secrets with brief checksums to avoid revealing sensitive information.
-.PP
-Beware that the output of both commands is aimed at humans,
-not programs,
-and the output format is subject to change without warning.
-.PP
-.I Barf
-has to figure out which files in
-.I /var/log
-contain the IPsec log messages.
-It looks for KLIPS and general log messages first in
-.IR messages
-and
-.IR syslog ,
-and for Pluto messages first in
-.IR secure ,
-.IR auth.log ,
-and
-.IR debug .
-In both cases,
-if it does not find what it is looking for in one of those ``likely'' places,
-it will resort to a brute-force search of most (non-compressed) files in
-.IR /var/log .
-.SH FILES
-.nf
-/proc/net/*
-/var/log/*
-/etc/ipsec.conf
-/etc/ipsec.secrets
-.fi
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-.SH BUGS
-.I Barf
-uses heuristics to try to pick relevant material out of the logs,
-and relevant messages
-which are not labelled with any of the tags that
-.I barf
-looks for will be lost.
-We think we've eliminated the last such case, but one never knows...
-.PP
-Finding
-.I updown
-scripts (so they can be included in output) is, in general, difficult.
-.I Barf
-uses a very simple heuristic that is easily fooled.
-.PP
-The brute-force search for the right log files can get expensive on
-systems with a lot of clutter in
-.IR /var/log .
diff --git a/programs/barf/barf.in b/programs/barf/barf.in
deleted file mode 100755
index 99cc3546c..000000000
--- a/programs/barf/barf.in
+++ /dev/null
@@ -1,296 +0,0 @@
-#! /bin/sh
-# dump assorted information of use in debugging
-# Copyright (C) 1998, 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: barf.in,v 1.4 2004/09/23 21:08:23 as Exp $
-
-IPSEC_NAME="strongSwan"
-
-KERNSRC=${KERNSRC-/usr/src/linux}
-LOGS=${LOGS-/var/log}
-CONFS=${IPSEC_CONFS-/etc}
-CONFDDIR=${IPSEC_CONFDDIR-/etc/ipsec.d}
-me="ipsec barf"
-
-# kludge to produce no barf output mentioning policygroups if none are present.
-# This will not catch ".file" policygroups.
-PREPOLICIES=${CONFDDIR}/policies
-if [ `ls $PREPOLICIES 2> /dev/null | wc -l` -ne 0 ]
-then
- POLICIES=$PREPOLICIES
-fi
-
-# message patterns that start relevant parts of logs
-fstart="Starting $IPSEC_NAME"
-pstart='Starting Pluto subsystem'
-
-case "$1" in
---help) echo "Usage: ipsec barf" ; exit 0 ;;
---version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
-esac
-
-# make sure output is in English
-unset LANG LANGUAGE LC_ALL LC_MESSAGES
-
-# log-location guesser, results in $findlog_file and $findlog_startline
-# Fine point: startline is the *last* line containing "string", or
-# failing that, the *first* line containing "fallbackstring".
-findlog() { # findlog string fallbackstring possiblefile ...
- s="$1"
- shift
- t="$1"
- shift
- # try the suggested files first
- for f in $*
- do
- if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$s" $LOGS/$f
- then
- # aha, this one has it
- findlog_file=$LOGS/$f
- findlog_startline=`egrep -n "$s" $LOGS/$f |
- sed -n '$s/:.*//p'`
- return 0
- fi
- done
- for f in $*
- do
- if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$t" $LOGS/$f
- then
- # aha, this one has it
- findlog_file=$LOGS/$f
- findlog_startline=`egrep -n "$t" $LOGS/$f |
- sed -n '1s/:.*//p'`
- return 0
- fi
- done
- # nope, resort to a search, newest first, of uncompressed logs
- for f in `ls -t $LOGS | egrep -v '^mail' | egrep -v '\.(gz|Z)$'`
- do
- if test -r $LOGS/$f -a ! -d $LOGS/$f && egrep -q "$s" $LOGS/$f
- then
- # found it
- findlog_file=$LOGS/$f
- findlog_startline=`egrep -n "$s" $LOGS/$f |
- sed -n '$s/:.*//p'`
- return 0
- fi
- done
- for f in `ls -t $LOGS | egrep -v '^mail' | egrep -v '\.(gz|Z)$'`
- do
- if test -r $LOGS/$f -a -f $LOGS/$f && egrep -q "$t" $LOGS/$f
- then
- # found it
- findlog_file=$LOGS/$f
- findlog_startline=`egrep -n "$t" $LOGS/$f |
- sed -n '1s/:.*//p'`
- return 0
- fi
- done
-# echo "$0: unable to find $LOGS/$1 or local equivalent" >&2
- findlog_file=/dev/null
- findlog_startline=1 # arbitrary
-}
-
-# try to guess where logs are
-findlog "$fstart" "klips" messages syslog
-if test " $findlog_file" = " /dev/null"
-then
-echo "Unable to find KLIPS messages, typically found in /var/log/messages or equivalent. You may need to run $IPSEC_NAME for the first time; alternatively, your log files have been emptied (ie, logwatch) or we do not understand your logging configuration."
-fi
-klog=$findlog_file
-kline=$findlog_startline
-
-findlog "$pstart" "Pluto" secure auth.log debug
-if test " $findlog_file" = " /dev/null"
-then
-echo "Unable to find Pluto messages, typically found in /var/log/secure or equivalent. You may need to run $IPSEC_NAME for the first time; alternatively, your log files have been emptied (ie, logwatch) or we do not understand your logging configuration."
-fi
-plog=$findlog_file
-pline=$findlog_startline
-
-# /lib/modules examiner
-modulegoo() {
- set +x
- for d in `ls /lib/modules`
- do
- if test -d /lib/modules/$d
- then
- f=/lib/modules/$d/$1
- if test -f $f
- then
- nm -g $f | egrep "$2"
- else
- echo
- fi | sed "s;^;$d: ;"
- fi
- done
- set -x
-}
-
-# advanced shell deviousness to get dividers into output
-_________________________() {
- $2 # something to do nothing and not echo anything
-}
-
-exec 2>&1 # stderr on stdout, so errors go into main output
-
-hostname ; date
-set -x
-_________________________ version
-ipsec --version
-_________________________ proc/version
-cat /proc/version
-_________________________ proc/net/ipsec_eroute
-sort -sg +3 /proc/net/ipsec_eroute || cat /proc/net/ipsec_eroute
-_________________________ netstat-rn
-netstat -nr
-_________________________ proc/net/ipsec_spi
-cat /proc/net/ipsec_spi
-_________________________ proc/net/ipsec_spigrp
-cat /proc/net/ipsec_spigrp
-_________________________ proc/net/ipsec_tncfg
-cat /proc/net/ipsec_tncfg
-_________________________ proc/net/pf_key
-cat /proc/net/pf_key
-_________________________ proc/net/pf_key-star
-( cd /proc/net && egrep '^' pf_key_* )
-_________________________ proc/sys/net/ipsec-star
-( cd /proc/sys/net/ipsec && egrep '^' * )
-_________________________ ipsec/statusall
-ipsec auto --statusall
-_________________________ ifconfig-a
-ifconfig -a
-_________________________ mii-tool
-if [ -x /sbin/mii-tool ]
-then
- /sbin/mii-tool -v
-elif [ -x /usr/sbin/mii-tool ]
-then
- /usr/sbin/mii-tool -v
-else
- mii-tool -v
-fi
-_________________________ ipsec/directory
-ipsec --directory
-_________________________ hostname/fqdn
-hostname --fqdn
-_________________________ hostname/ipaddress
-hostname --ip-address
-_________________________ uptime
-uptime
-_________________________ ps
-# -i ppid picks up the header
-ps alxwf | egrep -i 'ppid|pluto|ipsec|klips'
-_________________________ ipsec/showdefaults
-ipsec showdefaults
-_________________________ ipsec/conf
-ipsec _include $CONFS/ipsec.conf | ipsec _keycensor
-_________________________ ipsec/secrets
-ipsec _include $CONFS/ipsec.secrets | ipsec _secretcensor
-_________________________ ipsec/listall
-ipsec auto --listall
-if [ $POLICIES ]
-then
- for policy in $POLICIES/*; do base=`basename $policy`;
- _________________________ ipsec/policies/$base
- cat $policy
- done
-fi
-_________________________ ipsec/ls-libdir
-ls -l ${IPSEC_LIBDIR-/usr/local/lib/ipsec}
-_________________________ ipsec/ls-execdir
-ls -l ${IPSEC_EXECDIR-/usr/local/libexec/ipsec}
-_________________________ ipsec/updowns
-for f in `ls ${IPSEC_EXECDIR-/usr/local/libexec/ipsec} | egrep updown`
-do
- cat ${IPSEC_EXECDIR-/usr/local/libexec/ipsec}/$f
-done
-_________________________ proc/net/dev
-cat /proc/net/dev
-_________________________ proc/net/route
-cat /proc/net/route
-_________________________ proc/sys/net/ipv4/ip_forward
-cat /proc/sys/net/ipv4/ip_forward
-_________________________ proc/sys/net/ipv4/conf/star-rp_filter
-( cd /proc/sys/net/ipv4/conf && egrep '^' */rp_filter )
-_________________________ uname-a
-uname -a
-_________________________ redhat-release
-if test -r /etc/redhat-release
-then
- cat /etc/redhat-release
-fi
-_________________________ proc/net/ipsec_version
-cat /proc/net/ipsec_version
-_________________________ iptables/list
-iptables -L -v -n
-_________________________ ipchains/list
-ipchains -L -v -n
-_________________________ ipfwadm/forward
-ipfwadm -F -l -n -e
-_________________________ ipfwadm/input
-ipfwadm -I -l -n -e
-_________________________ ipfwadm/output
-ipfwadm -O -l -n -e
-_________________________ iptables/nat
-iptables -t nat -L -v -n
-_________________________ ipchains/masq
-ipchains -M -L -v -n
-_________________________ ipfwadm/masq
-ipfwadm -M -l -n -e
-_________________________ iptables/mangle
-iptables -t mangle -L -v -n
-_________________________ proc/modules
-cat /proc/modules
-_________________________ proc/meminfo
-cat /proc/meminfo
-_________________________ dev/ipsec-ls
-ls -l /dev/ipsec*
-_________________________ proc/net/ipsec-ls
-ls -l /proc/net/ipsec_*
-_________________________ usr/src/linux/.config
-if test -f $KERNSRC/.config
-then
- egrep 'IP|NETLINK' $KERNSRC/.config
-fi
-_________________________ etc/syslog.conf
-cat /etc/syslog.conf
-_________________________ etc/resolv.conf
-cat /etc/resolv.conf
-_________________________ lib/modules-ls
-ls -ltr /lib/modules
-_________________________ proc/ksyms-netif_rx
-egrep netif_rx /proc/ksyms
-_________________________ lib/modules-netif_rx
-modulegoo kernel/net/ipv4/ipip.o netif_rx
-_________________________ kern.debug
-if test -f $LOGS/kern.debug
-then
- tail -100 $LOGS/kern.debug
-fi
-_________________________ klog
-sed -n $kline,'$'p $klog |
- egrep -i 'ipsec|klips|pluto' |
- case "$1" in
- --short) tail -500 ;;
- *) cat ;;
- esac
-_________________________ plog
-sed -n $pline,'$'p $plog |
- egrep -i 'pluto' |
- case "$1" in
- --short) tail -500 ;;
- *) cat ;;
- esac
-_________________________ date
-date
diff --git a/programs/calcgoo/.cvsignore b/programs/calcgoo/.cvsignore
deleted file mode 100644
index b4aa748b7..000000000
--- a/programs/calcgoo/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-calcgoo
diff --git a/programs/calcgoo/Makefile b/programs/calcgoo/Makefile
deleted file mode 100644
index 8e3cae9ea..000000000
--- a/programs/calcgoo/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=calcgoo
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.1 2002/06/10 04:27:25 mcr
-# calcgoo program processes kernel symbol list and generates a
-# composite value by xor'ing the programmed symbol.
-#
-# Revision 1.1 2002/06/10 00:19:44 mcr
-# rename "ipsec check" to "ipsec verify"
-#
-# Revision 1.1 2002/06/08 17:01:25 mcr
-# added new program "ipsec check" to do rudamentary testing
-# on a newly installed system to see if it is OE ready.
-#
-#
-#
-
diff --git a/programs/calcgoo/calcgoo.8 b/programs/calcgoo/calcgoo.8
deleted file mode 100644
index ceb576e41..000000000
--- a/programs/calcgoo/calcgoo.8
+++ /dev/null
@@ -1,31 +0,0 @@
-.TH IPSEC_CALCGOO 8 "8 June 2002"
-.\" RCSID $Id: calcgoo.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.SH NAME
-ipsec calcgoo \- calculate hex value for matching modules and kernels
-.SH SYNOPSIS
-.B ipsec
-.B calcgoo
-.SH DESCRIPTION
-.I calcgoo
-accepts the output of
-.B nm -ao
-or
-.B /proc/ksyms
-and extracts a release dependant list of symbols from it. The symbols
-are processed to extract the values assigned during the MODVERSIONS
-process. This process makes sure that Linux modules are only loaded
-on matching kernels.
-.P
-This routine is used to find an appropriate module to match the currently
-running kernel by _startklips.
-.SH FILES
-.nf
-/proc/ksyms
-.fi
-.SH "SEE ALSO"
-ipsec__startklips(8), genksyms(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Michael Richardson.
-.SH BUGS
diff --git a/programs/calcgoo/calcgoo.in b/programs/calcgoo/calcgoo.in
deleted file mode 100644
index 0d383d173..000000000
--- a/programs/calcgoo/calcgoo.in
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/perl
-
-$MODULE_GOO_LIST="@MODULE_GOO_LIST@";
-
-@goo = split(/\s+/,$MODULE_GOO_LIST);
-
-$sep="(";
-$goore=" ";
-
-#print "GOO: ",join('|',@goo),"\n";
-
-foreach $sym (@goo) {
- $goore=${goore}.${sep}.${sym};
- $sep="|";
-}
-$goore=${goore}.")_R(smp_){0,1}([0-9A-F]{8})";
-
-#print "GOORE: $goore\n";
-
-while(<>) {
- chomp;
- if(/$goore/io) {
- $sym=$1;
- $goosym=$3;
- $bingoo=hex($goosym);
- if($2 eq "smp_") {
- $bingoo++;
- }
- #print STDERR "Processing $goosym (from $_)\n";
- $bingoo{$sym}=$bingoo;
- }
-}
-$wholegoo=0;
-foreach $sym (keys %bingoo) {
- $wholegoo=$wholegoo ^ $bingoo{$sym};
-}
-print sprintf("%08x", $wholegoo)."\n";
-
-# Local variables::
-# mode: perl
-# End variables::
-
-
diff --git a/programs/eroute/.cvsignore b/programs/eroute/.cvsignore
deleted file mode 100644
index 133c4b456..000000000
--- a/programs/eroute/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-eroute
diff --git a/programs/eroute/Makefile b/programs/eroute/Makefile
deleted file mode 100644
index 6d8f68033..000000000
--- a/programs/eroute/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM:=eroute
-EXTRA5PROC=eroute.5
-
-LIBS:=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/eroute/eroute.5 b/programs/eroute/eroute.5
deleted file mode 100644
index 52b3f4d25..000000000
--- a/programs/eroute/eroute.5
+++ /dev/null
@@ -1,272 +0,0 @@
-.TH IPSEC_EROUTE 5 "20 Sep 2001"
-.\"
-.\" RCSID $Id: eroute.5,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec_eroute \- list of existing eroutes
-.SH SYNOPSIS
-.B ipsec
-.B eroute
-.PP
-.B cat
-.B /proc/net/ipsec_eroute
-.SH DESCRIPTION
-.I /proc/net/ipsec_eroute
-lists the IPSEC extended routing tables,
-which control what (if any) processing is applied
-to non-encrypted packets arriving for IPSEC processing and forwarding.
-At this point it is a read-only file.
-.PP
-A table entry consists of:
-.IP + 3
-packet count,
-.IP +
-source address with mask and source port (0 if all ports or not applicable)
-.IP +
-a '->' separator for visual and automated parsing between src and dst
-.IP +
-destination address with mask and destination port (0 if all ports or
-not applicable)
-.IP +
-a '=>' separator for visual and automated parsing between selection
-criteria and SAID to use
-.IP +
-SAID (Security Association IDentifier), comprised of:
-.IP + 6
-protocol
-(\fIproto\fR),
-.IP +
-address family
-(\fIaf\fR),
-where '.' stands for IPv4 and ':' for IPv6
-.IP +
-Security Parameters Index
-(\fISPI\fR),
-.IP +
-effective destination
-(\fIedst\fR),
-where the packet should be forwarded after processing
-(normally the other security gateway)
-together indicate which Security Association should be used to process
-the packet,
-.IP + 3
-a ':' separating the SAID from the transport protocol (0 if all protocols)
-.IP +
-source identity text string with no whitespace, in parens,
-.IP +
-destination identity text string with no whitespace, in parens
-.PP
-Addresses are written as IPv4 dotted quads or IPv6 coloned hex,
-protocol is one of "ah", "esp", "comp" or "tun"
-and
-SPIs are prefixed hexadecimal numbers where the prefix '.' is for IPv4 and the prefix ':' is for IPv6
-.
-.PP
-SAIDs are written as "protoafSPI@edst". There are also 5
-"magic" SAIDs which have special meaning:
-.IP + 3
-.B %drop
-means that matches are to be dropped
-.IP +
-.B %reject
-means that matches are to be dropped and an ICMP returned, if
-possible to inform
-.IP +
-.B %trap
-means that matches are to trigger an ACQUIRE message to the Key
-Management daemon(s) and a hold eroute will be put in place to
-prevent subsequent packets also triggering ACQUIRE messages.
-.IP +
-.B %hold
-means that matches are to stored until the eroute is replaced or
-until that eroute gets reaped
-.IP +
-.B %pass
-means that matches are to allowed to pass without IPSEC processing
-.br
-.ne 5
-.SH EXAMPLES
-.LP
-.B "1867 172.31.252.0/24:0 -> 0.0.0.0/0:0 => tun0x130@192.168.43.1:0 "
-.br
-.B " () ()"
-.LP
-means that 1,867 packets have been sent to an
-.BR eroute
-that has been set up to protect traffic between the subnet
-.BR 172.31.252.0
-with a subnet mask of
-.BR 24
-bits and the default address/mask represented by an address of
-.BR 0.0.0.0
-with a subnet mask of
-.BR 0
-bits using the local machine as a security gateway on this end of the
-tunnel and the machine
-.BR 192.168.43.1
-on the other end of the tunnel with a Security Association IDentifier of
-.BR tun0x130@192.168.43.1
-which means that it is a tunnel mode connection (4, IPPROTO_IPIP) with a
-Security Parameters Index of
-.BR 130
-in hexadecimal with no identies defined for either end.
-.LP
-.B "746 192.168.2.110/32:0 -> 192.168.2.120/32:25 => esp0x130@192.168.2.120:6 "
-.br
-.B " () ()"
-.LP
-means that 746 packets have been sent to an
-.BR eroute
-that has been set up to protect traffic sent from any port on the host
-.BR 192.168.2.110
-to the SMTP (TCP, port 25) port on the host
-.BR 192.168.2.120
-with a Security Association IDentifier of
-.BR tun0x130@192.168.2.120
-which means that it is a transport mode connection with a
-Security Parameters Index of
-.BR 130
-in hexadecimal with no identies defined for either end.
-.LP
-.B 125 3049:1::/64 -> 0:0/0 => tun:130@3058:4::5 () ()
-.LP
-means that 125 packets have been sent to an
-.BR eroute
-that has been set up to protect traffic between the subnet
-.BR 3049:1::
-with a subnet mask of
-.BR 64
-bits and the default address/mask represented by an address of
-.BR 0:0
-with a subnet mask of
-.BR 0
-bits using the local machine as a security gateway on this end of the
-tunnel and the machine
-.BR 3058:4::5
-on the other end of the tunnel with a Security Association IDentifier of
-.BR tun:130@3058:4::5
-which means that it is a tunnel mode connection with a
-Security Parameters Index of
-.BR 130
-in hexadecimal with no identies defined for either end.
-.LP
-.B 42 192.168.6.0/24:0 -> 192.168.7.0/24:0 => %passthrough
-.LP
-means that 42 packets have been sent to an
-.BR eroute
-that has been set up to pass the traffic from the subnet
-.BR 192.168.6.0
-with a subnet mask of
-.BR 24
-bits and to subnet
-.BR 192.168.7.0
-with a subnet mask of
-.BR 24
-bits without any IPSEC processing with no identies defined for either end.
-.LP
-.B 2112 192.168.8.55/32:0 -> 192.168.9.47/24:0 => %hold (east) ()
-.LP
-means that 2112 packets have been sent to an
-.BR eroute
-that has been set up to hold the traffic from the host
-.BR 192.168.8.55
-and to host
-.BR 192.168.9.47
-until a key exchange from a Key Management daemon
-succeeds and puts in an SA or fails and puts in a pass
-or drop eroute depending on the default configuration with the local client
-defined as "east" and no identy defined for the remote end.
-.LP
-.B "2001 192.168.2.110/32:0 -> 192.168.2.120/32:0 => "
-.br
-.B " esp0xe6de@192.168.2.120:0 () ()"
-.LP
-means that 2001 packets have been sent to an
-.BR eroute
-that has been set up to protect traffic between the host
-.BR 192.168.2.110
-and the host
-.BR 192.168.2.120
-using
-.BR 192.168.2.110
-as a security gateway on this end of the
-connection and the machine
-.BR 192.168.2.120
-on the other end of the connection with a Security Association IDentifier of
-.BR esp0xe6de@192.168.2.120
-which means that it is a transport mode connection with a Security
-Parameters Index of
-.BR e6de
-in hexadecimal using Encapsuation Security Payload protocol (50,
-IPPROTO_ESP) with no identies defined for either end.
-.LP
-.B "1984 3049:1::110/128 -> 3049:1::120/128 => "
-.br
-.B " ah:f5ed@3049:1::120 () ()"
-.LP
-means that 1984 packets have been sent to an
-.BR eroute
-that has been set up to authenticate traffic between the host
-.BR 3049:1::110
-and the host
-.BR 3049:1::120
-using
-.BR 3049:1::110
-as a security gateway on this end of the
-connection and the machine
-.BR 3049:1::120
-on the other end of the connection with a Security Association IDentifier of
-.BR ah:f5ed@3049:1::120
-which means that it is a transport mode connection with a Security
-Parameters Index of
-.BR f5ed
-in hexadecimal using Authentication Header protocol (51,
-IPPROTO_AH) with no identies defined for either end.
-.SH FILES
-/proc/net/ipsec_eroute, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(5), ipsec_spi(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_eroute(8), ipsec_version(5),
-ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: eroute.5,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.9 2002/04/24 07:35:38 mcr
-.\" Moved from ./klips/utils/eroute.5,v
-.\"
-.\" Revision 1.8 2001/09/20 15:33:13 rgb
-.\" PF_KEYv2 ident extension output documentation.
-.\"
-.\" Revision 1.7 2001/05/29 05:15:31 rgb
-.\" Added packet count field at beginning of line.
-.\"
-.\" Revision 1.6 2001/02/26 19:58:32 rgb
-.\" Put SAID elements in order they appear in SAID.
-.\" Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
-.\" of the new SPD and to support opportunistic.
-.\"
-.\" Revision 1.5 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.4 2000/09/13 15:54:31 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/28 12:44:11 henry
-.\" format touchup
-.\"
-.\" Revision 1.1 2000/06/28 05:43:00 rgb
-.\" Added manpages for all 5 klips utils.
-.\"
-.\"
-.\"
diff --git a/programs/eroute/eroute.8 b/programs/eroute/eroute.8
deleted file mode 100644
index d9449632b..000000000
--- a/programs/eroute/eroute.8
+++ /dev/null
@@ -1,354 +0,0 @@
-.TH IPSEC_EROUTE 8 "21 Jun 2000"
-.\"
-.\" RCSID $Id: eroute.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.\"
-.SH NAME
-ipsec eroute \- manipulate IPSEC extended routing tables
-.SH SYNOPSIS
-.B ipsec
-.B eroute
-.PP
-.B ipsec
-.B eroute
-.B \-\-add
-.B \-\-eraf (inet | inet6)
-.B \-\-src
-src/srcmaskbits|srcmask
-.B \-\-dst
-dst/dstmaskbits|dstmask
-[
-.B \-\-transport\-proto
-transport-protocol
-]
-[
-.B \-\-src\-port
-source-port
-]
-[
-.B \-\-dst\-port
-dest-port
-]
-<SAID>
-.PP
-.B ipsec
-.B eroute
-.B \-\-replace
-.B \-\-eraf (inet | inet6)
-.B \-\-src
-src/srcmaskbits|srcmask
-.B \-\-dst
-dst/dstmaskbits|dstmask
-[
-.B \-\-transport\-proto
-transport-protocol
-]
-[
-.B \-\-src\-port
-source-port
-]
-[
-.B \-\-dst\-port
-dest-port
-]
-<SAID>
-.PP
-.B ipsec
-.B eroute
-.B \-\-del
-.B \-\-eraf (inet | inet6)
-.B \-\-src
-src/srcmaskbits|srcmask
-.B \-\-dst
-dst/dstmaskbits|dstmask
-[
-.B \-\-transport\-proto
-transport-protocol
-]
-[
-.B \-\-src\-port
-source-port
-]
-[
-.B \-\-dst\-port
-dest-port
-]
-.PP
-.B ipsec
-.B eroute
-.B \-\-clear
-.PP
-.B ipsec
-.B eroute
-.B \-\-help
-.PP
-.B ipsec
-.B eroute
-.B \-\-version
-.PP
-Where <SAID> is
-.B \-\-af
-(inet | inet6)
-.B \-\-edst
-edst
-.B \-\-spi
-spi
-.B \-\-proto
-proto
-OR
-.B \-\-said
-said
-OR
-.B \-\-said
-.B (%passthrough | %passthrough4 | %passthrough6 | %drop | %reject | %trap | %hold | %pass )
-.SH DESCRIPTION
-.I Eroute
-manages the IPSEC extended routing tables,
-which control what (if any) processing is applied
-to non-encrypted packets arriving for IPSEC processing and forwarding.
-The form with no additional arguments lists the contents of
-/proc/net/ipsec_eroute.
-The
-.B \-\-add
-form adds a table entry, the
-.B \-\-replace
-form replaces a table entry, while the
-.B \-\-del
-form deletes one. The
-.B \-\-clear
-form deletes the entire table.
-.PP
-A table entry consists of:
-.IP + 3
-source and destination addresses,
-with masks, source and destination ports and protocol
-for selection of packets. The source and destination ports are only
-legal if the transport protocol is
-.BR TCP
-or
-.BR UDP.
-A port can be specified as either decimal, hexadecimal (leading 0x),
-octal (leading 0) or a name listed in the first column of /etc/services.
-A transport protocol can be specified as either decimal, hexadecimal
-(leading 0x), octal (leading 0) or a name listed in the first column
-of /etc/protocols. If a transport protocol or port is not specified
-then it defaults to 0 which means all protocols or all ports
-respectively.
-.IP +
-Security Association IDentifier, comprised of:
-.IP + 6
-protocol
-(\fIproto\fR), indicating (together with the
-effective destination and the security parameters index)
-which Security Association should be used to process the packet
-.IP +
-address family
-(\fIaf\fR),
-.IP +
-Security Parameters Index
-(\fIspi\fR), indicating (together with the
-effective destination and protocol)
-which Security Association should be used to process the packet
-(must be larger than or equal to 0x100)
-.IP +
-effective destination
-(\fIedst\fR),
-where the packet should be forwarded after processing
-(normally the other security gateway)
-.IP + 3
-OR
-.IP + 6
-SAID
-(\fIsaid\fR), indicating
-which Security Association should be used to process the packet
-.PP
-Addresses are written as IPv4 dotted quads or IPv6 coloned hex,
-protocol is one of "ah", "esp", "comp" or "tun" and SPIs are
-prefixed hexadecimal numbers where '.' represents IPv4 and ':'
-stands for IPv6.
-.PP
-SAIDs are written as "protoafSPI@address". There are also 5
-"magic" SAIDs which have special meaning:
-.IP + 3
-.B %drop
-means that matches are to be dropped
-.IP +
-.B %reject
-means that matches are to be dropped and an ICMP returned, if
-possible to inform
-.IP +
-.B %trap
-means that matches are to trigger an ACQUIRE message to the Key
-Management daemon(s) and a hold eroute will be put in place to
-prevent subsequent packets also triggering ACQUIRE messages.
-.IP +
-.B %hold
-means that matches are to stored until the eroute is replaced or
-until that eroute gets reaped
-.IP +
-.B %pass
-means that matches are to allowed to pass without IPSEC processing
-.PP
-The format of /proc/net/ipsec_eroute is listed in ipsec_eroute(5).
-.br
-.ne 5
-.SH EXAMPLES
-.LP
-.B "ipsec eroute \-\-add \-\-eraf inet \-\-src 192.168.0.1/32 \e"
-.br
-.B " \-\-dst 192.168.2.0/24 \-\-af inet \-\-edst 192.168.0.2 \e"
-.br
-.B " \-\-spi 0x135 \-\-proto tun"
-.LP
-sets up an
-.BR eroute
-on a Security Gateway to protect traffic between the host
-.BR 192.168.0.1
-and the subnet
-.BR 192.168.2.0
-with
-.BR 24
-bits of subnet mask via Security Gateway
-.BR 192.168.0.2
-using the Security Association with address
-.BR 192.168.0.2 ,
-Security Parameters Index
-.BR 0x135
-and protocol
-.BR tun
-(50, IPPROTO_ESP).
-.LP
-.B "ipsec eroute \-\-add \-\-eraf inet6 \-\-src 3049:1::1/128 \e"
-.br
-.B " \-\-dst 3049:2::/64 \-\-af inet6 \-\-edst 3049:1::2 \e"
-.br
-.B " \-\-spi 0x145 \-\-proto tun"
-.LP
-sets up an
-.BR eroute
-on a Security Gateway to protect traffic between the host
-.BR 3049:1::1
-and the subnet
-.BR 3049:2::
-with
-.BR 64
-bits of subnet mask via Security Gateway
-.BR 3049:1::2
-using the Security Association with address
-.BR 3049:1::2 ,
-Security Parameters Index
-.BR 0x145
-and protocol
-.BR tun
-(50, IPPROTO_ESP).
-.LP
-.B "ipsec eroute \-\-replace \-\-eraf inet \-\-src company.com/24 \e"
-.br
-.B " \-\-dst ftp.ngo.org/32 \-\-said tun.135@gw.ngo.org"
-.LP
-replaces an
-.BR eroute
-on a Security Gateway to protect traffic between the subnet
-.BR company.com
-with
-.BR 24
-bits of subnet mask and the host
-.BR ftp.ngo.org
-via Security Gateway
-.BR gw.ngo.org
-using the Security Association with Security Association ID
-.BR tun0x135@gw.ngo.org
-.LP
-.B "ipsec eroute \-\-del \-\-eraf inet \-\-src company.com/24 \e"
-.br
-.B " \-\-dst www.ietf.org/32 \-\-said %passthrough4"
-.LP
-deletes an
-.BR eroute
-on a Security Gateway that allowed traffic between the subnet
-.BR company.com
-with
-.BR 24
-bits of subnet mask and the host
-.BR www.ietf.org
-to pass in the clear, unprocessed.
-.LP
-.B "ipsec eroute \-\-add \-\-eraf inet \-\-src company.com/24 \e"
-.br
-.B " \-\-dst mail.ngo.org/32 \-\-transport-proto 6 \e"
-.br
-.B " \-\-dst\-port 110 \-\-said tun.135@mail.ngo.org"
-.LP
-sets up an
-.BR eroute
-on on a Security Gateway to protect only TCP traffic on port 110
-(pop3) between the subnet
-.BR company.com
-with
-.BR 24
-bits of subnet mask and the host
-.BR ftp.ngo.org
-via Security Gateway
-.BR mail.ngo.org
-using the Security Association with Security Association ID
-.BR tun0x135@mail.ngo.org.
-Note that any other traffic bound for
-.BR mail.ngo.org
-that is routed via the ipsec device will be dropped. If you wish to
-allow other traffic to pass through then you must add a %pass rule.
-For example the following rule when combined with the above will
-ensure that POP3 messages read from
-.BR mail.ngo.org
-will be encrypted but all other traffic to/from
-.BR mail.ngo.org
-will be in clear text.
-.LP
-.B "ipsec eroute \-\-add \-\-eraf inet \-\-src company.com/24 \e"
-.br
-.B " \-\-dst mail.ngo.org/32 \-\-said %pass"
-.br
-.LP
-.SH FILES
-/proc/net/ipsec_eroute, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_spi(8),
-ipsec_spigrp(8), ipsec_klipsdebug(8), ipsec_eroute(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: eroute.8,v $
-.\" Revision 1.1 2004/03/15 20:35:27 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.25 2002/04/24 07:35:38 mcr
-.\" Moved from ./klips/utils/eroute.8,v
-.\"
-.\" Revision 1.24 2001/02/26 19:58:49 rgb
-.\" Added a comment on the restriction of spi > 0x100.
-.\" Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
-.\" of the new SPD and to support opportunistic.
-.\"
-.\" Revision 1.23 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.22 2000/09/13 15:54:31 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.21 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.20 2000/06/21 16:54:57 rgb
-.\" Added 'no additional args' text for listing contents of
-.\" /proc/net/ipsec_* files.
-.\"
-.\" Revision 1.19 1999/07/19 18:47:24 henry
-.\" fix slightly-misformed comments
-.\"
-.\" Revision 1.18 1999/04/06 04:54:37 rgb
-.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-.\" patch shell fixes.
-.\"
-.\"
diff --git a/programs/eroute/eroute.c b/programs/eroute/eroute.c
deleted file mode 100644
index d1b2bff0a..000000000
--- a/programs/eroute/eroute.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * manipulate eroutes
- * Copyright (C) 1996 John Ioannidis.
- * Copyright (C) 1997, 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char eroute_c_version[] = "RCSID $Id: eroute.c,v 1.3 2005/02/24 20:03:46 as Exp $";
-
-
-#include <sys/types.h>
-#include <linux/types.h> /* new */
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h> /* system(), strtoul() */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <netdb.h>
-
-
-#include <unistd.h>
-#include <freeswan.h>
-#if 0
-#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */
-#endif
-/* permanently turn it on since netlink support has been disabled */
-
-#include <signal.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "freeswan/radij.h"
-#include "freeswan/ipsec_encap.h"
-
-#include <stdio.h>
-#include <getopt.h>
-
-char *program_name;
-char me[] = "ipsec eroute";
-extern char *optarg;
-extern int optind, opterr, optopt;
-char *eroute_af_opt, *said_af_opt, *edst_opt, *spi_opt, *proto_opt, *said_opt, *dst_opt, *src_opt;
-char *transport_proto_opt, *src_port_opt, *dst_port_opt;
-int action_type = 0;
-
-int pfkey_sock;
-fd_set pfkey_socks;
-uint32_t pfkey_seq = 0;
-
-#define EMT_IFADDR 1 /* set enc if addr */
-#define EMT_SETSPI 2 /* Set SPI properties */
-#define EMT_DELSPI 3 /* Delete an SPI */
-#define EMT_GRPSPIS 4 /* Group SPIs (output order) */
-#define EMT_SETEROUTE 5 /* set an extended route */
-#define EMT_DELEROUTE 6 /* del an extended route */
-#define EMT_TESTROUTE 7 /* try to find route, print to console */
-#define EMT_SETDEBUG 8 /* set debug level if active */
-#define EMT_UNGRPSPIS 9 /* UnGroup SPIs (output order) */
-#define EMT_CLREROUTE 10 /* clear the extended route table */
-#define EMT_CLRSPIS 11 /* clear the spi table */
-#define EMT_REPLACEROUTE 12 /* set an extended route */
-#define EMT_GETDEBUG 13 /* get debug level if active */
-#define EMT_INEROUTE 14 /* set incoming policy for IPIP on a chain */
-
-static void
-add_port(int af, ip_address * addr, short port)
-{
- switch (af)
- {
- case AF_INET:
- addr->u.v4.sin_port = port;
- break;
- case AF_INET6:
- addr->u.v6.sin6_port = port;
- break;
- }
-}
-
-static void
-usage(char* arg)
-{
- fprintf(stdout, "usage: %s --{add,addin,replace} --eraf <inet | inet6> --src <src>/<srcmaskbits>|<srcmask> --dst <dst>/<dstmaskbits>|<dstmask> [ --transport-proto <protocol> ] [ --src-port <source-port> ] [ --dst-port <dest-port> ] <SA>\n", arg);
- fprintf(stdout, " where <SA> is '--af <inet | inet6> --edst <edst> --spi <spi> --proto <proto>'\n");
- fprintf(stdout, " OR '--said <said>'\n");
- fprintf(stdout, " OR '--said <%%passthrough | %%passthrough4 | %%passthrough6 | %%drop | %%reject | %%trap | %%hold | %%pass>'.\n");
- fprintf(stdout, " %s --del --eraf <inet | inet6>--src <src>/<srcmaskbits>|<srcmask> --dst <dst>/<dstmaskbits>|<dstmask> [ --transport-proto <protocol> ] [ --src-port <source-port> ] [ --dst-port <dest-port> ]\n", arg);
- fprintf(stdout, " %s --clear\n", arg);
- fprintf(stdout, " %s --help\n", arg);
- fprintf(stdout, " %s --version\n", arg);
- fprintf(stdout, " %s\n", arg);
- fprintf(stdout, " [ --debug ] is optional to any %s command.\n", arg);
- fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", arg);
- exit(1);
-}
-
-static struct option const longopts[] =
-{
- {"dst", 1, 0, 'D'},
- {"src", 1, 0, 'S'},
- {"eraf", 1, 0, 'f'},
- {"add", 0, 0, 'a'},
- {"addin", 0, 0, 'A'},
- {"replace", 0, 0, 'r'},
- {"clear", 0, 0, 'c'},
- {"del", 0, 0, 'd'},
- {"af", 1, 0, 'i'},
- {"edst", 1, 0, 'e'},
- {"proto", 1, 0, 'p'},
- {"transport-proto", 1, 0, 'P'},
- {"src-port", 1, 0, 'Q'},
- {"dst-port", 1, 0, 'R'},
- {"help", 0, 0, 'h'},
- {"spi", 1, 0, 's'},
- {"said", 1, 0, 'I'},
- {"version", 0, 0, 'v'},
- {"label", 1, 0, 'l'},
- {"optionsfrom", 1, 0, '+'},
- {"debug", 0, 0, 'g'},
- {0, 0, 0, 0}
-};
-
-int
-main(int argc, char **argv)
-{
- /* int fd; */
- char *endptr;
- /* int ret; */
- int c, previous = -1;
- const char* error_s;
- int debug = 0;
-
- int error = 0;
-
- char ipaddr_txt[ADDRTOT_BUF];
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
- ip_address pfkey_address_s_ska;
- /*struct sockaddr_in pfkey_address_d_ska;*/
- ip_address pfkey_address_sflow_ska;
- ip_address pfkey_address_dflow_ska;
- ip_address pfkey_address_smask_ska;
- ip_address pfkey_address_dmask_ska;
-
- int transport_proto = 0;
- int src_port = 0;
- int dst_port = 0;
- ip_said said;
- ip_subnet s_subnet, d_subnet;
- int eroute_af = 0;
- int said_af = 0;
-
- int argcount = argc;
-
- const char permitted_options[] =
- "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n";
-
- program_name = argv[0];
- eroute_af_opt = said_af_opt = edst_opt = spi_opt = proto_opt = said_opt = dst_opt = src_opt = NULL;
-
- while((c = getopt_long(argc, argv, ""/*"acdD:e:i:hprs:S:f:vl:+:g"*/, longopts, 0)) != EOF)
- {
- switch(c)
- {
- case 'g':
- debug = 1;
- pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
- argcount--;
- break;
- case 'a':
- if (action_type)
- {
- fprintf(stderr, permitted_options, program_name);
- exit(1);
- }
- action_type = EMT_SETEROUTE;
- break;
- case 'A':
- if (action_type)
- {
- fprintf(stderr, permitted_options, program_name);
- exit(1);
- }
- action_type = EMT_INEROUTE;
- break;
- case 'r':
- if (action_type)
- {
- fprintf(stderr, permitted_options, program_name);
- exit(1);
- }
- action_type = EMT_REPLACEROUTE;
- break;
- case 'c':
- if (action_type)
- {
- fprintf(stderr, permitted_options, program_name);
- exit(1);
- }
- action_type = EMT_CLREROUTE;
- break;
- case 'd':
- if (action_type)
- {
- fprintf(stderr, permitted_options, program_name);
- exit(1);
- }
- action_type = EMT_DELEROUTE;
- break;
- case 'e':
- if (said_opt)
- {
- fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined in SA:%s\n"
- , program_name, optarg, said_opt);
- exit (1);
- }
- if (edst_opt)
- {
- fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, edst_opt);
- exit (1);
- }
- error_s = ttoaddr(optarg, 0, said_af, &said.dst);
- if (error_s != NULL)
- {
- fprintf(stderr, "%s: Error, %s converting --edst argument:%s\n"
- , program_name, error_s, optarg);
- exit (1);
- }
- edst_opt = optarg;
- break;
- case 'h':
- case '?':
- usage(program_name);
- exit(1);
- case 's':
- if (said_opt)
- {
- fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined in SA:%s\n"
- , program_name, optarg, said_opt);
- exit (1);
- }
- if (spi_opt)
- {
- fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, spi_opt);
- exit (1);
- }
- said.spi = htonl(strtoul(optarg, &endptr, 0));
- if (!(endptr == optarg + strlen(optarg)))
- {
- fprintf(stderr, "%s: Invalid character in SPI parameter: %s\n"
- , program_name, optarg);
- exit (1);
- }
- if (ntohl(said.spi) < 0x100)
- {
- fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than 0x100.\n"
- , program_name, optarg, ntohl(said.spi));
- exit(1);
- }
- spi_opt = optarg;
- break;
- case 'p':
- if (said_opt)
- {
- fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined in SA:%s\n"
- , program_name, optarg, said_opt);
- exit (1);
- }
- if (proto_opt)
- {
- fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, proto_opt);
- exit (1);
- }
-#if 0
- if (said.proto)
- {
- fprintf(stderr, "%s: Warning, PROTO parameter redefined:%s\n"
- , program_name, optarg);
- exit (1);
- }
-#endif
- if (!strcmp(optarg, "ah"))
- said.proto = SA_AH;
- if (!strcmp(optarg, "esp"))
- said.proto = SA_ESP;
- if (!strcmp(optarg, "tun"))
- said.proto = SA_IPIP;
- if (!strcmp(optarg, "comp"))
- said.proto = SA_COMP;
- if (said.proto == 0)
- {
- fprintf(stderr, "%s: Invalid PROTO parameter: %s\n"
- , program_name, optarg);
- exit (1);
- }
- proto_opt = optarg;
- break;
- case 'I':
- if (said_opt)
- {
- fprintf(stderr, "%s: Error, SAID parameter redefined:%s, already defined in SA:%s\n"
- , program_name, optarg, said_opt);
- exit (1);
- }
- if (proto_opt)
- {
- fprintf(stderr, "%s: Error, PROTO parameter redefined in SA:%s, already defined as:%s\n"
- , program_name, optarg, proto_opt);
- exit (1);
- }
- if (edst_opt)
- {
- fprintf(stderr, "%s: Error, EDST parameter redefined in SA:%s, already defined as:%s\n"
- , program_name, optarg, edst_opt);
- exit (1);
- }
- if (spi_opt)
- {
- fprintf(stderr, "%s: Error, SPI parameter redefined in SA:%s, already defined as:%s\n"
- , program_name, optarg, spi_opt);
- exit (1);
- }
- if (said_af_opt)
- {
- fprintf(stderr, "%s: Error, address family parameter redefined in SA:%s, already defined as:%s\n"
- , program_name, optarg, said_af_opt);
- exit (1);
- }
- error_s = ttosa(optarg, 0, &said);
- if (error_s != NULL)
- {
- fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n"
- , program_name, error_s, optarg);
- exit (1);
- }
- else if (ntohl(said.spi) < 0x100)
- {
- fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than or equal to 0x100.\n"
- , program_name, optarg, said.spi);
- exit(1);
- }
- said_af = addrtypeof(&said.dst);
- said_opt = optarg;
- break;
- case 'v':
- fprintf(stdout, "%s %s\n", me, ipsec_version_code());
- fprintf(stdout, "See `ipsec --copyright' for copyright information.\n");
- exit(1);
- case 'D':
- if (dst_opt)
- {
- fprintf(stderr, "%s: Error, --dst parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, dst_opt);
- exit (1);
- }
- error_s = ttosubnet(optarg, 0, eroute_af, &d_subnet);
- if (error_s != NULL)
- {
- fprintf(stderr, "%s: Error, %s converting --dst argument: %s\n"
- , program_name, error_s, optarg);
- exit (1);
- }
- dst_opt = optarg;
- break;
- case 'S':
- if (src_opt)
- {
- fprintf(stderr, "%s: Error, --src parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, src_opt);
- exit (1);
- }
- error_s = ttosubnet(optarg, 0, eroute_af, &s_subnet);
- if (error_s != NULL)
- {
- fprintf(stderr, "%s: Error, %s converting --src argument: %s\n"
- , program_name, error_s, optarg);
- exit (1);
- }
- src_opt = optarg;
- break;
- case 'P':
- if (transport_proto_opt)
- {
- fprintf(stderr, "%s: Error, --transport-proto parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, transport_proto_opt);
- exit(1);
- }
- transport_proto_opt = optarg;
- break;
- case 'Q':
- if (src_port_opt)
- {
- fprintf(stderr, "%s: Error, --src-port parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, src_port_opt);
- exit(1);
- }
- src_port_opt = optarg;
- break;
- case 'R':
- if (dst_port_opt)
- {
- fprintf(stderr, "%s: Error, --dst-port parameter redefined:%s, already defined as:%s\n"
- , program_name, optarg, dst_port_opt);
- exit(1);
- }
- dst_port_opt = optarg;
- break;
- case 'l':
- program_name = malloc(strlen(argv[0])
- + 10 /* update this when changing the sprintf() */
- + strlen(optarg));
- sprintf(program_name, "%s --label %s", argv[0], optarg);
- argcount -= 2;
- break;
- case 'i': /* specifies the address family of the SAID, stored in said_af */
- if (said_af_opt)
- {
- fprintf(stderr, "%s: Error, address family of SAID redefined:%s, already defined as:%s\n"
- , program_name, optarg, said_af_opt);
- exit (1);
- }
- if (!strcmp(optarg, "inet"))
- said_af = AF_INET;
- if (!strcmp(optarg, "inet6"))
- said_af = AF_INET6;
- if (said_af == 0)
- {
- fprintf(stderr, "%s: Invalid address family parameter for SAID: %s\n"
- , program_name, optarg);
- exit (1);
- }
- said_af_opt = optarg;
- break;
- case 'f': /* specifies the address family of the eroute, stored in eroute_af */
- if (eroute_af_opt)
- {
- fprintf(stderr, "%s: Error, address family of eroute redefined:%s, already defined as:%s\n"
- , program_name, optarg, eroute_af_opt);
- exit (1);
- }
- if (!strcmp(optarg, "inet"))
- eroute_af = AF_INET;
- if (!strcmp(optarg, "inet6"))
- eroute_af = AF_INET6;
- if (eroute_af == 0)
- {
- fprintf(stderr, "%s: Invalid address family parameter for eroute: %s\n"
- , program_name, optarg);
- exit (1);
- }
- eroute_af_opt = optarg;
- break;
- case '+': /* optionsfrom */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* no return on error */
- break;
- default:
- break;
- }
- previous = c;
- }
-
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: argc=%d\n", program_name, argc);
- }
-
- if (argcount == 1)
- {
- system("cat /proc/net/ipsec_eroute");
- exit(0);
- }
-
- /* Sanity checks */
-
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: action_type=%d\n", program_name, action_type);
- }
-
- if (transport_proto_opt != 0)
- {
- struct protoent * proto = getprotobyname(transport_proto_opt);
-
- if (proto != 0)
- {
- transport_proto = proto->p_proto;
- }
- else
- {
- transport_proto = strtoul(transport_proto_opt, &endptr, 0);
-
- if ((*endptr != '\0')
- || (transport_proto == 0 && endptr == transport_proto_opt))
- {
- fprintf(stderr, "%s: Invalid character in --transport-proto parameter: %s\n"
- , program_name, transport_proto_opt);
- exit (1);
- }
- if (transport_proto > 255)
- {
- fprintf(stderr, "%s: --transport-proto parameter: %s must be in the range 0 to 255 inclusive\n"
- , program_name, transport_proto_opt);
- exit (1);
- }
- }
- }
-
- if (src_port_opt != 0 || dst_port_opt != 0)
- {
- switch (transport_proto)
- {
- case IPPROTO_UDP:
- case IPPROTO_TCP:
- break;
- default:
- fprintf(stderr, "%s: --transport-proto with either UDP or TCP must be specified if --src-port or --dst-port is used\n"
- , program_name);
- exit(1);
- }
- }
-
- if (src_port_opt)
- {
- struct servent * ent = getservbyname(src_port_opt, 0);
-
- if (ent != 0)
- {
- src_port = ent->s_port;
- }
- else
- {
- src_port = strtoul(src_port_opt, &endptr, 0);
-
- if ((*endptr != '\0')
- || (src_port == 0 && endptr == src_port_opt))
- {
- fprintf(stderr, "%s: Invalid character in --src-port parameter: %s\n"
- , program_name, src_port_opt);
- exit (1);
- }
- if (src_port > 65535)
- {
- fprintf(stderr, "%s: --src-port parameter: %s must be in the range 0 to 65535 inclusive\n"
- , program_name, src_port_opt);
- }
- src_port = htons(src_port);
- }
- }
-
- if (dst_port_opt)
- {
- struct servent * ent = getservbyname(dst_port_opt, 0);
-
- if (ent != 0)
- {
- dst_port = ent->s_port;
- }
- else
- {
- dst_port = strtoul(dst_port_opt, &endptr, 0);
-
- if ((*endptr != '\0')
- || (dst_port == 0 && endptr == dst_port_opt))
- {
- fprintf(stderr, "%s: Invalid character in --dst-port parameter: %s\n"
- , program_name, dst_port_opt);
- exit (1);
- }
- if (dst_port > 65535)
- {
- fprintf(stderr, "%s: --dst-port parameter: %s must be in the range 0 to 65535 inclusive\n"
- , program_name, dst_port_opt);
- }
- dst_port = htons(dst_port);
- }
- }
-
- switch(action_type)
- {
- case EMT_SETEROUTE:
- case EMT_REPLACEROUTE:
- case EMT_INEROUTE:
- if (!(said_af_opt && edst_opt && spi_opt && proto_opt) && !(said_opt))
- {
- fprintf(stderr, "%s: add and addin options must have SA specified.\n"
- , program_name);
- exit(1);
- }
- case EMT_DELEROUTE:
- if (!src_opt)
- {
- fprintf(stderr, "%s: Error -- %s option '--src' is required.\n"
- , program_name, (action_type == EMT_SETEROUTE) ? "add" : "del");
- exit(1);
- }
- if (!dst_opt)
- {
- fprintf(stderr, "%s: Error -- %s option '--dst' is required.\n"
- , program_name, (action_type == EMT_SETEROUTE) ? "add" : "del");
- exit(1);
- }
- case EMT_CLREROUTE:
- break;
- default:
- fprintf(stderr, "%s: exactly one of '--add', '--addin', '--replace', '--del' or '--clear' options must be specified.\n"
- "Try %s --help' for usage information.\n"
- , program_name, program_name);
- exit(1);
- }
-
- if ((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0)
- {
- fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: "
- , program_name);
- switch(errno)
- {
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case EACCES:
- fprintf(stderr, "access denied. ");
- if (getuid() == 0)
- {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- }
- else
- {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "KLIPS not loaded.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. "
- "Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
- break;
- case ENOBUFS:
- case ENOMEM:
- case ENFILE:
- fprintf(stderr, "No kernel memory to allocate socket.\n");
- break;
- case EMFILE:
- fprintf(stderr, "Process file table overflow.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Socket type not supported.\n");
- break;
- case EPROTONOSUPPORT:
- fprintf(stderr, "Protocol version not supported.\n");
- break;
- case EAFNOSUPPORT:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- default:
- fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n"
- , errno);
- }
- exit(1);
- }
-
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: PFKEYv2 socket successfully openned=%d.\n"
- , program_name, pfkey_sock);
- }
-
- /* Build an SADB_X_ADDFLOW or SADB_X_DELFLOW message to send down. */
- /* It needs <base, SA, address(SD), flow(SD), mask(SD)> minimum. */
- pfkey_extensions_init(extensions);
-
- error = pfkey_msg_hdr_build(&extensions[0]
- , (action_type == EMT_SETEROUTE || action_type == EMT_REPLACEROUTE
- || action_type == EMT_INEROUTE)? SADB_X_ADDFLOW : SADB_X_DELFLOW
- , proto2satype(said.proto)
- , 0
- , ++pfkey_seq
- , getpid()
- );
-
- if (error)
- {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n"
- , program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
-
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_msg_hdr_build successfull.\n"
- , program_name);
- }
-
- switch (action_type)
- {
- case EMT_SETEROUTE:
- case EMT_REPLACEROUTE:
- case EMT_INEROUTE:
- case EMT_CLREROUTE:
- error = pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , said.spi /* in network order */
- , 0
- , 0
- , 0
- , 0
- , (action_type == EMT_CLREROUTE) ? SADB_X_SAFLAGS_CLEARFLOW : 0
- );
-
- if (error)
- {
- fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n"
- , program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_sa_build successful.\n"
- , program_name);
- }
- default:
- break;
- }
-
- switch (action_type)
- {
- case EMT_SETEROUTE:
- case EMT_REPLACEROUTE:
- case EMT_INEROUTE:
- anyaddr(said_af, &pfkey_address_s_ska);
- error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC]
- , SADB_EXT_ADDRESS_SRC
- , 0
- , 0
- , sockaddrof(&pfkey_address_s_ska)
- );
- if (error)
- {
- addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n"
- , program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src.\n"
- , program_name);
- }
-
- error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST]
- , SADB_EXT_ADDRESS_DST
- , 0
- , 0
- , sockaddrof(&said.dst)
- );
-
- if (error)
- {
- addrtot(&said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n"
- , program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst.\n"
- , program_name);
- }
- default:
- break;
- }
-
- switch (action_type)
- {
- case EMT_SETEROUTE:
- case EMT_REPLACEROUTE:
- case EMT_INEROUTE:
- case EMT_DELEROUTE:
- networkof(&s_subnet, &pfkey_address_sflow_ska); /* src flow */
- add_port(eroute_af, &pfkey_address_sflow_ska, src_port);
-
- error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_SRC_FLOW]
- , SADB_X_EXT_ADDRESS_SRC_FLOW
- , 0
- , 0
- , sockaddrof(&pfkey_address_sflow_ska)
- );
-
- if (error)
- {
- addrtot(&pfkey_address_sflow_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_sflow extension (%s), error=%d.\n",
- program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src flow.\n"
- , program_name);
- }
-
- networkof(&d_subnet, &pfkey_address_dflow_ska); /* dst flow */
- add_port(eroute_af, &pfkey_address_dflow_ska, dst_port);
-
- error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_DST_FLOW]
- , SADB_X_EXT_ADDRESS_DST_FLOW
- , 0
- , 0
- , sockaddrof(&pfkey_address_dflow_ska)
- );
-
- if (error)
- {
- addrtot(&pfkey_address_dflow_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_dflow extension (%s), error=%d.\n"
- , program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst flow.\n"
- , program_name);
- }
-
- maskof(&s_subnet, &pfkey_address_smask_ska); /* src mask */
- add_port(eroute_af, &pfkey_address_smask_ska, src_port ? ~0:0);
-
- error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_SRC_MASK]
- , SADB_X_EXT_ADDRESS_SRC_MASK
- , 0
- , 0
- , sockaddrof(&pfkey_address_smask_ska)
- );
-
- if (error)
- {
- addrtot(&pfkey_address_smask_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_smask extension (%s), error=%d.\n"
- , program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src mask.\n"
- , program_name);
- }
-
- maskof(&d_subnet, &pfkey_address_dmask_ska); /* dst mask */
- add_port(eroute_af, &pfkey_address_dmask_ska, dst_port ? ~0:0);
-
- error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_DST_MASK]
- , SADB_X_EXT_ADDRESS_DST_MASK
- , 0
- , 0
- , sockaddrof(&pfkey_address_dmask_ska)
- );
-
- if (error)
- {
- addrtot(&pfkey_address_dmask_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_dmask extension (%s), error=%d.\n"
- , program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst mask.\n"
- , program_name);
- }
- }
-
- if (transport_proto != 0)
- {
- error = pfkey_x_protocol_build(&extensions[SADB_X_EXT_PROTOCOL]
- , transport_proto);
-
- if (error)
- {
- fprintf(stderr, "%s: Trouble building transport protocol extension, error=%d.\n"
- , program_name, error);
- exit(1);
- }
- }
-
- error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
-
- if (error)
- {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n"
- , program_name, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey_msg_build successful.\n"
- , program_name);
- }
-
- error = write(pfkey_sock
- , pfkey_msg
- , pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN
- )
- != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-
- if (error)
- {
- fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n"
- , program_name, error, errno);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
-
- switch (errno)
- {
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENXIO:
- if (action_type == EMT_SETEROUTE || action_type == EMT_REPLACEROUTE)
- {
- fprintf(stderr, "Invalid mask.\n");
- break;
- }
- if (action_type == EMT_DELEROUTE)
- {
- fprintf(stderr, "Mask not found.\n");
- break;
- }
- case EFAULT:
- if (action_type == EMT_SETEROUTE || action_type == EMT_REPLACEROUTE)
- {
- fprintf(stderr, "Invalid address.\n");
- break;
- }
- if (action_type == EMT_DELEROUTE)
- {
- fprintf(stderr, "Address not found.\n");
- break;
- }
- case EACCES:
- fprintf(stderr, "access denied. ");
- if (getuid() == 0)
- {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- }
- else
- {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "KLIPS not loaded.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. "
- "Please report as much detail as possible to development team.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- fprintf(stderr, "No device?!?\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "eroute already in use. Delete old one first.\n");
- break;
- case ENOENT:
- if (action_type == EMT_INEROUTE)
- {
- fprintf(stderr, "non-existant IPIP SA.\n");
- break;
- }
- fprintf(stderr, "eroute doesn't exist. Can't delete.\n");
- break;
- case ENOSPC:
- fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n");
- break;
- case ESPIPE:
- fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n"
- , errno);
- }
-/* fprintf(stderr, "%s: socket write returned errno %d\n",
- program_name, errno);*/
- exit(1);
- }
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: pfkey write successful.\n"
- , program_name);
- }
-
- if (pfkey_msg)
- {
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- }
-
- (void) close(pfkey_sock); /* close the socket */
-
- if (debug)
- {
- fprintf(stdout, "%s: DEBUG: write ok\n", program_name);
- }
-
- exit(0);
-}
diff --git a/programs/examples/Makefile b/programs/examples/Makefile
deleted file mode 100644
index 114008a73..000000000
--- a/programs/examples/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/08/28 11:25:09 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-CONFDSUBDIR=examples
-CONFDFILES=oe.conf
-
-include ../Makefile.program
diff --git a/programs/examples/oe.conf.in b/programs/examples/oe.conf.in
deleted file mode 100644
index 4eff4d0dd..000000000
--- a/programs/examples/oe.conf.in
+++ /dev/null
@@ -1,68 +0,0 @@
-# defines default policy groups for Opportunistic Encryption (OE)
-#
-# RCSID $Id: oe.conf.in,v 1.1 2004/08/28 11:25:09 as Exp $
-
-conn packetdefault
- type=tunnel
- leftsubnet=0.0.0.0/0
- right=%opportunistic
- failureshunt=passthrough
- keyingtries=3
- ikelifetime=1h
- keylife=1h
- rekey=no
- also=oe_defaults
- auto=route
-
-conn clear
- type=passthrough
- authby=never
- right=%group
- also=oe_defaults
- auto=route
-
-conn clear-or-private
- type=passthrough
- right=%opportunisticgroup
- failureshunt=passthrough
- keyingtries=3
- ikelifetime=1h
- keylife=1h
- rekey=no
- also=oe_defaults
- auto=route
-
-conn private-or-clear
- type=tunnel
- right=%opportunisticgroup
- failureshunt=passthrough
- keyingtries=3
- ikelifetime=1h
- keylife=1h
- rekey=no
- also=oe_defaults
- auto=route
-
-conn private
- type=tunnel
- right=%opportunisticgroup
- failureshunt=drop
- keyingtries=3
- ikelifetime=1h
- keylife=1h
- rekey=no
- also=oe_defaults
- auto=route
-
-conn block
- type=reject
- authby=never
- right=%group
- also=oe_defaults
- auto=route
-
-conn oe_defaults
- left=%defaultroute
- leftid=%myid
- leftrsasigkey=%dnsondemand
- rightrsasigkey=%dnsondemand
diff --git a/programs/ikeping/.cvsignore b/programs/ikeping/.cvsignore
deleted file mode 100644
index 755295a5f..000000000
--- a/programs/ikeping/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-ikeping
diff --git a/programs/ikeping/Makefile b/programs/ikeping/Makefile
deleted file mode 100644
index 6c7b31d59..000000000
--- a/programs/ikeping/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:27 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=ikeping
-LIBS=${FREESWANLIB}
-
-ifeq ($(USE_IKEPING),false)
-NOINSTALL=true
-install:
- # do nothing
-
-install_file_list:
- # do nothing
-
-endif
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:27 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2003/06/29 21:34:49 mcr
-# added "NOINSTALL" to omit install: target from common
-# Makefile so that it can be overridden
-#
-# Revision 1.3 2003/06/25 03:57:45 mcr
-# build, but do not install "ikeping" even when we do not
-# want it as part of the system.
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/ikeping/ikeping.8 b/programs/ikeping/ikeping.8
deleted file mode 100644
index a9b80b46d..000000000
--- a/programs/ikeping/ikeping.8
+++ /dev/null
@@ -1,71 +0,0 @@
-.TH IPSEC_IKEPING 8 "23 Feb 2002"
-.\" RCSID $Id: ikeping.8,v 1.1 2004/03/15 20:35:27 as Exp $
-.SH NAME
-ipsec ikeping \- send/receive ISAKMP/IKE echo requests/replies
-.SH SYNOPSIS
-.B ipsec
-.B ikeping
-[
-.B \-\-listen
-] [
-.B \-\-verbose
-] [
-.B \-\-wait
-time ] [
-.B \-\-exchangenum
-num ] [
-.B \-\-ikeport
-localport ] [
-.B \-\-ikeaddress
-address ] [
-.B \-\-inet
-] [
-.B \-\-inet6
-] destaddr[/dstport] ...
-.SH DESCRIPTION
-.I Ikeping
-sends and receives ISAKMP/IKE echo request and echo reply packets. These
-packets are intended for diagnostics purposes, in a manner similar to
-.IR ping (8)
-does for ICMP echo request/reply packets.
-.PP
-At the time of this writing, the ISAKMP echo request/reply exchange is still
-an internet-draft, and is therefore completely non-standard.
-.PP
-.I Ikeping
-will bind to the local address given by
-.B \-\-ikeaddress
-and the port number given by
-.B \-\-ikeport
-defaulting to the wildcard address and the ISAKMP port 500. An ISAKMP
-exchange of type 244 (a private use number) is sent to each of the
-address/ports listed on the command line. The exchange number may be
-overridden by the
-.B \-\-exchangenum
-option.
-.PP
-.I Ikeping
-then listens for replies, printing them as they are received. Replies
-are of exchange type 245 or the specified exchange number plus 1.
-.I Ikeping
-will keep listening until it either receives as many echo responses as it sent,
-or until the timeout period (10 seconds) has been reached. Receipt of a
-packet will reset the timer. The
-.B \-\-wait
-option can be used to specify a different timeout period.
-.PP
-If the
-.B \-\-listen
-option is given, then
-.I ikeping
-will not send any packets. Instead, it will listen for them and reply to
-each request received.
-.SH FILES
-no external files
-.SH SEE ALSO
-ping(8), ipsec_pluto(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Michael Richardson.
-.SH BUGS
diff --git a/programs/ikeping/ikeping.c b/programs/ikeping/ikeping.c
deleted file mode 100644
index 7efb26ad7..000000000
--- a/programs/ikeping/ikeping.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* send out an IKE "ping" packet.
- * Copyright (C) 2002 Michael Richardson
- * Copyright (C) 2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ikeping.c,v 1.1 2004/03/15 20:35:27 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <assert.h>
-#include <poll.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/packet.h"
-
-#ifndef ISAKMP_XCHG_ECHOREQUEST
-#define ISAKMP_XCHG_ECHOREQUEST 30 /* Echo Request */
-#define ISAKMP_XCHG_ECHOREPLY 31 /* Echo Reply */
-#endif
-
-#ifndef ISAKMP_XCGH_ECHOREQUEST_PRIV
-#define ISAKMP_XCHG_ECHOREQUEST_PRIV 244 /* Private Echo Request */
-#define ISAKMP_XCHG_ECHOREPLY_PRIV 245 /* Private Echo Reply */
-#endif
-
-
-/* what exchange number to use for outgoing requests */
-static int exchange_number;
-
-static void
-help(void)
-{
- fprintf(stderr,
- "Usage:\n\n"
- "ikeping"
- " [--listen] causes IKEping to open a socket and reply to requests.\n"
- " [--verbose] causes IKEping to hexdump all packets sent/received.\n"
- " [--ikeport <port-number>] port to listen on/send from\n"
- " [--ikeaddress <address>] address to listen on/send from\n"
- " [--inet] just send/listen on IPv4 socket\n"
- " [--inet6] just send/listen on IPv6 socket\n"
- " [--version] just dump version number and exit\n"
- " [--exchangenum num] use num instead of 244 for the exchange type.\n"
- " [--wait seconds] time to wait for replies, defaults to 10 seconds.\n"
- " host/port ...\n\n"
- "FreeS/WAN %s\n",
- ipsec_version_code());
-}
-
-static void
-hton_ping(struct isakmp_hdr *ih)
-{
- u_int32_t *ihp;
-
- ihp=(u_int32_t *)ih;
-
- /* put it in network byte order. */
- /* cookies are byte viewed anyway */
- ihp[4]=htonl(ihp[4]);
- ih->isa_msgid = htonl(ih->isa_msgid);
- ih->isa_length = htonl(ih->isa_length);
-}
-
-static void
-ntoh_ping(struct isakmp_hdr *ih)
-{
- u_int32_t *ihp;
-
- ihp=(u_int32_t *)ih;
-
- /* put it in network byte order. */
- /* cookies are byte viewed anyway */
- ihp[4]=ntohl(ihp[4]);
- ih->isa_msgid = ntohl(ih->isa_msgid);
- ih->isa_length = ntohl(ih->isa_length);
-}
-
-
-/*
- * send an IKE ping
- *
- */
-static void
-send_ping(int afamily,
- int s,
- ip_address *raddr,
- int rport)
-{
- struct isakmp_hdr ih;
- int i, raddrlen;
-
- raddrlen=0;
-
- for(i=0; i<COOKIE_SIZE; i++) {
- ih.isa_icookie[i]=rand()&0xff;
- }
-
- for(i=0; i<COOKIE_SIZE; i++) {
- ih.isa_rcookie[i]=rand()&0xff;
- }
-
- ih.isa_np = NOTHING_WRONG;
- ih.isa_version = (1 << ISA_MAJ_SHIFT) | 0;
- ih.isa_xchg = (exchange_number ?
- exchange_number : ISAKMP_XCHG_ECHOREQUEST_PRIV);
- ih.isa_flags =0;
- ih.isa_msgid =rand();
- ih.isa_length=0;
-
- switch(afamily) {
- case AF_INET:
- raddr->u.v4.sin_port = htons(rport);
- raddrlen=sizeof(raddr->u.v4);
- break;
-
- case AF_INET6:
- raddr->u.v6.sin6_port = htons(rport);
- raddrlen=sizeof(raddr->u.v6);
- break;
- }
-
- hton_ping(&ih);
-
- if(sendto(s, &ih, sizeof(ih), 0, (struct sockaddr *)raddr, raddrlen) < 0) {
- perror("sendto");
- exit(5);
- }
-}
-
-/*
- * send an IKE ping
- *
- */
-static void
-reply_packet(int afamily,
- int s,
- ip_address *dst_addr,
- int dst_len,
- struct isakmp_hdr *op)
-{
- int i, tmp;
-
- tmp=afamily; /* shut up compiler */
-
- for(i=0; i<COOKIE_SIZE; i++) {
- tmp=op->isa_icookie[i];
- op->isa_icookie[i]=op->isa_rcookie[i];
- op->isa_rcookie[i]=tmp;
- }
-
- op->isa_np = NOTHING_WRONG;
- op->isa_version = (1 << ISA_MAJ_SHIFT) | 0;
- op->isa_xchg = ISAKMP_XCHG_ECHOREPLY;
- op->isa_flags =0;
- op->isa_msgid =rand();
- op->isa_length=0;
-
- hton_ping(op);
-
- if(sendto(s, op, sizeof(*op), 0, (struct sockaddr *)dst_addr, dst_len) < 0) {
- perror("sendto");
- exit(5);
- }
-}
-
-/*
- * receive and decode packet.
- *
- */
-static void
-receive_ping(int afamily, int s, int reply)
-{
- ip_address sender;
- struct isakmp_hdr ih;
- char buf[64];
- int n, rport, sendlen;
- const char *xchg_name;
- int xchg;
-
- rport = 500;
- xchg = 0;
- sendlen=sizeof(sender);
- n = recvfrom(s, &ih, sizeof(ih), 0, (struct sockaddr *)&sender, &sendlen);
-
- addrtot(&sender, 0, buf, sizeof(buf));
- switch(afamily) {
- case AF_INET:
- rport = sender.u.v4.sin_port;
- break;
-
- case AF_INET6:
- rport = sender.u.v6.sin6_port;
- break;
- }
-
- if((unsigned int)n < sizeof(ih)) {
- fprintf(stderr, "read short packet (%d) from %s/%d\n",
- n, buf, rport);
- return;
- }
-
- /* translate from network byte order */
- ntoh_ping(&ih);
-
-
- if(ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST ||
- ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST_PRIV ||
- (exchange_number!=0 && ih.isa_xchg == exchange_number)) {
- xchg_name="echo-request";
- xchg=ISAKMP_XCHG_ECHOREQUEST;
- } else if(ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY ||
- ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY_PRIV ||
- (exchange_number!=0 && ih.isa_xchg == exchange_number+1)) {
- xchg_name="echo-reply";
- } else {
- xchg_name="";
- }
-
- printf("received %d(%s) packet from %s/%d of len: %d\n",
- ih.isa_xchg, xchg_name, buf, ntohs(rport), n);
- printf("\trcookie=%08x_%08x icookie=%08x_%08x msgid=%08x\n",
- *(u_int32_t *)(ih.isa_icookie),
- *(u_int32_t *)(ih.isa_icookie+4),
- *(u_int32_t *)(ih.isa_rcookie),
- *(u_int32_t *)(ih.isa_rcookie+4),
- ih.isa_msgid);
- printf("\tnp=%03d version=%d.%d xchg=%s(%d)\n",
- ih.isa_np,
- ih.isa_version >> ISA_MAJ_SHIFT,
- ih.isa_version & ISA_MIN_MASK,
- xchg_name,
- ih.isa_xchg);
-
- if(reply && xchg==ISAKMP_XCHG_ECHOREQUEST) {
- reply_packet(afamily, s, &sender, sendlen, &ih);
- }
-}
-
-static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
- { "verbose", no_argument, NULL, 'v' },
- { "listen", no_argument, NULL, 's' },
- { "ikeport", required_argument, NULL, 'p' },
- { "ikeaddress", required_argument, NULL, 'b' },
- { "inet", no_argument, NULL, '4' },
- { "inet6", no_argument, NULL, '6' },
- { "exchangenum", required_argument, NULL, 'n' },
- { "wait", required_argument, NULL, 'w' },
- { 0,0,0,0 }
-};
-
-int
-main(int argc, char **argv)
-{
- char *foo;
- const char *errstr;
- int s;
- int listen_only;
- int lport,dport;
- int afamily;
- int pfamily;
- int c;
- int numSenders, numReceived, noDNS;
- int waitTime;
- int verbose, timedOut;
- ip_address laddr, raddr;
-
- afamily=AF_INET;
- pfamily=PF_INET;
- lport=500;
- dport=500;
- waitTime=10;
- verbose=0;
- listen_only=0;
- noDNS=0;
- bzero(&laddr, sizeof(laddr));
-
- while((c = getopt_long(argc, argv, "hVnvsp:b:46E:w:", long_opts, 0))!=EOF) {
- switch (c) {
- case 'h': /* --help */
- help();
- return 0; /* GNU coding standards say to stop here */
-
- case 'V': /* --version */
- fprintf(stderr, "FreeS/WAN %s\n", ipsec_version_code());
- return 0; /* GNU coding standards say to stop here */
-
- case 'v': /* --label <string> */
- verbose++;
- continue;
-
- case 'n':
- noDNS=1;
- break;
-
- case 'E':
- exchange_number=strtol(optarg, &foo, 0);
- if(optarg==foo || exchange_number < 1 || exchange_number>255) {
- fprintf(stderr, "Invalid exchange number '%s' (should be 1<=x<255)\n",
- optarg);
- exit(1);
- }
- continue;
-
-
- case 's':
- listen_only++;
- continue;
-
- case 'p':
- lport=strtol(optarg, &foo, 0);
- if(optarg==foo || lport <0 || lport>65535) {
- fprintf(stderr, "Invalid port number '%s' (should be 0<=x<65536)\n",
- optarg);
- exit(1);
- }
- continue;
-
- case 'w':
- waitTime=strtol(optarg, &foo, 0);
- if(optarg==foo || waitTime < 0) {
- fprintf(stderr, "Invalid waittime number '%s' (should be 0<=x)\n",
- optarg);
- exit(1);
- }
- continue;
-
- case 'b':
- errstr = ttoaddr(optarg, strlen(optarg), afamily, &laddr);
- if(errstr!=NULL) {
- fprintf(stderr, "Invalid local address '%s': %s\n",
- optarg, errstr);
- exit(1);
- }
- continue;
-
- case '4':
- afamily=AF_INET;
- pfamily=PF_INET;
- continue;
-
- case '6':
- afamily=AF_INET6;
- pfamily=PF_INET6;
- continue;
-
- default:
- assert(FALSE); /* unknown return value */
- }
- }
-
- s=socket(pfamily, SOCK_DGRAM, IPPROTO_UDP);
- if(s < 0) {
- perror("socket");
- exit(3);
- }
-
- switch(afamily) {
- case AF_INET:
- laddr.u.v4.sin_port = htons(lport);
- if(bind(s, (struct sockaddr *)&laddr.u.v4, sizeof(laddr.u.v4)) < 0) {
- perror("v4 bind");
- exit(5);
- }
- break;
-
- case AF_INET6:
- laddr.u.v6.sin6_port = htons(lport);
- if(bind(s, (struct sockaddr *)&laddr.u.v6, sizeof(laddr.u.v6)) < 0) {
- perror("v6 bind");
- exit(5);
- }
- break;
- }
-
- numSenders = 0;
-
- if(!listen_only) {
- while(optind < argc) {
- char *port;
- char *host;
- char namebuf[128];
-
- host = argv[optind];
-
- port = strchr(host, '/');
- dport=500;
- if(port) {
- *port='\0';
- port++;
- dport= strtol(port, &foo, 0);
- if(port==foo || dport < 0 || dport > 65535) {
- fprintf(stderr, "Invalid port number '%s' "
- "(should be 0<=x<65536)\n",
- port);
- exit(1);
- }
- }
-
- errstr = ttoaddr(host, strlen(host),
- afamily, &raddr);
- if(errstr!=NULL) {
- fprintf(stderr, "Invalid remote address '%s': %s\n",
- host, errstr);
- exit(1);
- }
-
- addrtot(&raddr, 0, namebuf, sizeof(namebuf));
-
- printf("Sending packet to %s/%d\n", namebuf, dport);
-
- send_ping(afamily, s, &raddr, dport);
- numSenders++;
- optind++;
- }
- }
-
- timedOut = 0;
- numReceived=0;
-
- /* really should catch ^C and print stats on exit */
- while(numSenders > 0 || listen_only) {
- struct pollfd ready;
- int n;
-
- ready.fd = s;
- ready.events = POLLIN;
-
- n = poll(&ready, 1, waitTime);
- if(n < 0) {
- perror("poll");
- exit(1);
- }
-
- if(n == 0 && !listen_only) {
- break;
- }
-
- if(n == 1) {
- numReceived++;
- receive_ping(afamily, s, listen_only);
- }
- }
-
- if(numReceived > 0) {
- printf("%d packets sent, %d packets received. %d packet loss\n",
- numSenders, numReceived, numSenders*100/numReceived);
- }
- exit(0);
-}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 4
- * End:
- *
- */
diff --git a/programs/ipsec/.cvsignore b/programs/ipsec/.cvsignore
deleted file mode 100644
index 70025a7f8..000000000
--- a/programs/ipsec/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-ipsec
diff --git a/programs/ipsec/Makefile b/programs/ipsec/Makefile
deleted file mode 100644
index fdff3728a..000000000
--- a/programs/ipsec/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.2 2006/02/10 11:27:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=ipsec
-PROGRAMDIR=${SBINDIR}
-MANPROGPREFIX:=./
-LIBFILES:=$(wildcard distro.txt)
-
-include ../Makefile.program
-
-install:: ipsec
- @$(INSTALL) $(INSTBINFLAGS) ipsec $(RCDIR)/ipsec
-
diff --git a/programs/ipsec/distro.txt b/programs/ipsec/distro.txt
deleted file mode 100644
index 80f4192a4..000000000
--- a/programs/ipsec/distro.txt
+++ /dev/null
@@ -1 +0,0 @@
-distributed by Andreas Steffen <andreas.steffen@strongswan.org>
diff --git a/programs/ipsec/ipsec.8 b/programs/ipsec/ipsec.8
deleted file mode 100644
index 823289372..000000000
--- a/programs/ipsec/ipsec.8
+++ /dev/null
@@ -1,336 +0,0 @@
-.TH IPSEC 8 "9 February 2006"
-.\" RCSID $Id: ipsec.8,v 1.3 2006/02/09 19:47:38 as Exp $
-.SH NAME
-ipsec \- invoke IPsec utilities
-.SH SYNOPSIS
-.B ipsec
-command [ argument ...]
-.sp
-.B ipsec start|update|reload|restart|stop
-.sp
-.B ipsec up|down|route|unroute
-\fIconnectionname\fP
-.sp
-.B ipsec status|statusall
-[
-\fIconnectionname\fP
-]
-.sp
-.B ipsec listalgs|listpubkeys|listcerts
-[
-.B \-\-utc
-]
-.br
-.B ipsec listcacerts|listaacerts|listocspcerts
-[
-.B \-\-utc
-]
-.br
-.B ipsec listacerts|listgroups|listcainfos
-[
-.B \-\-utc
-]
-.br
-.B ipsec listcrls|listocsp|listcards|listall
-[
-.B \-\-utc
-]
-.sp
-.B ipsec rereadsecrets|rereadgroups
-.br
-.B ipsec rereadcacerts|rereadaacerts|rereadocspcerts
-.br
-.B ipsec rereadacerts|rereadcrls|rereadall
-.sp
-.B ipsec purgeocsp
-.sp
-.B ipsec
-[
-.B \-\-help
-] [
-.B \-\-version
-] [
-.B \-\-versioncode
-] [
-.B \-\-copyright
-]
-.br
-.B ipsec
-[
-.B \-\-directory
-] [
-.B \-\-confdir
-]
-.SH DESCRIPTION
-.I Ipsec
-invokes any of several utilities involved in controlling the IPsec
-encryption/authentication system,
-running the specified
-.I command
-with the specified
-.IR argument s
-as if it had been invoked directly.
-This largely eliminates possible name collisions with other software,
-and also permits some centralized services.
-.PP
-The commands
-.BR start ,
-.BR update ,
-.BR reload ,
-.BR restart ,
-and
-.BR stop
-are built-in and are used to control the
-.BR "ipsec starter"
-utility, an extremely fast replacement for the traditional
-.BR ipsec
-.BR setup
-script.
-.PP
-The commands
-.BR up,
-.BR down,
-.BR route,
-.BR unroute,
-.BR status,
-.BR statusall,
-.BR listalgs,
-.BR listpubkeys,
-.BR listcerts,
-.BR listcacerts,
-.BR listaacerts,
-.BR listocspcerts,
-.BR listacerts,
-.BR listgroups,
-.BR listcainfos,
-.BR listcrls,
-.BR listocsp,
-.BR listcards,
-.BR listall,
-.BR rereadsecrets,
-.BR rereadgroups,
-.BR rereadcacerts,
-.BR rereadaacerts,
-.BR rereadocspcerts,
-.BR rereadacerts,
-.BR rereadcrls,
-and
-.BR rereadall
-are also built-in and completely replace the corresponding
-.BR "ipsec auto"
-\-\-\fIoperation\fP"
-commands. Communication with the pluto daemon happens via the
-.BR "ipsec whack"
-socket interface.
-.PP
-In particular,
-.I ipsec
-supplies the invoked
-.I command
-with a suitable PATH environment variable,
-and also provides IPSEC_DIR,
-IPSEC_CONFS, and IPSEC_VERSION environment variables,
-containing respectively
-the full pathname of the directory where the IPsec utilities are stored,
-the full pathname of the directory where the configuration files live,
-and the IPsec version number.
-.PP
-.B "ipsec start"
-calls
-.BR "ipsec starter"
-which in turn starts \fIpluto\fR.
-.PP
-.B "ipsec update"
-sends a \fIHUP\fR signal to
-.BR "ipsec starter"
-which in turn determines any changes in \fIipsec.conf\fR
-and updates the configuration on the running \fIpluto\fR daemon, correspondingly.
-.PP
-.B "ipsec reload"
-sends a \fIUSR1\fR signal to
-.BR "ipsec starter"
-which in turn reloads the whole configuration on the running \fIpluto\fR daemon
-based on the actual \fIipsec.conf\fR.
-.PP
-.B "ipsec restart"
-executes
-.B "ipsec stop"
-followed by
-.BR "ipsec start".
-.PP
-.B "ipsec stop"
-stops \fIipsec\fR by sending a \fITERM\fR signal to
-.BR "ipsec starter".
-.PP
-.B "ipsec up"
-\fIname\fP tells the \fIpluto\fP daemon to start up connection \fIname\fP.
-.PP
-.B "ipsec down"
-\fIname\fP tells the \fIpluto\fP daemon to take down connection \fIname\fP.
-.PP
-.B "ipsec route"
-\fIname\fP tells the \fIpluto\fP daemon to install a route for connection
-\fIname\fP.
-.PP
-.B "ipsec unroute"
-\fIname\fP tells the \fIpluto\fP daemon to take down the route for connection
-\fIname\fP.
-.PP
-.B "ipsec status"
-[ \fIname\fP ] gives concise status information either on connection
-\fIname\fP or if the \fIname\fP argument is lacking, on all connections.
-.PP
-.B "ipsec statusall"
-[ \fIname\fP ] gives detailed status information either on connection
-\fIname\fP or if the \fIname\fP argument is lacking, on all connections.
-.PP
-.B "ipsec listalgs"
-returns a list all supported IKE encryption and hash algorithms, the available
-Diffie-Hellman groups, as well as all supported ESP encryption and authentication
-algorithms.
-.PP
-.B "ipsec listpubkeys"
-returns a list of RSA public keys that were either loaded in raw key format
-or extracted from X.509 and|or OpenPGP certificates.
-.PP
-.B "ipsec listcerts"
-returns a list of X.509 and|or OpenPGP certificates that were loaded locally
-by the \fIpluto\fP daemon.
-.PP
-.B "ipsec listcacerts"
-returns a list of X.509 Certification Authority (CA) certificates that were
-loaded locally by the \fIpluto\fP daemon from the \fI/etc/ipsec.d/cacerts/\fP
-directory or received in PKCS#7-wrapped certificate payloads via the IKE
-protocol.
-.PP
-.B "ipsec listaacerts"
-returns a list of X.509 Authorization Authority (AA) certificates that were
-loaded locally by the \fIpluto\fP daemon from the \fI/etc/ipsec.d/aacerts/\fP
-directory.
-.PP
-.B "ipsec listocspcerts"
-returns a list of X.509 OCSP Signer certificates that were either loaded
-locally by the \fIpluto\fP daemon from the \fI/etc/ipsec.d/ocspcerts/\fP
-directory or were sent by an OCSP server.
-.PP
-.B "ipsec listacerts"
-returns a list of X.509 Attribute certificates that were loaded locally by
-the \fIpluto\fP daemon from the \fI/etc/ipsec.d/acerts/\fP directory.
-.PP
-.B "ipsec listgroups"
-returns a list of groups that are used to define user authorization profiles.
-.PP
-.B "ipsec listcainfos"
-returns certification authority information (CRL distribution points, OCSP URIs,
-LDAP servers) that were defined by
-.BR ca
-sections in \fIipsec.conf\fP.
-.PP
-.B "ipsec listcrls"
-returns a list of Certificate Revocation Lists (CRLs).
-.PP
-.B "ipsec listocsp"
-returns revocation information fetched from OCSP servers.
-.PP
-.B "ipsec listcards"
-returns a list of certificates residing on smartcards.
-.PP
-.B "ipsec listall"
-returns all information generated by the list commands above. Each list command
-can be called with the
-\-\-url
-option which displays all dates in UTC instead of local time.
-.PP
-.B "ipsec rereadsecrets"
-flushes and rereads all secrets defined in \fIipsec.conf\fP.
-.PP
-.B "ipsec rereadcacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
-directory and adds them to \fIpluto\fP's list of Certification Authority (CA) certificates.
-.PP
-.B "ipsec rereadaacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
-directory and adds them to \fIpluto\fP's list of Authorization Authority (AA) certificates.
-.PP
-.B "ipsec rereadocspcerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/ocspcerts/\fP
-directory and adds them to \fIpluto\fP's list of OCSP signer certificates.
-.PP
-.B "ipsec rereadacerts"
-operation reads all certificate files contained in the \fI/etc/ipsec.d/acerts/\fP
-directory and adds them to \fIpluto\fP's list of attribute certificates.
-.PP
-.B "ipsec rereadcrls"
-reads all Certificate Revocation Lists (CRLs) contained in the
-\fI/etc/ipsec.d/crls/\fP directory and adds them to \fIpluto\fP's list of CRLs.
-.PP
-.B "ipsec rereadall"
-is equivalent to the execution of \fBrereadsecrets\fP,
-\fBrereadcacerts\fP, \fBrereadaacerts\fP, \fBrereadocspcerts\fP,
-\fBrereadacerts\fP, and \fBrereadcrls\fP.
-.PP
-.B "ipsec \-\-help"
-lists the available commands.
-Most have their own manual pages, e.g.
-.IR ipsec_auto (8)
-for
-.IR auto .
-.PP
-.B "ipsec \-\-version"
-outputs version information about Linux strongSwan.
-A version code of the form ``U\fIxxx\fR/K\fIyyy\fR''
-indicates that the user-level utilities are version \fIxxx\fR
-but the kernel portion appears to be version \fIyyy\fR
-(this form is used only if the two disagree).
-.PP
-.B "ipsec \-\-versioncode"
-outputs \fIjust\fR the version code,
-with none of
-.BR \-\-version 's
-supporting information,
-for use by scripts.
-.PP
-.B "ipsec \-\-copyright"
-supplies boring copyright details.
-.PP
-.B "ipsec \-\-directory"
-reports where
-.I ipsec
-thinks the IPsec utilities are stored.
-.PP
-.B "ipsec \-\-confdir"
-reports where
-.I ipsec
-thinks the IPsec configuration files are stored.
-.SH FILES
-/usr/local/lib/ipsec usual utilities directory
-.SH ENVIRONMENT
-.PP
-The following environment variables control where strongSwan finds its
-components.
-The
-.B ipsec
-command sets them if they are not already set.
-.nf
-.na
-IPSEC_EXECDIR directory containing published commands
-IPSEC_LIBDIR directory containing internal executables
-IPSEC_SBINDIR directory containing \fBipsec\fP command
-IPSEC_CONFS directory containing configuration files
-.ad
-.fi
-.SH SEE ALSO
-.hy 0
-.na
-ipsec.conf(5), ipsec.secrets(5),
-ipsec_barf(8),
-.ad
-.hy
-.PP
-.SH HISTORY
-Written for Linux FreeS/WAN
-<http://www.freeswan.org>
-by Henry Spencer.
-Updated and extended for Linux strongSwan
-<http://www.strongswan.org>
-by Andreas Steffen.
diff --git a/programs/ipsec/ipsec.in b/programs/ipsec/ipsec.in
deleted file mode 100755
index 1c657b9e7..000000000
--- a/programs/ipsec/ipsec.in
+++ /dev/null
@@ -1,259 +0,0 @@
-#! /bin/sh
-# prefix command to run stuff from our programs directory
-# Copyright (C) 1998-2002 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: ipsec.in,v 1.14 2006/05/25 11:52:03 as Exp $
-
-IPSEC_NAME=strongSwan
-
-# where the private directory and the config files are
-IPSEC_EXECDIR="${IPSEC_EXECDIR-@IPSEC_EXECDIR@}"
-IPSEC_LIBDIR="${IPSEC_LIBDIR-@IPSEC_LIBDIR@}"
-IPSEC_SBINDIR="${IPSEC_SBINDIR-@IPSEC_SBINDIR@}"
-IPSEC_CONFS="${IPSEC_CONFS-@IPSEC_CONFS@}"
-
-IPSEC_DIR="$IPSEC_LIBDIR"
-export IPSEC_DIR IPSEC_CONFS IPSEC_LIBDIR IPSEC_EXECDIR
-
-IPSEC_STARTER_PID="/var/run/starter.pid"
-
-# standardize PATH, and export it for everything else's benefit
-PATH="${IPSEC_SBINDIR}":/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin
-export PATH
-
-# things not to be listed in --help command list
-DONTMENTION='^(ipsec|_.*|.*\.old|.*~)$'
-
-# version numbering (details filled in by build)
-# Possibly should call a C program to invoke the version_code() function
-# instead, but for performance's sake, we inline it here (and only here).
-version="xxx"
-
-# export the version information
-IPSEC_VERSION="$version"
-export IPSEC_VERSION
-
-# function for the funky user/kernel version stuff
-fixversion() {
- if test -f /proc/net/ipsec_version
- then
- stack=" (KLIPS)"
- kv="`awk '{print $NF}' /proc/net/ipsec_version`"
- else
- if test -f /proc/net/pfkey
- then
- stack=" (native)"
- kv="`uname -r`"
- else
- kv="(no kernel code presently loaded)"
- fi
- fi
- if test " $kv" != " $version"
- then
- version="U$version/K$kv"
- fi
- version="$version$stack"
-}
-
-case "$1" in
-'')
- echo "Usage: ipsec command argument ..."
- echo "Use --help for list of commands, or see ipsec(8) manual page"
- echo "or the $IPSEC_NAME documentation for names of the common ones."
- echo "Most have their own manual pages, e.g. ipsec_auto(8)."
- echo "See <http://www.strongswan.org> for more general info."
- exit 0
- ;;
---help)
- echo "Usage: ipsec command argument ..."
- echo "where command is one of:"
- echo " start|restart arguments..."
- echo " update|reload|stop"
- echo " up|down|route|unroute <connectionname>"
- echo " status|statusall [<connectionname>]"
- echo " ready"
- echo " listalgs|listpubkeys|listcerts [--utc]"
- echo " listcacerts|listaacerts|listocspcerts [--utc]"
- echo " listacerts|listgroups|listcainfos [--utc]"
- echo " listcrls|listocsp|listcards|listall [--utc]"
- echo " rereadsecrets|rereadgroups"
- echo " rereadcacerts|rereadaacerts|rereadocspcerts"
- echo " rereadacerts|rereadcrls|rereadall"
- echo " purgeocsp"
- echo " scencrypt|scdecrypt <value> [--inbase <base>] [--outbase <base>] [--keyid <id>]"
- echo " barf"
- echo " openac"
- echo " pluto"
- echo " scepclient"
- echo " secrets"
- echo " starter"
- echo " version"
- echo " whack"
- echo
- echo "Some of these functions have their own manual pages, e.g. ipsec_scepclient(8)."
- exit 0
- ;;
---versioncode)
- fixversion
- echo "$version"
- exit 0
- ;;
---copyright)
- set _copyright
- # and fall through, invoking "ipsec _copyright"
- ;;
---directory)
- echo "$IPSEC_DIR"
- exit 0
- ;;
---confdir)
- echo "$IPSEC_CONFS"
- exit 0
- ;;
-down)
- shift
- if [ "$#" -ne 1 ]
- then
- echo "Usage: ipsec down <connection name>"
- exit 1
- fi
- $IPSEC_EXECDIR/whack --name "$1" --terminate
- exit 0
- ;;
-listalgs|listpubkeys|listcerts|listcacerts|\
-listaacerts|listocspcerts|listacerts|listgroups|\
-listcainfos|listcrls|listocsp|listcards|\
-listall|purgeocsp|rereadsecrets|rereadgroups|\
-rereadcacerts|rereadaacerts|rereadocspcerts|\
-rereadacerts|rereadcrls|rereadall)
- op="$1"
- shift
- $IPSEC_EXECDIR/whack "$@" "--$op"
- exit 0
- ;;
-ready)
- shift
- $IPSEC_EXECDIR/whack --listen
- exit 0
- ;;
-reload)
- if test -e $IPSEC_STARTER_PID
- then
- echo "Reloading strongSwan IPsec configuration..." >&2
- kill -s USR1 `cat $IPSEC_STARTER_PID`
- else
- echo "ipsec starter is not running" >&2
- fi
- exit 0
- ;;
-restart)
- $IPSEC_SBINDIR/ipsec stop
- sleep 2
- shift
- $IPSEC_SBINDIR/ipsec start "$@"
- exit 0
- ;;
-route|unroute)
- op="$1"
- shift
- if [ "$#" -ne 1 ]
- then
- echo "Usage: ipsec $op <connection name>"
- exit 1
- fi
- $IPSEC_EXECDIR/whack --name "$1" "--$op"
- exit 0
- ;;
-scencrypt|scdecrypt)
- op="$1"
- shift
- $IPSEC_EXECDIR/whack "--$op" "$@"
- exit 0
- ;;
-start)
- shift
- exec $IPSEC_EXECDIR/starter "$@"
- ;;
-status|statusall)
- op="$1"
- shift
- if test $# -eq 0
- then
- $IPSEC_EXECDIR/whack "--$op"
- else
- $IPSEC_EXECDIR/whack --name "$1" "--$op"
- fi
- exit 0
- ;;
-stop)
- if test -e $IPSEC_STARTER_PID
- then
- echo "Stopping strongSwan IPsec..." >&2
- kill `cat $IPSEC_STARTER_PID`
- else
- echo "ipsec starter is not running" >&2
- fi
- exit 0
- ;;
-up)
- shift
- if [ "$#" -ne 1 ]
- then
- echo "Usage: ipsec up <connection name>"
- exit 1
- fi
- $IPSEC_EXECDIR/whack --name "$1" --initiate
- exit 0
- ;;
-update)
- if test -e $IPSEC_STARTER_PID
- then
- echo "Updating strongSwan IPsec configuration..." >&2
- kill -s HUP `cat $IPSEC_STARTER_PID`
- else
- echo "ipsec starter is not running" >&2
- fi
- exit 0
- ;;
-version|--version)
- fixversion
- echo "Linux $IPSEC_NAME $version"
- echo "See \`ipsec --copyright' for copyright information."
- if [ -f $IPSEC_LIBDIR/distro.txt ]
- then
- cat $IPSEC_LIBDIR/distro.txt
- fi
- exit 0
- ;;
---*)
- echo "$0: unknown option \`$1' (perhaps command name was omitted?)" >&2
- exit 1
- ;;
-esac
-
-cmd="$1"
-shift
-
-path="$IPSEC_EXECDIR/$cmd"
-
-if test ! -x "$path"
-then
- path="$IPSEC_LIBDIR/$cmd"
- if test ! -x "$path"
- then
- echo "$0: unknown IPsec command \`$cmd' (\`ipsec --help' for list)" >&2
- exit 1
- fi
-fi
-
-exec $path "$@"
diff --git a/programs/klipsdebug/.cvsignore b/programs/klipsdebug/.cvsignore
deleted file mode 100644
index 03c1d474c..000000000
--- a/programs/klipsdebug/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-klipsdebug
diff --git a/programs/klipsdebug/Makefile b/programs/klipsdebug/Makefile
deleted file mode 100644
index 6c98e7592..000000000
--- a/programs/klipsdebug/Makefile
+++ /dev/null
@@ -1,80 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM:=klipsdebug
-EXTRA5PROC=${PROGRAM}.5
-
-LIBS:=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/klipsdebug/klipsdebug.5 b/programs/klipsdebug/klipsdebug.5
deleted file mode 100644
index 8e5f985f0..000000000
--- a/programs/klipsdebug/klipsdebug.5
+++ /dev/null
@@ -1,138 +0,0 @@
-.TH IPSEC_KLIPSDEBUG 5 "26 Jun 2000"
-.\"
-.\" RCSID $Id: klipsdebug.5,v 1.1 2004/03/15 20:35:28 as Exp $
-.\"
-.SH NAME
-ipsec_klipsdebug \- list KLIPS (kernel IPSEC support) debug features and level
-.SH SYNOPSIS
-.B ipsec
-.B klipsdebug
-.PP
-.B cat
-.B /proc/net/ipsec_klipsdebug
-.SH DESCRIPTION
-.I /proc/net/ipsec_klipsdebug
-lists flags that control various parts of the debugging output of Klips
-(the kernel portion of FreeS/WAN IPSEC).
-At this point it is a read-only file.
-.PP
-A table entry consists of:
-.IP + 3
-a KLIPS debug variable
-.IP +
-a '=' separator for visual and automated parsing between the variable
-name and its current value
-.IP +
-hexadecimal bitmap of variable's flags.
-.PP
-The variable names roughly describe the scope of the debugging variable.
-Currently, no flags are documented or individually accessible yet except
-tunnel-xmit.
-.ne 5
-.PP
-The variable names are:
-.TP 8
-.B tunnel
-tunnelling code
-.TP
-.B netlink
-userspace communication code (obsolete)
-.TP
-.B xform
-transform selection and manipulation code
-.TP
-.B eroute
-eroute table manipulation code
-.TP
-.B spi
-SA table manipulation code
-.TP
-.B radij
-radij tree manipulation code
-.TP
-.B esp
-encryptions transforms code
-.TP
-.B ah
-authentication transforms code
-.TP
-.B rcv
-receive code
-.TP
-.B ipcomp
-ip compression transforms code
-.TP
-.B verbose
-give even more information, beware this will probably trample the 4k kernel printk buffer giving inaccurate output
-.PP
-All KLIPS debug output appears as
-.B kernel.info
-messages to
-.IR syslogd (8).
-Most systems are set up
-to log these messages to
-.IR /var/log/messages .
-.PP
-.SH EXAMPLES
-.LP
-.B debug_tunnel=00000010.
-.br
-.B debug_netlink=00000000.
-.br
-.B debug_xform=00000000.
-.br
-.B debug_eroute=00000000.
-.br
-.B debug_spi=00000000.
-.br
-.B debug_radij=00000000.
-.br
-.B debug_esp=00000000.
-.br
-.B debug_ah=00000000.
-.br
-.B debug_rcv=00000000.
-.br
-.B debug_pfkey=ffffffff.
-.LP
-means that one
-.B tunnel
-flag has been set (tunnel-xmit),
-full
-.B pfkey
-sockets debugging has been set and everything else is not set.
-.LP
-.SH FILES
-/proc/net/ipsec_klipsdebug, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_eroute(8),
-ipsec_spi(8), ipsec_spigrp(8), ipsec_klipsdebug(5), ipsec_version(5),
-ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: klipsdebug.5,v $
-.\" Revision 1.1 2004/03/15 20:35:28 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.5 2002/04/24 07:35:38 mcr
-.\" Moved from ./klips/utils/klipsdebug.5,v
-.\"
-.\" Revision 1.4 2000/10/10 20:10:19 rgb
-.\" Added support for debug_ipcomp and debug_verbose to klipsdebug.
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/28 12:44:12 henry
-.\" format touchup
-.\"
-.\" Revision 1.1 2000/06/28 05:43:00 rgb
-.\" Added manpages for all 5 klips utils.
-.\"
-.\"
-.\"
diff --git a/programs/klipsdebug/klipsdebug.8 b/programs/klipsdebug/klipsdebug.8
deleted file mode 100644
index 60d018eec..000000000
--- a/programs/klipsdebug/klipsdebug.8
+++ /dev/null
@@ -1,164 +0,0 @@
-.TH IPSEC_KLIPSDEBUG 8 "21 Jun 2000"
-.\"
-.\" RCSID $Id: klipsdebug.8,v 1.1 2004/03/15 20:35:28 as Exp $
-.\"
-.SH NAME
-ipsec klipsdebug \- set KLIPS (kernel IPSEC support) debug features and level
-.SH SYNOPSIS
-.B ipsec
-.B klipsdebug
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-set
-flagname
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-clear
-flagname
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-all
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-none
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-help
-.PP
-.B ipsec
-.B klipsdebug
-.B \-\-version
-.SH DESCRIPTION
-.I Klipsdebug
-sets and clears flags that control
-various parts of the debugging output of Klips
-(the kernel portion of FreeS/WAN IPSEC).
-The form with no additional arguments lists the present contents of
-/proc/net/ipsec_klipsdebug.
-The
-.B \-\-set
-form turns the specified flag on,
-while the
-.B \-\-clear
-form turns the specified flag off.
-The
-.B \-\-all
-form
-turns all flags on except verbose, while the
-.B \-\-none
-form turns all flags off.
-.PP
-The current flag names are:
-.TP 8
-.B tunnel
-tunnelling code
-.TP
-.B tunnel-xmit
-tunnelling transmit only code
-.TP
-.B pfkey
-userspace communication code
-.TP
-.B xform
-transform selection and manipulation code
-.TP
-.B eroute
-eroute table manipulation code
-.TP
-.B spi
-SA table manipulation code
-.TP
-.B radij
-radij tree manipulation code
-.TP
-.B esp
-encryptions transforms code
-.TP
-.B ah
-authentication transforms code
-.B rcv
-receive code
-.TP
-.B ipcomp
-ip compression transforms code
-.TP
-.B verbose
-give even more information, BEWARE:
-a)this will print authentication and encryption keys in the logs
-b)this will probably trample the 4k kernel printk buffer giving inaccurate output
-.PP
-All Klips debug output appears as
-.B kernel.info
-messages to
-.IR syslogd (8).
-Most systems are set up
-to log these messages to
-.IR /var/log/messages .
-Beware that
-.B klipsdebug
-.B \-\-all
-produces a lot of output and the log file will grow quickly.
-.PP
-The file format for /proc/net/ipsec_klipsdebug is discussed in
-ipsec_klipsdebug(5).
-.SH EXAMPLES
-.TP
-.B klipsdebug \-\-all
-turns on all KLIPS debugging except verbose.
-.TP
-.B klipsdebug \-\-clear tunnel
-turns off only the
-.B tunnel
-debugging messages.
-.LP
-.SH FILES
-/proc/net/ipsec_klipsdebug, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_eroute(8),
-ipsec_spi(8), ipsec_spigrp(8), ipsec_klipsdebug(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.SH BUGS
-It really ought to be possible to set or unset selective combinations
-of flags.
-.\"
-.\" $Log: klipsdebug.8,v $
-.\" Revision 1.1 2004/03/15 20:35:28 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.18 2002/04/24 07:35:39 mcr
-.\" Moved from ./klips/utils/klipsdebug.8,v
-.\"
-.\" Revision 1.17 2000/10/10 20:10:19 rgb
-.\" Added support for debug_ipcomp and debug_verbose to klipsdebug.
-.\"
-.\" Revision 1.16 2000/08/18 17:33:11 rgb
-.\" Updated obsolete netlink reference and added pfkey and tunnel-xmit.
-.\"
-.\" Revision 1.15 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.14 2000/06/28 05:53:09 rgb
-.\" Mention that netlink is obsolete.
-.\"
-.\" Revision 1.13 2000/06/21 16:54:58 rgb
-.\" Added 'no additional args' text for listing contents of
-.\" /proc/net/ipsec_* files.
-.\"
-.\" Revision 1.12 1999/07/19 18:47:24 henry
-.\" fix slightly-misformed comments
-.\"
-.\" Revision 1.11 1999/04/06 04:54:37 rgb
-.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-.\" patch shell fixes.
-.\"
-.\"
diff --git a/programs/klipsdebug/klipsdebug.c b/programs/klipsdebug/klipsdebug.c
deleted file mode 100644
index c205038a1..000000000
--- a/programs/klipsdebug/klipsdebug.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * control KLIPS debugging options
- * Copyright (C) 1996 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
- * 2001 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char klipsdebug_c_version[] = "RCSID $Id: klipsdebug.c,v 1.2 2004/06/07 15:16:34 as Exp $";
-
-
-#include <sys/types.h>
-#include <linux/types.h> /* new */
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h> /* system(), strtoul() */
-#include <sys/stat.h> /* open() */
-#include <fcntl.h> /* open() */
-
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-
-
-#include <unistd.h>
-#include <freeswan.h>
-#if 0
-#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */
-#endif
-
-/* permanently turn it on since netlink support has been disabled */
-#include <signal.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "freeswan/radij.h"
-#include "freeswan/ipsec_encap.h"
-#ifndef CONFIG_IPSEC_DEBUG
-#define CONFIG_IPSEC_DEBUG
-#endif /* CONFIG_IPSEC_DEBUG */
-#include "freeswan/ipsec_tunnel.h"
-
-#include <stdio.h>
-#include <getopt.h>
-
-__u32 bigbuf[1024];
-char *program_name;
-
-int pfkey_sock;
-fd_set pfkey_socks;
-uint32_t pfkey_seq = 0;
-
-char copyright[] =
-"Copyright (C) 1999 Henry Spencer, Richard Guy Briggs, D. Hugh Redelmeier,\n\
- Sandy Harris, Angelos D. Keromytis, John Ioannidis.\n\
-\n\
- This program is free software; you can redistribute it and/or modify it\n\
- under the terms of the GNU General Public License as published by the\n\
- Free Software Foundation; either version 2 of the License, or (at your\n\
- option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.\n\
-\n\
- This program is distributed in the hope that it will be useful, but\n\
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n\
- (file COPYING in the distribution) for more details.\n";
-
-static void
-usage(char * arg)
-{
- fprintf(stdout, "usage: %s {--set|--clear} {tunnel|tunnel-xmit|netlink|xform|eroute|spi|radij|esp|ah|rcv|pfkey|ipcomp|verbose}\n", arg);
- fprintf(stdout, " %s {--all|--none}\n", arg);
- fprintf(stdout, " %s --help\n", arg);
- fprintf(stdout, " %s --version\n", arg);
- fprintf(stdout, " %s\n", arg);
- fprintf(stdout, " [ --debug ] is optional to any %s command\n", arg);
- fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", arg);
- exit(1);
-}
-
-static struct option const longopts[] =
-{
- {"set", 1, 0, 's'},
- {"clear", 1, 0, 'c'},
- {"all", 0, 0, 'a'},
- {"none", 0, 0, 'n'},
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"label", 1, 0, 'l'},
- {"optionsfrom", 1, 0, '+'},
- {"debug", 0, 0, 'd'},
- {0, 0, 0, 0}
-};
-
-int
-main(int argc, char **argv)
-{
-/* int fd; */
- unsigned char action = 0;
- int c, previous = -1;
-
- int debug = 0;
- int error = 0;
- int argcount = argc;
- int em_db_tn, em_db_nl, em_db_xf, em_db_er, em_db_sp;
- int em_db_rj, em_db_es, em_db_ah, em_db_rx, em_db_ky;
- int em_db_gz, em_db_vb;
-
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
-
- em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
- em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
- em_db_gz=em_db_vb=0;
-
-
- program_name = argv[0];
-
- while((c = getopt_long(argc, argv, ""/*"s:c:anhvl:+:d"*/, longopts, 0)) != EOF) {
- switch(c) {
- case 'd':
- debug = 1;
- pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
- argcount--;
- break;
- case 's':
- if(action) {
- fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
- program_name);
- exit(1);
- }
- action = 's';
- em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
- em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
- em_db_gz=em_db_vb=0;
- if(strcmp(optarg, "tunnel") == 0) {
- em_db_tn = -1L;
- } else if(strcmp(optarg, "tunnel-xmit") == 0) {
- em_db_tn = DB_TN_XMIT;
- } else if(strcmp(optarg, "netlink") == 0) {
- em_db_nl = -1L;
- } else if(strcmp(optarg, "xform") == 0) {
- em_db_xf = -1L;
- } else if(strcmp(optarg, "eroute") == 0) {
- em_db_er = -1L;
- } else if(strcmp(optarg, "spi") == 0) {
- em_db_sp = -1L;
- } else if(strcmp(optarg, "radij") == 0) {
- em_db_rj = -1L;
- } else if(strcmp(optarg, "esp") == 0) {
- em_db_es = -1L;
- } else if(strcmp(optarg, "ah") == 0) {
- em_db_ah = -1L;
- } else if(strcmp(optarg, "rcv") == 0) {
- em_db_rx = -1L;
- } else if(strcmp(optarg, "pfkey") == 0) {
- em_db_ky = -1L;
- } else if(strcmp(optarg, "comp") == 0) {
- em_db_gz = -1L;
- } else if(strcmp(optarg, "verbose") == 0) {
- em_db_vb = -1L;
- } else {
- usage(program_name);
- }
- em_db_nl |= 1 << (sizeof(em_db_nl) * 8 -1);
- break;
- case 'c':
- if(action) {
- fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
- program_name);
- exit(1);
- }
- em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1;
- em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1;
- em_db_gz=em_db_vb=-1;
-
- action = 'c';
- if(strcmp(optarg, "tunnel") == 0) {
- em_db_tn = 0;
- } else if(strcmp(optarg, "tunnel-xmit") == 0) {
- em_db_tn = ~DB_TN_XMIT;
- } else if(strcmp(optarg, "netlink") == 0) {
- em_db_nl = 0;
- } else if(strcmp(optarg, "xform") == 0) {
- em_db_xf = 0;
- } else if(strcmp(optarg, "eroute") == 0) {
- em_db_er = 0;
- } else if(strcmp(optarg, "spi") == 0) {
- em_db_sp = 0;
- } else if(strcmp(optarg, "radij") == 0) {
- em_db_rj = 0;
- } else if(strcmp(optarg, "esp") == 0) {
- em_db_es = 0;
- } else if(strcmp(optarg, "ah") == 0) {
- em_db_ah = 0;
- } else if(strcmp(optarg, "rcv") == 0) {
- em_db_rx = 0;
- } else if(strcmp(optarg, "pfkey") == 0) {
- em_db_ky = 0;
- } else if(strcmp(optarg, "comp") == 0) {
- em_db_gz = 0;
- } else if(strcmp(optarg, "verbose") == 0) {
- em_db_vb = 0;
- } else {
- usage(program_name);
- }
- em_db_nl &= ~(1 << (sizeof(em_db_nl) * 8 -1));
- break;
- case 'a':
- if(action) {
- fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
- program_name);
- exit(1);
- }
- action = 'a';
- em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1;
- em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1;
- em_db_gz=-1;
- em_db_vb= 0;
- break;
- case 'n':
- if(action) {
- fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n",
- program_name);
- exit(1);
- }
- action = 'n';
- em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0;
- em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0;
- em_db_gz=em_db_vb=0;
- break;
- case 'h':
- case '?':
- usage(program_name);
- exit(1);
- case 'v':
- fprintf(stdout, "klipsdebug (Linux FreeS/WAN %s) %s\n",
- ipsec_version_code(), klipsdebug_c_version);
- fputs(copyright, stdout);
- exit(0);
- case 'l':
- program_name = malloc(strlen(argv[0])
- + 10 /* update this when changing the sprintf() */
- + strlen(optarg));
- sprintf(program_name, "%s --label %s",
- argv[0],
- optarg);
- argcount -= 2;
- break;
- case '+': /* optionsfrom */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* no return on error */
- break;
- default:
- break;
- }
- previous = c;
- }
-
- if(argcount == 1) {
- system("cat /proc/net/ipsec_klipsdebug");
- exit(0);
- }
-
- if(!action) {
- usage(program_name);
- }
-
- if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
- fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",
- program_name);
- switch(errno) {
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENXIO:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case EAFNOSUPPORT:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- default:
- fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno);
- }
- exit(1);
- }
-
- pfkey_extensions_init(extensions);
-
- if((error = pfkey_msg_hdr_build(&extensions[0],
- SADB_X_DEBUG,
- 0,
- 0,
- ++pfkey_seq,
- getpid()))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
-
- if((error = pfkey_x_debug_build(&extensions[SADB_X_EXT_DEBUG],
- em_db_tn,
- em_db_nl,
- em_db_xf,
- em_db_er,
- em_db_sp,
- em_db_rj,
- em_db_es,
- em_db_ah,
- em_db_rx,
- em_db_ky,
- em_db_gz,
- em_db_vb))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
-
- if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
-
- if((error = write(pfkey_sock,
- pfkey_msg,
- pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
- (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
- fprintf(stderr,
- "%s: pfkey write failed, tried to write %u octets, returning %d with errno=%d.\n",
- program_name,
- (unsigned)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN),
- error,
- errno);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- switch(errno) {
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- fprintf(stderr, "No device?!?\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case ENXIO:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case ENOSPC:
- fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n");
- break;
- case ESPIPE:
- fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno);
- }
- exit(1);
- }
-
- if(pfkey_msg) {
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- }
-
- (void) close(pfkey_sock); /* close the socket */
- exit(0);
-}
diff --git a/programs/look/.cvsignore b/programs/look/.cvsignore
deleted file mode 100644
index 6f094f8d7..000000000
--- a/programs/look/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-look
diff --git a/programs/look/Makefile b/programs/look/Makefile
deleted file mode 100644
index e66ca60c1..000000000
--- a/programs/look/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=look
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/look/look.8 b/programs/look/look.8
deleted file mode 100644
index fc2d53eca..000000000
--- a/programs/look/look.8
+++ /dev/null
@@ -1,45 +0,0 @@
-.TH look 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: look.8,v 1.1 2004/03/15 20:35:28 as Exp $
-.\"
-.SH NAME
-ipsec look \- get a quick summary of FreeS/WAN status
-.SH SYNOPSIS
-.I look
-is used to get a quick overview of what the status of FreeSWAN is.
-It is equivalent to:
-\ \ \ ipsec eroute
-
-\ \ \ ipsec spigrp
-
-\ \ \ ipsec tncfg
-
-\ \ \ ipsec spi
-
-\ \ \ netstat -rn
-
-.LP
-However a bit of processing is done to combine the outputs.
-.SH "SEE ALSO"
-ipsec(8), ipsec_tncfg(8), ipsec_spi(8), ipsec_spigrp(8), ipsec_eroute(5),
-netstat(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program written by Henry Spencer.
-.\"
-.\" $Log: look.8,v $
-.\" Revision 1.1 2004/03/15 20:35:28 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.2 2002/04/29 22:39:31 mcr
-.\" added basic man page for all internal commands.
-.\"
-.\" Revision 1.1 2002/04/26 01:21:43 mcr
-.\" while tracking down a missing (not installed) /etc/ipsec.conf,
-.\" MCR has decided that it is not okay for each program subdir to have
-.\" some subset (determined with -f) of possible files.
-.\" Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-.\" Optional PROGRAM.5 files have been added to the makefiles.
-.\"
-.\"
-.\"
diff --git a/programs/look/look.in b/programs/look/look.in
deleted file mode 100755
index a5331c03b..000000000
--- a/programs/look/look.in
+++ /dev/null
@@ -1,87 +0,0 @@
-#! /bin/sh
-# quick look at current connections and related information
-# Copyright (C) 1998, 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: look.in,v 1.1 2004/03/15 20:35:28 as Exp $
-
-info=/var/run/ipsec.info
-me="ipsec look"
-
-case "$1" in
---help) echo "Usage: ipsec look" ; exit 0 ;;
---version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
-esac
-
-# clear out variables that have strange effects on sort etc.
-unset LANG LANGUAGE LC_ALL LC_MESSAGES
-
-# Pick up IPsec configuration etc.
-eval `ipsec _confread --varprefix IPSEC --optional --type config setup`
-if test " $IPSEC_confreadstatus" != " "
-then
- echo "$IPSEC_confreadstatus -- aborting" |
- logger -s -p daemon.error -t ipsec_look
- exit 1
-fi
-if test -s $info
-then
- . $info
-fi
-
-# label it just to be sure
-echo "`hostname` `date`"
-
-# combine spigrp and eroute
-cat /proc/net/ipsec_spigrp /proc/net/ipsec_eroute |
- awk '
- function pad(subnet) {
- sub("/", ".", subnet)
- split(subnet, d, ".")
- return sprintf("%03s%03s%03s%03s%03s", d[1], d[2],
- d[3], d[4], d[5])
- }
- $2 == "->" {
- printf "%s:%-18s -> %-18s => %s\n",
- (pad($1) pad($3)),
- $1, $3, (($5 in tun) ? tun[$5] : $5)
- next
- }
- $3 == "->" {
- printf "%s:%-18s -> %-18s => %s (%s)\n",
- (pad($2) pad($4)),
- $2, $4, (($6 in tun) ? tun[$6] : $6), $1
- next
- }
- { tun[$1] = $0 }
- ' | sort | sed 's/^[^:]*://'
-
-# tncfg (mostly as a divider line)
-egrep -v 'NULL[ \t]+mtu=0\(0\)[ \t]+->[ \t]+0' /proc/net/ipsec_tncfg |
- paste -d % | sed 's/%/ /g' | sed 's/ -> /->/g'
-
-# SAs
-sort /proc/net/ipsec_spi
-
-# relevant routing information, including header line (which is good
-# enough as a separator, no need for another bar)
-pat="^Dest"
-if test " $defaultroutephys" != " "
-then
- pat="$pat|$defaultroutephys\$|$defaultroutevirt\$"
-else
- for i in `echo "$IPSECinterfaces" | tr '=' ' '`
- do
- pat="$pat|$i\$"
- done
-fi
-netstat -nr | egrep "$pat" | sed '/^Dest/s/^/ /' | sort | sed '/^ Dest/s/ //'
diff --git a/programs/lwdnsq/.cvsignore b/programs/lwdnsq/.cvsignore
deleted file mode 100644
index b1ff942bf..000000000
--- a/programs/lwdnsq/.cvsignore
+++ /dev/null
@@ -1,4 +0,0 @@
-dnskey
-dnskey.cat8
-lwdnsq
-lwdnsq.xml
diff --git a/programs/lwdnsq/CONTRACT.txt b/programs/lwdnsq/CONTRACT.txt
deleted file mode 100644
index 77335e8cf..000000000
--- a/programs/lwdnsq/CONTRACT.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-The only delays are after START, and after CNAME.
-
-add the time to each line.
-
-put DNSSEC status on each line.
-
-The format of the replies is:
-
- <ID> <TIME> <TTL> <TYPE> <TYPE-SPECIFIC> \n
- ^- whitespace.
-
-ID is a unique number that identifies the transaction. It is determined
-by the caller. lwdnsq treats this ID as a string, and does nothing
-with it other than repeat it on each line.
-There is no predetermined bound on the length, but the total line
-length of input to lwdnsq must not exceed LWDNSQ_CMDBUF_LEN (1024).
-LWDNSQ_CMDBUF_LEN is defined in <freeswan.h>
-
-The output of lwdnsq is currently limited to LWDNSQ_RESULT_LEN_MAX (4096) byte
-lines. LWDNSQ_RESULT_LEN_MAX is defined in <freeswan.h>
-
-Time is a decimal encoded integer, currently 32-bit time (time_t) since Unix
-epoch. On systems with a 64-bit time_t, it would be 64-bit in range.
-
-The TTL field gives the number of seconds that the result is valid for.
-(starting at the time given). If there is no useful TTL value for the
-record, it will be either "0".
-
-Type is a case-insensitive, one of:
-structure
- START (optional comments) acknowledges start of transaction
- DONE (optional comments) signals the end of data for a transaction
-
-errors
- RETRY same as for FATAL, but this implies that the data
- was not found, but could be found later.
-
- FATAL Following this, is text detailing the fault,
- in a human readable form.
- "FATAL" results likely mean that the lwdnsq should
- be restarted.
-
- WARNING Log this result, but do not cancel transaction.
-
- Errors are still followed by "DONE".
-
-
-
-data answers
- DNSSEC followed by "OKAY" or "not present"
- NAME followed by canonical name for requested RR,
- i.e. the result of any CNAMEs/DNAMEs that were chased
- by the recursive resolving server.
- CNAME followed by the name which has been followed.
- CNAMEFROM the thing that was mapped
- TXT followed by RR-specific Presentation Format
- SIG "
- A "
- AAAA "
- PTR "
- KEY "
- AD-TXT followed by RR-specific Presentation Format - DNSSEC
- TXT followed by RR-specific Presentation Format - DNSSEC
- AD-KEY followed by RR-specific Presentation Format - DNSSEC
- KEY followed by RR-specific Presentation Format - DNSSEC
-
-If there is no data of the type requested, even after lwdnsq
-has attempted to follow CNAMEs, then there will be no resource
-records returned. This is the formal indication of the lack of
-the records, however, in addition, an error will be returned, of the type:
- RETRY the record "foobar" does not have a RR resource record.
-
-The -ldns library from bind9 will deal with the presentation format,
-producing a structure breakout from it. The functions are:
-
-dns_rdata_fromtext(3)
- Presentation Format -> Wire Format
-dns_rdata_tostruct(3)
- Wire Format -> C-structure
-
-dns_rdata_totext(3)
- Wire Format -> Presentation Format
-
-(Above from .../src/bind-9.3.0s20020722/lib/dns/include/dns/rdata.h)
-
-The lwdnsq program uses dns_rdata_totext(3) to format the resource record
-(received from lwres in wire format) into its presentation format.
-
-The documentation is in the bind-9.3 source tree, in the header files.
-(They are likely all installed into the include directories).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/programs/lwdnsq/Makefile b/programs/lwdnsq/Makefile
deleted file mode 100644
index 2fca5e249..000000000
--- a/programs/lwdnsq/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM:=lwdnsq
-
-OBJS:=cmds.o lookup.o
-
-LWRESINCL=${LWRESDIR}/include
-
-LIBS:=${FREESWANLIB} ${LWRESLIB} ${BIND9STATICLIBDIR}/libdns.a ${BIND9STATICLIBDIR}/libisc.a
-CFLAGS+=-I${LWRESINCL}
-#USERCOMPILE=-g
-
-
-include ../Makefile.program
-
-lwdnsq.8: lwdnsq.xml
- xmlto man lwdnsq.xml
-
-lwdnsq.xml: lwdnsq.xml.in
-
-TAGS:
- etags *.[ch] ../../lib/liblwres/*.[ch] ../../lib/liblwres/include/lwres/*.h
-
-# manually maintained dependancies
-lwdnsq.o: lwdnsq.c lwdnsq.h
-cmds.o: cmds.c lwdnsq.h
-lookup.o: lookup.c lwdnsq.h
-
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.9 2003/09/03 01:13:24 mcr
-# first attempt at async capable lwdnsq.
-#
-# Revision 1.8 2003/02/27 09:29:02 mcr
-# moved targets to after include file so that XML-conversion
-# does not occur by default.
-#
-# Revision 1.7 2003/02/01 01:36:53 mcr
-# updates to lwdnsq man page to reflect CONTRACT
-#
-# Revision 1.6 2003/01/14 03:01:14 dhr
-#
-# improve diagnostics; tidy
-#
-# Revision 1.5 2003/01/10 23:20:40 dhr
-#
-# remove reference to /sandel
-#
-# Revision 1.4 2002/12/19 05:45:47 mcr
-# use BIND9STATICLIBDIR to find -lisc/-ldns.
-#
-# Revision 1.3 2002/12/12 06:03:41 mcr
-# added --regress option to force times to be regular
-#
-# Revision 1.2 2002/12/04 03:21:06 mcr
-# DNS zone files (with signed versions) for DNSSEC enabled testing root.
-#
-# Revision 1.1 2002/10/30 02:25:31 mcr
-# renamed version of files from dnskey/
-#
-# Revision 1.4 2002/10/18 04:08:02 mcr
-# added -ldns and -lisc to libraries, but it isn't clear
-# where we will find these only-slightly standard libraries yet.
-#
-# Revision 1.3 2002/10/09 20:13:10 mcr
-# get appropriate LWRES include directory.
-#
-# Revision 1.2 2002/09/30 18:55:54 mcr
-# skeleton for dnskey helper program.
-#
-# Revision 1.1 2002/09/30 16:50:23 mcr
-# documentation for "dnskey" helper
-#
-#
-#
diff --git a/programs/lwdnsq/cmds.c b/programs/lwdnsq/cmds.c
deleted file mode 100644
index 1b15202ff..000000000
--- a/programs/lwdnsq/cmds.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * DNS KEY lookup helper - command implementation
- * Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <freeswan.h>
-
-#include <errno.h>
-#include <arpa/nameser.h>
-#include <lwres/netdb.h>
-#include <time.h>
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/types.h>
-#include <isc/result.h>
-#include <isc/mem.h>
-#include <isc/buffer.h>
-#include <isc/region.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <lwres/netdb.h>
-#include <lwres/async.h>
-
-
-#include "lwdnsq.h"
-
-static void cmd_not_implemented(dnskey_glob *gs, const char *what)
-{
- fprintf(gs->cmdproto_out, "0 FATAL unimplemented command \"%s\"\n", what);
-}
-
-void output_transaction_line(dnskey_glob *gs,
- char *id,
- int ttl,
- char *cmd,
- char *data)
-{
- time_t t;
-
- t=time(NULL);
-
- /* regularlize time for regression testing */
- if(gs->regress) {
- t=3145915;
- }
-
- if(data) {
- fprintf(gs->cmdproto_out,
- "%s %ld %d %s %s\n",
- id, t, ttl, cmd, data);
- } else {
- fprintf(gs->cmdproto_out,
- "%s %ld %d %s\n",
- id, t, ttl, cmd);
- }
-
-}
-
-void output_transaction_line_limited(dnskey_glob *gs,
- char *id,
- int ttl,
- char *cmd,
- int max,
- char *data)
-{
- time_t t;
-
- t=time(NULL);
-
- /* regularlize time for regression testing */
- if(gs->regress) {
- t=3145915;
- }
-
- fprintf(gs->cmdproto_out,
- "%s %ld %d %s %.*s\n",
- id, t, ttl, cmd, max, data);
-}
-
-
-#if 0
-again:
-
- lwres_getrrsetbyname_xmit(ctx, &las);
- timeout.tv_sec = lwres_async_timeout(ctx);
- sock = lwres_async_fd(ctx);
-
- FD_ZERO(&readfds);
- FD_SET(sock, &readfds);
- ret2 = select(sock + 1, &readfds, NULL, NULL, &timeout);
-
- /*
- * What happened with select?
- */
- if (ret2 < 0) {
- success = LWRES_R_IOERROR;
- goto out3;
- }
- if (ret2 == 0) {
- success = LWRES_R_TIMEOUT;
- goto out3;
- }
-
- out:
- if (ctx != NULL)
- lwres_context_destroy(&ctx);
-
- out2:
-
-#endif
-
-
-void lookup_key(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- char *id;
- char *fqdn;
- char simplebuf[80];
-
- /* process arguments */
- /* KEY 31459 east.uml.freeswan.org */
- if(argc!=3) {
- snprintf(simplebuf, sizeof(simplebuf), "wrong number of arguments %d", argc);
- output_transaction_line(gs, "0", 0, "FATAL", simplebuf);
- return;
- }
-
- id=argv[1];
- fqdn=argv[2];
-
- lookup_thing(gs, dns_rdatatype_key, "KEY", id, fqdn);
-}
-
-void lookup_key4(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "key4");
-}
-
-void lookup_key6(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "key6");
-}
-
-
-void lookup_txt(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- char *id;
- char *fqdn;
- char simplebuf[80];
-
- /* process arguments */
- /* KEY 31459 east.uml.freeswan.org */
- if(argc != 3) {
- snprintf(simplebuf, sizeof(simplebuf), "wrong number of arguments to TXT: %d", argc);
- output_transaction_line(gs, "0", 0, "FATAL", simplebuf);
- return;
- }
-
- id=argv[1];
- fqdn=argv[2];
-
- lookup_thing(gs, dns_rdatatype_txt, "TXT", id, fqdn);
-}
-
-void lookup_txt4(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- char *id;
- char *ipv4;
- struct in_addr in4;
- char simplebuf[80];
-
- /* process arguments */
- /* KEY 31459 east.uml.freeswan.org */
- if(argc != 3) {
- snprintf(simplebuf, sizeof(simplebuf), "wrong number of arguments to TXT: %d", argc);
- output_transaction_line(gs, "0", 0, "FATAL", simplebuf);
- return;
- }
-
- id=argv[1];
- ipv4=argv[2];
-
- if(inet_pton(AF_INET, ipv4, &in4) <= 0) {
- snprintf(simplebuf, sizeof(simplebuf), "invalid IPv4 address: %s", ipv4);
- output_transaction_line(gs, "0", 0, "FATAL", simplebuf);
- return;
- }
-
- snprintf(simplebuf, 80, "%d.%d.%d.%d.in-addr.arpa",
- in4.s_addr & 0xff,
- (in4.s_addr & 0xff00) >> 8,
- (in4.s_addr & 0xff0000) >> 16,
- (in4.s_addr & 0xff000000) >> 24);
-
- lookup_thing(gs, dns_rdatatype_txt, "TXT4", id, simplebuf);
-}
-
-void lookup_txt6(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "txt6");
-}
-
-void lookup_ipseckey(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "ipseckey");
-}
-
-void lookup_ipseckey4(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "ipseckey4");
-}
-
-void lookup_ipseckey6(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "ipseckey6");
-}
-
-void lookup_oe4(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "oe4");
-}
-
-void lookup_oe6(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "oe6");
-}
-
-void lookup_a(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "a");
-}
-
-void lookup_aaaa(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- cmd_not_implemented(gs, "aaaa");
-}
-
-
-
-
-
-
-/*
- * $Log: cmds.c,v $
- * Revision 1.1 2004/03/15 20:35:28 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.11 2003/09/03 01:13:24 mcr
- * first attempt at async capable lwdnsq.
- *
- * Revision 1.10 2003/05/22 16:33:51 mcr
- * added trailing . to CNAME return and cleaned up "CNAMEFROM" output.
- *
- * Revision 1.9 2003/05/14 15:47:39 mcr
- * processing of IP address into pieces was not done with
- * the right order of operations.
- *
- * Revision 1.8 2003/02/27 09:27:17 mcr
- * adjusted lwdnsq so that it adheres to contract - TXT records
- * are returned in a single piece. Requires custom decoding.
- * implemented "txt4" lookup type.
- *
- * Revision 1.7 2003/01/14 07:53:29 dhr
- *
- * - attempt to diagnose lack of lwdnsq
- * - increase too-small buffer size
- *
- * Revision 1.6 2003/01/14 03:01:14 dhr
- *
- * improve diagnostics; tidy
- *
- * Revision 1.5 2002/12/12 06:03:41 mcr
- * added --regress option to force times to be regular
- *
- * Revision 1.4 2002/11/25 18:37:28 mcr
- * added AD- marking of each record that was DNSSEC verified.
- *
- * Revision 1.3 2002/11/16 02:53:53 mcr
- * lwdnsq - with new contract added.
- *
- * Revision 1.2 2002/11/12 04:33:44 mcr
- * print DNSSEC status as we process CNAMEs.
- *
- * Revision 1.1 2002/10/30 02:25:31 mcr
- * renamed version of files from dnskey/
- *
- * Revision 1.4 2002/10/18 23:11:02 mcr
- * if we get ENOENT, then see if we can get a CNAME. If so, then
- * follow it.
- * Be careful when following them to avoid recursion.
- *
- * Revision 1.3 2002/10/18 04:08:47 mcr
- * use -ldns routines to decode lwres results and format them nicely.
- *
- * Revision 1.2 2002/10/09 20:13:34 mcr
- * first set of real code - lookup KEY records in forward.
- *
- * Revision 1.1 2002/09/30 18:55:54 mcr
- * skeleton for dnskey helper program.
- *
- * Revision 1.1 2002/09/30 16:50:23 mcr
- * documentation for "dnskey" helper
- *
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 2
- * End:
- *
- */
diff --git a/programs/lwdnsq/lookup.c b/programs/lwdnsq/lookup.c
deleted file mode 100644
index 700c4adbe..000000000
--- a/programs/lwdnsq/lookup.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * DNS KEY lookup helper
- * Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char lookup_c_version[] = "@(#) RCSID $Id: lookup.c,v 1.1 2004/03/15 20:35:28 as Exp $";
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <freeswan.h>
-
-#include <errno.h>
-#include <getopt.h>
-#include <setjmp.h>
-#include <ctype.h>
-#include <signal.h>
-
-#include <isc/mem.h>
-#include <isc/buffer.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <dns/name.h>
-#include <lwres/netdb.h>
-#include <lwres/async.h>
-#include "lwdnsq.h"
-
-static int lwresd_has_spoken = 0;
-
-char *xstrdup(const char *s)
-{
- char *n;
-
- n = strdup(s);
- if(n == NULL) {
- abort();
- }
- return n;
-}
-
-void free_dl(dnskey_glob *gs, dnskey_lookup *dl)
-{
- dnskey_lookup **walk;
-
- walk = &gs->dns_outstanding;
- while(*walk!=NULL && *walk != dl)
- {
- walk = &((*walk)->next);
- }
- if(*walk != NULL)
- {
- /* if we exit with it non-null, then we
- * found a matching location, remove
- * it.
- */
- *walk = dl->next;
- dl->next = NULL;
- }
- gs->dns_inflight--;
-
- if(dl->tracking_id) {
- free(dl->tracking_id);
- dl->tracking_id = NULL;
- }
- if(dl->wantedtype_name) {
- free(dl->wantedtype_name);
- dl->wantedtype_name = NULL;
- }
- if(dl->fqdn) {
- free(dl->fqdn);
- dl->fqdn = NULL;
- }
-#if 0
- if(dl->last_cname_used) {
- dns_name_free(&dl->last_cname, gs->iscmem);
- }
-#endif
-
- free(dl);
-}
-
-void lookup_thing(dnskey_glob *gs,
- dns_rdatatype_t wantedtype,
- char *wantedtype_name,
- char *id,
- char *fqdn)
-{
- isc_mem_t *iscmem;
- isc_buffer_t *iscbuf;
- int success;
- dnskey_lookup *dl;
-
- iscmem=NULL;
- iscbuf=NULL;
- dl = malloc(sizeof(*dl));
- memset(dl, 0, sizeof(*dl));
-
- dl->tracking_id = strdup(id);
- dl->step = dkl_start;
-
- output_transaction_line(gs, id, 0, "START", NULL);
-
- success = lwres_getrrsetbyname_init(fqdn, dns_rdataclass_in,
- wantedtype, 0 /*flags*/,
- gs->lwctx, &dl->las);
-
- if(success != ERRSET_SUCCESS) {
- /* screwed: */
- output_transaction_line(gs, id, 0, "FATAL", "isc buffer error");
- return;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- dl->step = dkl_first;
- dl->wantedtype = wantedtype;
- dl->wantedtype_name = xstrdup(wantedtype_name);
- dl->fqdn = xstrdup(fqdn);
- dl->tracking_id = xstrdup(id);
-
- /* link it in */
- dl->next = gs->dns_outstanding;
- gs->dns_outstanding = dl;
-
- gs->dns_inflight++;
-
- return;
-}
-
-
-int setup_follow_possible_cname(dnskey_glob *gs,
- dnskey_lookup *dl)
-{
- int ret;
-
- dl->cname_count++;
-
- /*
- * If we are on an odd cycle (starting with 1),
- * then convert to dns_name_t so that we can compare later.
- *
- * This detects loops in the CNAME processing, while still
- * allowing an arbitrary number of CNAMEs to be followed.
- */
- if(dl->cname_count & 1)
- {
- isc_buffer_t fqdn_src;
- isc_buffer_t *fqdn_dst;
-
- if(dl->cname_count == 1)
- {
- memset(&dl->last_cname, 0, sizeof(dl->last_cname));
- dns_name_init(&dl->last_cname, NULL);
- }
- else
- {
- dns_name_reset(&dl->last_cname);
- }
-
- fqdn_dst=NULL;
-
- isc_buffer_init(&fqdn_src, dl->fqdn, strlen(dl->fqdn));
- isc_buffer_add(&fqdn_src, strlen(dl->fqdn));
-
- isc_buffer_allocate(gs->iscmem, &fqdn_dst, strlen(dl->fqdn)+1);
-
-#if 0
- if(dl->last_cname_used) {
- dns_name_free(&dl->last_cname, gs->iscmem);
- }
-#endif
- dl->last_cname_used = 1;
- if(dns_name_fromtext(&dl->last_cname,
- &fqdn_src,
- NULL,
- 1,
- fqdn_dst) != ISC_R_SUCCESS) {
- return 0;
- }
-
- /* something else here ? */
- }
-
- ret = lwres_getrrsetbyname_init(dl->fqdn, dns_rdataclass_in,
- dns_rdatatype_cname, 0 /*flags*/,
- gs->lwctx,
- &dl->las);
-
- if(ret != ERRSET_SUCCESS) {
- return 0;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- return 1;
-}
-
-
-/*
- * we asked for, and got a CNAME of some kind.
- */
-void process_step_cname(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success)
-{
- struct rdatainfo *ri;
- isc_region_t region;
- dns_rdata_t rd;
- dns_rdata_cname_t cn;
- char simplebuf[80];
- isc_buffer_t *cname_text;
- char cname_buf[DNS_NAME_MAXTEXT];
- /* char cname_buf2[DNS_NAME_MAXTEXT]; */
-
- switch(success) {
- case ERRSET_NONAME:
- case ERRSET_NODATA:
- /* no, no CNAME found, thing isn't there */
- snprintf(simplebuf, sizeof(simplebuf),
- "RR of type %s for %s was not found (tried CNAMEs)",
- dl->wantedtype_name,
- dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY",
- simplebuf);
- dl->step = dkl_done;
- return;
-
- case 0:
- /* aha! found a CNAME */
- break;
-
- default:
- fatal:
- /* some other error */
- snprintf(simplebuf, sizeof(simplebuf), "err=%d", success);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- return;
- }
-
- /*
- * now process out the CNAMEs, and look them up, one by one...
- * there should be only one... We just use the first one that works.
- */
-
- if(ans->rri_flags & RRSET_VALIDATED) {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "OKAY");
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "not present");
- }
-
- if(ans->rri_nrdatas != 1) {
- /* we got a number of CNAMEs different from 1! */
- success=0;
- snprintf(simplebuf, sizeof(simplebuf), "illegal number of CNAMES: %d", ans->rri_nrdatas);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- return;
- }
-
- /* process first CNAME record */
- ri= &ans->rri_rdatas[0];
-
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dns_rdatatype_cname, &region);
-
- /* we set mctx to NULL, which means that the tenure for
- * the stuff pointed to by cn will persist only as long
- * as rd persists.
- */
- if(dns_rdata_tostruct(&rd, &cn, NULL) != ISC_R_SUCCESS) {
- /* failed, try next return error */
- success=0;
- goto fatal;
- }
-
- cname_text=NULL;
- if(isc_buffer_allocate(gs->iscmem, &cname_text, DNS_NAME_MAXTEXT)) {
- success=0;
- goto fatal;
- }
-
- if(dns_name_totext(&cn.cname, ISC_TRUE, cname_text) !=
- ISC_R_SUCCESS) {
- success=0;
- goto fatal;
- }
-
- cname_buf[0]='\0';
- strncat(cname_buf,
- isc_buffer_base(cname_text),
- isc_buffer_usedlength(cname_text));
-
- /* free up buffer */
- isc_buffer_free(&cname_text);
-
- {
- /* add a trailing . */
- char *end;
- end = &cname_buf[strlen(cname_buf)];
- if(*end != '.') {
- strncat(cname_buf, ".", sizeof(cname_buf));
- }
- }
-
- /* format out a text version */
- output_transaction_line(gs, dl->tracking_id, 0, "CNAME", cname_buf);
- output_transaction_line(gs, dl->tracking_id, 0, "CNAMEFROM", dl->fqdn);
-
- /* check for loops in the CNAMEs! */
- if(dns_name_equal(&dl->last_cname, &cn.cname) == ISC_TRUE) {
- /* damn, we found a loop! */
- dl->step = dkl_done;
- return;
- }
-
- /* send new request. */
- /* okay, so look this new thing up */
- success = lwres_getrrsetbyname_init(cname_buf, dns_rdataclass_in,
- dl->wantedtype, 0 /*flags*/,
- gs->lwctx, &dl->las);
-
- if(success != ERRSET_SUCCESS) {
- return;
- }
-
- lwres_getrrsetbyname_xmit(gs->lwctx, &dl->las);
-
- dl->step = dkl_second;
-}
-
-void process_step_first(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success,
- int attempt) /* attempt = 0 first time, 1 after cname */
-{
- char simplebuf[132], typebuf[16];
- char txtbuf[1024];
- int i;
-
- switch(success) {
- case ERRSET_NODATA:
- if(attempt == 0) {
- lwresd_has_spoken = 1;
- setup_follow_possible_cname(gs, dl);
- dl->step = dkl_cname;
- return;
- }
- /* FALLTHROUGH */
- case ERRSET_NONAME:
- lwresd_has_spoken = 1;
- snprintf(simplebuf, sizeof(simplebuf),
- "RR of type %s for %s was not found",
- dl->wantedtype_name,
- dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY",
- simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_NOMEMORY:
- snprintf(simplebuf, sizeof(simplebuf),
- "ran out of memory while looking up RR of type %s for %s",
- dl->wantedtype_name, dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_FAIL:
- snprintf(simplebuf, sizeof(simplebuf),
- "unspecified failure while looking up RR of type %s for %s%s",
- dl->wantedtype_name, dl->fqdn,
- lwresd_has_spoken ? "" : " (is lwresd running?)");
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- case ERRSET_INVAL:
- snprintf(simplebuf, sizeof(simplebuf),
- "invalid input while looking up RR of type %s for %s",
- dl->wantedtype_name, dl->fqdn);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY", simplebuf);
- dl->step = dkl_done;
- goto done;
-
- default:
- snprintf(simplebuf, sizeof(simplebuf), " unknown error %d", success);
- output_transaction_line(gs, dl->tracking_id, 0, "RETRY", simplebuf);
- dl->step = dkl_done;
- done:
- return;
-
- case 0:
- /* everything okay */
- lwresd_has_spoken = 1;
- dl->step = dkl_done;
- break;
- }
-
- /* output the rest of the data */
-
- if(ans->rri_flags & RRSET_VALIDATED) {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "OKAY");
- snprintf(typebuf, sizeof(typebuf), "AD-%s", dl->wantedtype_name);
- if(dl->wantedtype_name) free(dl->wantedtype_name);
- dl->wantedtype_name=xstrdup(typebuf);
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "DNSSEC", "not present");
- }
-
- output_transaction_line(gs, dl->tracking_id, 0, "NAME", ans->rri_name);
-
- for(i=0; i<ans->rri_nrdatas; i++) {
- struct rdatainfo *ri = &ans->rri_rdatas[i];
- isc_region_t region;
- dns_rdata_t rd;
-
- isc_buffer_clear(gs->iscbuf);
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- if(dl->wantedtype == dns_rdatatype_txt) {
- /* special treatment for TXT records */
- unsigned int len, rdatalen, totlen;
- unsigned char *txtp, *rdata;
-
- txtp = txtbuf;
- totlen = 0;
- rdatalen = ri->rdi_length;
- rdata = ri->rdi_data;
-
- while(rdatalen > 0) {
- len= (unsigned)rdata[0];
- memcpy(txtp, rdata+1, len);
- totlen += len;
- txtp += len;
- rdata += len+1;
- rdatalen -= len+1;
- }
- *txtp = '\0';
-
- output_transaction_line_limited(gs, dl->tracking_id, 0,
- dl->wantedtype_name,
- totlen, txtbuf);
-
- } else {
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dl->wantedtype, &region);
-
- if(dns_rdata_totext(&rd, NULL, gs->iscbuf) != ISC_R_SUCCESS) {
-
- }
-
- output_transaction_line_limited(gs, dl->tracking_id, 0,
- dl->wantedtype_name,
- (int)isc_buffer_usedlength(gs->iscbuf),
- (char *)isc_buffer_base(gs->iscbuf));
- }
- }
-
- for(i=0; i<ans->rri_nsigs; i++) {
- struct rdatainfo *ri = &ans->rri_sigs[i];
- isc_region_t region;
- dns_rdata_t rd;
-
- isc_buffer_clear(gs->iscbuf);
- memset(&region, 0, sizeof(region));
- memset(&rd, 0, sizeof(rd));
-
- region.base = ri->rdi_data;
- region.length = ri->rdi_length;
-
- dns_rdata_fromregion(&rd, dns_rdataclass_in,
- dns_rdatatype_sig, &region);
- if(dns_rdata_totext(&rd, NULL, gs->iscbuf) != ISC_R_SUCCESS) {
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", "isc totext error");
- return;
- }
-
- output_transaction_line_limited(gs, dl->tracking_id, 0, "SIG",
- (int)isc_buffer_usedlength(gs->iscbuf),
- (char *)isc_buffer_base(gs->iscbuf));
- }
-}
-
-
-
-void lookup_step(dnskey_glob *gs,
- dnskey_lookup *dl,
- struct rrsetinfo *ans,
- int success)
-{
- /* char simplebuf[80]; */
- int nextstate;
-
- nextstate = dkl_done;
-
- if(dl == NULL)
- {
- return;
- }
-
- switch(dl->step)
- {
- case dkl_start:
- /* first request done, why are still in this state? */
- break;
-
- case dkl_first:
- /* okay, got the reply from the first step! */
- process_step_first(gs, dl, ans, success, 0);
- nextstate = dl->step;
- break;
-
- case dkl_cname:
- /*
- * we asked for a cname, and we have some result to deal
- * with here.
- */
- process_step_cname(gs, dl, ans, success);
- nextstate = dl->step;
- break;
-
- case dkl_second:
- /*
- * we had asked for something, for a cname, and we followed
- * it, and we'll see what we got back.
- */
- process_step_first(gs, dl, ans, success, 1);
- nextstate = dl->step;
- break;
-
- case dkl_done:
- /* this should not happen, really, just book keeping, so,
- * just free up the structure, and return.
- */
- nextstate = dl->step;
- return;
- }
-
-
- /* we have been through, made a state transition, if we are
- * done, then do that.
- */
- if(nextstate == dkl_done)
- {
- output_transaction_line(gs, dl->tracking_id, 0, "DONE", NULL);
- free_dl(gs, dl);
- dl=NULL;
- }
- return;
-}
-
-void process_dns_reply(dnskey_glob *gs)
-{
- dnskey_lookup *dl;
- struct lwres_async_state *plas;
- struct rrsetinfo *res;
- int success;
-
- plas = NULL;
-
- success = lwres_getrrsetbyname_read(&plas, gs->lwctx, &res);
-
- /* cast answer back to dnskey_lookup structure */
- dl = (dnskey_lookup *)plas;
-
- if(success == LWRES_R_RETRY) {
- /* XXX we got something from some other weird place!
- * transmit again, in the hope of getting the right answer
- */
- dl->retry_count--;
- if(dl->retry_count > 0) {
- lwres_getrrsetbyname_xmit(gs->lwctx, plas);
- } else {
- output_transaction_line(gs, dl->tracking_id, 0, "FATAL", "too many retries");
- free_dl(gs, dl);
- }
- return;
- }
-
- /* perform next step for this one */
- lookup_step(gs, dl, res, success);
-}
-
-/*
- * $Log: lookup.c,v $
- * Revision 1.1 2004/03/15 20:35:28 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.3 2003/09/18 02:17:39 mcr
- * if we have tried a CNAME lookup, then take a NODATA
- * reply as a no-name.
- *
- * Revision 1.2 2003/09/10 17:55:14 mcr
- * the CNAME message had the s removed, which changes test
- * results gratuitously.
- *
- * Revision 1.1 2003/09/03 01:13:24 mcr
- * first attempt at async capable lwdnsq.
- *
- *
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 2
- * End:
- *
- */
diff --git a/programs/lwdnsq/lwdnsq.8 b/programs/lwdnsq/lwdnsq.8
deleted file mode 100644
index bb07985f2..000000000
--- a/programs/lwdnsq/lwdnsq.8
+++ /dev/null
@@ -1,250 +0,0 @@
-.\"Generated by db2man.xsl. Don't modify this, modify the source.
-.de Sh \" Subsection
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp \" Vertical space (when we can't use .PP)
-.if t .sp .5v
-.if n .sp
-..
-.de Ip \" List item
-.br
-.ie \\n(.$>=3 .ne \\$3
-.el .ne 3
-.IP "\\$1" \\$2
-..
-.TH "IPSEC LWDNSQ" 8 "" "" ""
-.SH NAME
-lwdnsq \- lookup items in DNS to help pluto (and others)
-.SH "SYNOPSIS"
-
-.nf
-\fBipsec lwdnsq\fR lwdnsq\fR [\fB\-\-prompt\fR] [\fB\-\-serial\fR]
-.fi
-
-.nf
-\fBipsec lwdnsq\fR lwdnsq\fR [\fB\-\-help\fR]
-.fi
-
-.SH "DESCRIPTION"
-
-.PP
-The \fBipsec lwdnsq\fR is a helper program that does DNS lookups for other programs. It implements an asynchronous interface on stdin/stdout, with an ASCII driven command language.
-
-.PP
-If stdin is a tty or if the \fB\-\-prompt\fR option is given, then it issues a prompt to the user. Otherwise, it is silent, except for results.
-
-.PP
-The program will accept multiple queries concurrently, with each result being marked with the ID provided on the output. The IDs are strings.
-
-.PP
-If the \fB\-\-serial\fR option is given, then the program will not attempt to execute concurrent queries, but will serialize all input and output.
-
-.SH "QUERY LANGUAGE"
-
-.PP
-There are eleven command that the program understands. This is to lookup different types of records in both the forward and reverse maps. Every query includes a queryid, which is returned in the output, on every single line to identify the transaction.
-
-.SS "KEY queryid FQDN"
-
-.PP
-This request looks up the KEY resource record for the given \fBFQDN.\fR.
-
-.SS "KEY4 queryid A.B.C.D"
-
-.PP
-This request looks up the KEY resource record found in the reverse map for the IP version 4 address \fBA.B.C.D\fR, i.e. it looks up D.C.B.A.in\-addr.arpa.
-
-.SS "KEY6 queryid A:B::C:D"
-
-.PP
-This request looks up the KEY resource record found in the reverse map for the IPv6 address \fBA:B::C:D\fR, i.e. it looks the 32\-nibble long entry in ip6.arpa (and ip6.int).
-
-.SS "TXT4 queryid A.B.C.D"
-
-.PP
-This request looks up the TXT resource record found in the reverse map for the IP version 4 address \fBA.B.C.D\fR, i.e. it looks up D.C.B.A.in\-addr.arpa.
-
-.SS "TXT6 queryid A:B::C:D"
-
-.PP
-This request looks up the TXT resource record found in the reverse map for the IPv6 address \fBA:B::C:D\fR, i.e. it looks the 32\-nibble long entry in ip6.arpa (and ip6.int).
-
-.SS "KEY queryid FQDN"
-
-.PP
-This request looks up the IPSECKEY resource record for the given \fBFQDN.\fR. See note about IPSECKEY processing, below.
-
-.SS "IPSECKEY4 queryid A.B.C.D"
-
-.PP
-This request looks up the IPSECKEY resource record found in the reverse map for the IP version 4 address \fBA.B.C.D\fR, i.e. it looks up D.C.B.A.in\-addr.arpa. See special note about IPSECKEY processing, below.
-
-.SS "IPSECKEY6 queryid A:B::C:D"
-
-.PP
-This request looks up the IPSECKEY resource record found in the reverse map for the IPv6 address \fBA:B::C:D\fR, i.e. it looks the 32\-nibble long entry in ip6.arpa (and ip6.int). See special note about IPSECKEY processing, below.
-
-.SS "OE4 queryid A.B.C.D"
-
-.PP
-This request looks an appropriate record for Opportunistic Encryption for the given IP address. This attempts to look for the delegation record. This may be one of IPSECKEY, KEY, or TXT record. Unless configured otherwise, (see OE4 Directives, below), then a query type of ANY will be used to retrieve all relevant records, and all will be returned.
-
-.SS "OE6 queryid A:B::C:D"
-
-.PP
-This request looks an appropriate record for Opportunistic Encryption for the given IPv6 address. This attempts to look for the delegation record. This may be one of IPSECKEY, KEY, or TXT record. Unless configured otherwise, (see OE Directives, below), then a query type of ALL will be used to retrieve all relevant records, and all will be returned. i.e. it looks the 32\-nibble long entry in ip6.arpa (and ip6.int).
-
-.SS "A queryid FQDN"
-
-.PP
-This request looks up the A (IPv4) resource record for the given \fBFQDN.\fR.
-
-.SS "AAAA queryid FQDN"
-
-.PP
-This request looks up the AAAA (IPv6) resource record for the given \fBFQDN.\fR.
-
-.SH "REPLIES TO QUERIES"
-
-.PP
-All replies from the queries are in the following format:
-
-.nf
-
-<ID> <TIME> <TTL> <TYPE> <TYPE\-SPECIFIC> \\n
-
-.fi
-
-
-.TP
-\fIID\fR
-this is the \fBqueryid\fR value that was provided in the query. It is repeated on every line to permit the replies to be properly associated with the query. When the response is not ascribable to particular query (such as for a mis\-formed query), then the query ID "0" will be used.
-
-.TP
-\fITIME\fR
-this is the current time in seconds since epoch.
-
-.TP
-\fITTL\fR
-for answers which have a time to live, this is the current value. The answer is valid for this number of seconds. If there is no useful value here, then the number 0 is used.
-
-.TP
-\fITYPE\fR
-This is the type of the record that is being returned. The types are described in the next section. The TYPE specific data that follows is specific to the type.
-
-
-.PP
-The replies are limited to 4096 bytes, a value defined as \fBLWDNSQ_RESULT_LEN_MAX\fR. This is defined in \fIfreeswan.h\fR.
-
-.PP
-All of the replies which include resource records use the standard presentation format (with no line feeds or carriage returns) in their answer.
-
-.SS "START"
-
-.PP
-This reply indicates that a query has been received and has been started. It serves as an anchor point for timing, as well as an acknowledgement.
-
-.SS "DONE"
-
-.PP
-This reply indicates that a query is entirely over, and no further information from this query will be sent.
-
-.SS "RETRY"
-
-.PP
-This reply indicates that a query is entirely over, but that no data was found. The records may exist, but appropriate servers could not be reached.
-
-.SS "FATAL"
-
-.PP
-This reply indicates that a query is entirely over, and that no data of the type requested could be found. There were no timeouts, and all servers were available and confirmed non\-existances. There may be NXT records returned prior to this.
-
-.SS "CNAME"
-
-.PP
-This is an interim reply, and indicates that a CNAME was found (and followed) while performing the query. The value of the CNAME is present in the type specific section.
-
-.SS "CNAMEFROM"
-
-.PP
-This is an interim reply, and indicates that a CNAME was found. The original name that was queries for was not the canonical name, and this reply indicates the name that was actually followed.
-
-.SS "NAME"
-
-.PP
-This is an interim reply. The original name that was queries for was not the canonical name. This reply indicates the canonical name.
-
-.SS "DNSSEC"
-
-.PP
-This is an interim reply. It is followed either by "OKAY" or "not present. It indicates if DNSSEC was available on the reply.
-
-.SS "TXT and AD-TXT"
-
-.PP
-This is an interim reply. If there are TXT resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SS "A and AD-A"
-
-.PP
-This is an interim reply. If there are A resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SS "AAAA and AD-AAAA"
-
-.PP
-This is an interim reply. If there are AAAA resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SS "PTR and AD-PTR"
-
-.PP
-This is an interim reply. If there are PTR resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SS "KEY and AD-KEY"
-
-.PP
-This is an interim reply. If there are KEY resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SS "IPSECKEY and AD-IPSECKEY"
-
-.PP
-This is an interim reply. If there are IPSEC resource records in the reply, then each one is presented using this type. If preceeded by AD\-, then this record was signed with DNSSEC.
-
-.SH "SPECIAL IPSECKEY PROCESSING"
-
-.PP
-At the time of this writing, the IPSECKEY resource record is not entirely specified. In particular no resource record number has been assigned. This program assumes that it is resource record number 45. If the file /etc/ipsec.d/lwdnsq.conf exists, and contains a line like
-
-.nf
-
-ipseckey_rr=\fBnumber\fR
-
-.fi
- then this number will be used instead. The file is read only once at startup.
-
-.SH "OE DIRECTIVES"
-
-.PP
-If the file /etc/ipsec.d/lwdnsq.conf exists, and contains a line like
-
-.nf
-
-queryany=false
-
-.fi
- then instead of doing an ALL query when looking for OE delegation records, lwdnsq will do a series of queries. It will first look for IPSECKEY, and then TXT record. If it finds neither, it will then look for KEY records of all kinds, although they do not contain delegation information.
-
-.SH "SPECIAL IPSECKEY PROCESSING"
-
-.nf
-
-/etc/ipsec.d/lwdnsq.conf
-
-.fi
-
-.SH AUTHOR
-Michael Richardson <mcr@sandelman.ottawa.on.ca>.
diff --git a/programs/lwdnsq/lwdnsq.c b/programs/lwdnsq/lwdnsq.c
deleted file mode 100644
index 2684a7d45..000000000
--- a/programs/lwdnsq/lwdnsq.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * DNS KEY lookup helper
- * Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char tncfg_c_version[] = "RCSID $Id: lwdnsq.c,v 1.1 2004/03/15 20:35:28 as Exp $";
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <freeswan.h>
-
-#include <errno.h>
-#include <getopt.h>
-#include <setjmp.h>
-#include <ctype.h>
-#include <signal.h>
-
-#include <isc/lang.h>
-#include <isc/magic.h>
-#include <isc/types.h>
-#include <isc/result.h>
-#include <isc/mem.h>
-#include <isc/buffer.h>
-#include <isc/region.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
-#include <lwres/netdb.h>
-#include <lwres/async.h>
-
-#include "lwdnsq.h"
-
-static void
-usage(char *name)
-{
- fprintf(stdout,"%s --attach --virtual <virtual-device> --physical <physical-device>\n",
- name);
- exit(1);
-}
-
-static struct option const longopts[] =
-{
- {"prompt", 0, 0, 'i'},
- {"serial", 0, 0, 's'},
- {"debug", 0, 0, 'g'},
- {"regress",0, 0, 'X'},
- {"ignoreeof",0, 0, 'Z'},
- {0, 0, 0, 0}
-};
-
-/* globals */
-jmp_buf getMeOut;
-
-void sig_handler(int sig)
-{
- fprintf(stderr, "Caught signal %d, cleaning up and exiting\n", sig);
- longjmp(getMeOut, 1);
-}
-
-void cmdprompt(dnskey_glob *gs)
-{
- if(gs->prompt) {
- printf("lwdnsq> ");
- }
- fflush(gs->cmdproto_out);
-}
-
-void quitprog(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- gs->done=1;
-}
-
-void setdebug(dnskey_glob *gs,
- int argc,
- char **argv)
-{
- if(argc > 1) {
- gs->debug=strtoul(argv[1],NULL,0);
- }
- printf("0 DEBUG is %d\n",gs->debug);
-}
-
-
-int cmdparse(dnskey_glob *gs,
- char *cmdline)
-{
- char *argv[256];
- int argc;
- char *arg;
- static const struct cmd_entry {
- const char *cmdname;
- void (*cmdfunc)(dnskey_glob *, int, char **);
- } cmds[]={
- {"key", lookup_key},
- {"key4", lookup_key4},
- {"key6", lookup_key6},
- {"txt", lookup_txt},
- {"txt4", lookup_txt4},
- {"txt6", lookup_txt6},
- {"ipseckey", lookup_ipseckey},
- {"ipseckey4", lookup_ipseckey4},
- {"ipseckey6", lookup_ipseckey6},
- {"oe4", lookup_oe4},
- {"oe6", lookup_oe6},
- {"vpn4", lookup_key4},
- {"vpn6", lookup_key6},
- {"quit", quitprog},
- {"a", lookup_a},
- {"aaaa", lookup_aaaa},
- {"debug", setdebug},
- {NULL, NULL}};
- const struct cmd_entry *ce = cmds;
-
- argc=0;
-
- /* skip initial spaces */
- while(cmdline && isspace(*cmdline)) {
- cmdline++;
- }
-
- while(cmdline && *cmdline!='\0' &&
- (arg=strsep(&cmdline, " \t\n"))!=NULL) {
- if (argc < sizeof(argv)/sizeof(*argv - 1)) {
- /* ignore arguments that would overflow.
- * XXX should generate a diagnostic.
- */
- argv[argc++]=arg;
- }
- while(cmdline && isspace(*cmdline)) {
- cmdline++;
- }
- }
- argv[argc]=NULL;
-
- if(argc==0 || argv[0][0]=='\0') {
- /* ignore empty line */
- } else if(strcasecmp("help", argv[0]) == 0) {
- fprintf(gs->cmdproto_out, "0 HELP\n");
- for (; ce->cmdname != NULL; ce++)
- fprintf(gs->cmdproto_out, "0 HELP %s\n", ce->cmdname);
- } else {
- for (;; ce++) {
- if (ce->cmdname == NULL) {
- fprintf(gs->cmdproto_out, "0 FATAL unknown command \"%s\"\n", argv[0]);
- break;
- }
- if(strcasecmp(ce->cmdname, argv[0])==0) {
- (*ce->cmdfunc)(gs, argc, argv);
- break;
- }
- }
- }
-
- if (!gs->done)
- cmdprompt(gs);
- return 0;
-}
-
-int cmdread(dnskey_glob *gs,
- char *buf,
- int len)
-{
- unsigned char *nl;
- int cmdlen;
-
- cmdlen=0;
-
- /*
- * have to handle partial reads and multiple commands
- * per read, since this may in fact be a file or a pipe.
- */
- if((gs->cmdloc + len + 1) > sizeof(gs->cmdbuf)) {
- fprintf(stderr, "command '%.*s...' is too long, discarding!\n",
- 40, buf);
- fflush(stdout);
-
- gs->cmdloc=0;
- return 0;
- }
- memcpy(gs->cmdbuf+gs->cmdloc, buf, len);
- gs->cmdloc+=len;
- gs->cmdbuf[gs->cmdloc]='\0';
-
- while((nl = strchr(gs->cmdbuf, '\n')) != NULL) {
- /* found a newline, so turn it into a \0, and process the
- * command, and then we will pull the rest of the buffer
- * up.
- */
- *nl='\0';
- cmdlen= nl - gs->cmdbuf +1;
-
- cmdparse(gs, gs->cmdbuf);
-
- gs->cmdloc -= cmdlen;
- memmove(gs->cmdbuf, gs->cmdbuf+cmdlen, gs->cmdloc);
- }
- return 1;
-}
-
-int
-main(int argc, char *argv[])
-{
- char *program_name;
- dnskey_glob gs;
- int c;
- static int ignoreeof=0; /* static to avoid longjmp clobber */
- int ineof;
-
- memset(&gs, 0, sizeof(dnskey_glob));
-
-#if 0
- printf("PID: %d\n", getpid());
- sleep(60);
-#endif
-
- program_name = argv[0];
- gs.concurrent = 1;
-
- if(lwres_async_init(&gs.lwctx) != ERRSET_SUCCESS) {
- fprintf(stderr, "Can not initialize async context\n");
- exit(3);
- }
-
- if(isc_mem_create(0,0,&gs.iscmem) != ISC_R_SUCCESS) {
- fprintf(stderr, "Can not initialize isc memory allocator\n");
- exit(4);
- }
-
- if(isc_buffer_allocate(gs.iscmem, &gs.iscbuf, LWDNSQ_RESULT_LEN_MAX)) {
- fprintf(stderr, "Can not allocate a result buffer\n");
- exit(5);
- }
-
- while((c = getopt_long_only(argc, argv, "dgsiXZ", longopts, 0)) != EOF) {
- switch(c) {
- case 'd':
- gs.debug+=2;
- break;
-
- case 'g':
- gs.debug++;
- break;
- case 's':
- gs.concurrent=0;
- break;
- case 'i':
- gs.prompt=1;
- break;
- case 'X':
- gs.regress++;
- break;
-
- case 'Z':
- ignoreeof=1;
- break;
-
- default:
- usage(program_name);
- break;
- }
- }
-
- if(gs.debug && ignoreeof) {
- fprintf(stderr, "Ignoring end of file\n");
- }
-
- if(isatty(0)) {
- gs.prompt=1;
- }
-
- /* do various bits of setup */
- if(setjmp(getMeOut)!=0) {
- signal(SIGINT, SIG_DFL);
- signal(SIGPIPE, SIG_IGN);
-
- /* cleanup_crap(); */
-
- exit(1);
- }
-
- if(signal(SIGINT, sig_handler) < 0)
- perror("Setting handler for SIGINT");
-
- if(signal(SIGPIPE, sig_handler) < 0)
- perror("Setting handler for SIGINT");
-
- cmdprompt(&gs);
-
- ineof = 0;
- gs.done = 0;
- gs.cmdproto_out = stdout;
- gs.l_fds[0].events = POLLIN|POLLHUP;
- gs.l_fds[0].fd=0;
-
- gs.l_fds[1].events = POLLIN|POLLHUP|POLLERR;
- gs.l_fds[1].fd = lwres_async_fd(gs.lwctx);
-
- gs.l_nfds= 2;
-
- while(!gs.done)
- {
- int timeout;
- char buf[128];
- int n;
- int rlen;
-
- timeout=-1;
-
- gs.l_fds[0].revents = 0;
-
- gs.l_fds[1].events = POLLIN|POLLHUP|POLLERR;
- gs.l_fds[1].revents = 0;
- gs.l_fds[1].fd = lwres_async_fd(gs.lwctx);
-
- if(gs.debug > 1) {
- fprintf(stderr, "=== invoking poll(,%d,) with %s\n",
- gs.l_nfds,
- timeout>0 ? "waittime" : "no wait");
- for(n = 0; n < gs.l_nfds; n++) {
- fprintf(stderr, "=== waiting on fd#%d\n",
- gs.l_fds[n].fd);
- }
- fprintf(stderr, "=== inflight: %d\n", gs.dns_inflight);
- }
-
- n = poll(gs.l_fds, gs.l_nfds, timeout);
-
- if(n == 0) {
- /* timeout! */
- }
-
- if(n < 0) {
- perror("poll");
- }
-
- if(gs.debug > 1) {
- fprintf(stderr, "=== poll returned with %d\n", n);
- }
-
- while(n>0) {
- if((gs.l_fds[0].revents & POLLERR) == POLLERR ||
- (gs.l_fds[1].revents & POLLERR) == POLLERR)
- {
- break;
- }
-
- /* see if there are DNS events coming back */
- if((gs.l_fds[1].revents & POLLIN) == POLLIN) {
- if(gs.debug > 1) {
- fprintf(stderr,
- "=== new responses from lwdnsd\n");
- }
-
- process_dns_reply(&gs);
- fflush(stdout);
- n--;
- }
-
- if(!ignoreeof &&
- (gs.l_fds[0].revents & POLLHUP) == POLLHUP)
- {
- break;
- }
-
- if((gs.l_fds[0].revents & POLLIN) == POLLIN) {
-
- rlen=read(0, buf, sizeof(buf));
-
- if(gs.debug > 1) {
- if(rlen > 0) {
- buf[rlen]='\0';
- }
- fprintf(stderr,
- "=== new commands on fd 0: %d: %s\n",
- rlen, buf);
- }
-
- if(rlen > 0) {
- cmdread(&gs, buf, rlen);
- } else if(rlen == 0) {
- ineof = 1;
- if(!ignoreeof) {
- /* EOF, die */
- gs.done=1;
- }
- }
- n--;
- }
-
- }
-
- if((gs.l_fds[0].revents & POLLHUP) == POLLHUP)
- {
- ineof = 1;
- if(!ignoreeof)
- {
- gs.done=1;
- }
- }
-
- if(ignoreeof) {
- /* if we have exhausted the input,
- * and there are none in flight,
- * then exit, finally.
- */
- if(ineof) {
- if(gs.dns_inflight == 0) {
- gs.done=1;
- }
- }
- }
-
- if(gs.debug) {
- fprintf(stderr, "=== ineof: %d inflight: %d\n",
- ineof, gs.dns_inflight);
- }
-
- }
-
- signal(SIGINT, SIG_DFL);
- signal(SIGPIPE, SIG_IGN);
-
- exit(0);
-}
-
-/*
- * $Log: lwdnsq.c,v $
- * Revision 1.1 2004/03/15 20:35:28 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.12 2003/09/16 05:01:14 mcr
- * prefix all debugging with === so that it can be easily removed.
- *
- * Revision 1.11 2003/09/10 04:43:52 mcr
- * final fixes to lwdnsq to exit only when all requests are done,
- * and we have been told to wait, *OR* if there is an EOF in stdin.
- *
- * Revision 1.10 2003/09/03 01:13:24 mcr
- * first attempt at async capable lwdnsq.
- *
- * Revision 1.9 2003/04/02 07:37:57 dhr
- *
- * lwdnsq: fix non-deterministic bug in handling batched input
- *
- * Revision 1.8 2003/02/08 04:03:06 mcr
- * renamed --single to --serial.
- *
- * Revision 1.7 2003/01/14 03:01:14 dhr
- *
- * improve diagnostics; tidy
- *
- * Revision 1.6 2002/12/19 07:29:47 dhr
- *
- * - avoid (improbable) buffer overflow
- * - suppress prompt after "quit" command
- * - add space to prompt to match aesthetics and man page
- * - elminate a magic number
- *
- * Revision 1.5 2002/12/19 07:08:42 dhr
- *
- * continue renaming dnskey => lwdnsq
- *
- * Revision 1.4 2002/12/12 06:03:41 mcr
- * added --regress option to force times to be regular
- *
- * Revision 1.3 2002/11/25 18:37:48 mcr
- * make sure that we exit cleanly upon EOF.
- *
- * Revision 1.2 2002/11/16 02:53:53 mcr
- * lwdnsq - with new contract added.
- *
- * Revision 1.1 2002/10/30 02:25:31 mcr
- * renamed version of files from dnskey/
- *
- * Revision 1.3 2002/10/09 20:14:16 mcr
- * make sure to flush stdout at the right time - do it regardless
- * of whether or not we are printing prompts.
- *
- * Revision 1.2 2002/09/30 18:55:54 mcr
- * skeleton for dnskey helper program.
- *
- * Revision 1.1 2002/09/30 16:50:23 mcr
- * documentation for "dnskey" helper
- *
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 2
- * End:
- *
- */
diff --git a/programs/lwdnsq/lwdnsq.h b/programs/lwdnsq/lwdnsq.h
deleted file mode 100644
index 109b39507..000000000
--- a/programs/lwdnsq/lwdnsq.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * DNS KEY lookup global definitions
- * Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef POLLIN
-#include <poll.h>
-#endif
-
-#include "freeswan.h"
-
-/*
- * a base-64 encoded 2192 bit key takes:
- * 2192/8 * 4/3 = 365 bytes.
- *
- * a base-64 encoded 16384 bit key takes:
- * 16384/8*4/3 = 2730 bytes.
- *
- * so, we pick 4096 bytes as the maximum.
- *
- * Note that TXT records may have an introducer (X-IPsec) and an ID which
- * is either an IP address or @FQDN that preceeds the base64 encoded key.
- *
- */
-
-enum dkl_state {
- dkl_start, /* no work yet none - initial state */
- dkl_first, /* sent first DNS request. */
- dkl_cname, /* sent request for CNAME record */
- dkl_second, /* sent request for thing CNAME pointed to */
- dkl_done /* done */
-};
-
-typedef struct dnskey_lookup dnskey_lookup;
-
-struct dnskey_lookup {
- struct lwres_async_state las;
- dnskey_lookup *next;
- char *tracking_id;
- enum dkl_state step;
- /* lwres_context_t *ctx; */
- char *wantedtype_name;
- dns_rdatatype_t wantedtype;
- char *fqdn;
- int cname_count;
- int last_cname_used;
- dns_name_t last_cname;
- int retry_count;
-};
-
-typedef struct dnskey_glob {
- int debug;
- int prompt;
- int concurrent;
- int done;
- int regress; /* if 1, then we are doing regression testing */
- struct pollfd l_fds[5]; /* array of input sources */
- int l_nfds; /* number of relevant entries */
- int cmdloc;
- unsigned char cmdbuf[LWDNSQ_CMDBUF_LEN];
- FILE *cmdproto_out;
- dnskey_lookup *dns_outstanding;
- int dns_inflight;
- lwres_context_t *lwctx;
- isc_mem_t *iscmem;
- isc_buffer_t *iscbuf;
-} dnskey_glob;
-
-/* in cmds.c */
-extern void lookup_key(dnskey_glob *gs,int, char **);
-extern void lookup_key4(dnskey_glob *gs,int, char **);
-extern void lookup_key6(dnskey_glob *gs,int, char **);
-extern void lookup_txt(dnskey_glob *gs,int, char **);
-extern void lookup_txt4(dnskey_glob *gs,int, char **);
-extern void lookup_txt6(dnskey_glob *gs,int, char **);
-extern void lookup_ipseckey(dnskey_glob *gs,int, char **);
-extern void lookup_ipseckey4(dnskey_glob *gs,int, char **);
-extern void lookup_ipseckey6(dnskey_glob *gs,int, char **);
-extern void lookup_oe4(dnskey_glob *gs,int, char **);
-extern void lookup_oe6(dnskey_glob *gs,int, char **);
-extern void lookup_a(dnskey_glob *gs,int, char **);
-extern void lookup_aaaa(dnskey_glob *gs,int, char **);
-extern void output_transaction_line(dnskey_glob *gs,
- char *id,
- int ttl,
- char *cmd,
- char *data);
-extern void output_transaction_line_limited(dnskey_glob *gs,
- char *id,
- int ttl,
- char *cmd,
- int max,
- char *data);
-
-
-/* lookup code */
-extern void process_dns_reply(dnskey_glob *gs);
-extern void lookup_thing(dnskey_glob *gs,
- dns_rdatatype_t wantedtype,
- char *wantedtype_name,
- char *id,
- char *fqdn);
-
-/*
- *
- * Local variables:
- * c-file-style: "linux"
- * c-basic-offset: 2
- * End:
- *
- */
diff --git a/programs/lwdnsq/lwdnsq.xml.in b/programs/lwdnsq/lwdnsq.xml.in
deleted file mode 100644
index 4c4039120..000000000
--- a/programs/lwdnsq/lwdnsq.xml.in
+++ /dev/null
@@ -1,446 +0,0 @@
-<?xml version='1.0'?> <!-- -*- docbook -*- -->
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<article>
- <articleinfo>
- <title>lwdnsq</title>
-
- <author>
- <firstname>Michael</firstname>
- <surname>Richardson</surname>
- <affiliation>
- <address><email>mcr@sandelman.ottawa.on.ca</email></address>
- </affiliation>
- </author>
-
- <copyright>
- <year>2003</year>
- <holder>Michael Richardson</holder>
- </copyright>
- </articleinfo>
-
- <section>
- <title>Reference</title>
-
-<refentry id="ipsec_lwdnsq">
-
-<refmeta>
-<refentrytitle>ipsec lwdnsq</refentrytitle>
-<manvolnum>8</manvolnum>
-</refmeta>
-
-<refnamediv>
-<refname>lwdnsq</refname>
-<refpurpose>lookup items in DNS to help pluto (and others)</refpurpose>
-</refnamediv>
-
-<refsynopsisdiv>
-
-<cmdsynopsis>
- <command>ipsec lwdnsq</command>
- <arg choice="opt"><option>--prompt</option></arg>
- <arg choice="opt"><option>--serial</option></arg>
-</cmdsynopsis>
-
-<cmdsynopsis>
- <command>ipsec lwdnsq</command>
- <arg choice="opt"><option>--help</option></arg>
-</cmdsynopsis>
-
-</refsynopsisdiv>
-
-<refsect1><title>Description</title>
-<para>
-The
-<command>ipsec lwdnsq</command>
-is a helper program that does DNS lookups for other programs. It implements
-an asynchronous interface on stdin/stdout, with an ASCII driven command
-language.
-</para>
-
-<para>
-If stdin is a tty or if the
-<option>--prompt</option>
-option is given, then it issues a prompt to the user. Otherwise, it is
-silent, except for results.
-</para>
-
-<para>
-The program will accept multiple queries concurrently, with each result
-being marked with the ID provided on the output. The IDs are strings.
-</para>
-
-<para>
-If the
-<option>--serial</option>
-option is given, then the program will not attempt to execute concurrent
-queries, but will serialize all input and output.
-</para>
-
-</refsect1>
-
-<refsect1><title>QUERY LANGUAGE</title>
-
-<para>
-There are eleven command that the program understands. This is to lookup
-different types of records in both the forward and reverse maps. Every query
-includes a queryid, which is returned in the output, on every single line to
-identify the transaction.
-</para>
-
-<refsect2><title>KEY <option>queryid</option> <option>FQDN</option></title>
-<para>
-This request looks up the KEY resource record for the given <option>FQDN.</option>.
-</para>
-</refsect2>
-
-<refsect2>
-<title>KEY4 <option>queryid</option> <option>A.B.C.D</option></title>
-<para>
-This request looks up the KEY resource record found in the reverse map for
-the IP version 4 address <option>A.B.C.D</option>, i.e. it looks
-up D.C.B.A.in-addr.arpa.
-</para>
-</refsect2>
-
-<refsect2>
-<title>KEY6 <option>queryid</option> <option>A:B::C:D</option></title>
-<para>
-This request looks up the KEY resource record found in the reverse map
-for the IPv6 address <option>A:B::C:D</option>, i.e.
-it looks the 32-nibble long entry in ip6.arpa (and ip6.int).
-</para>
-</refsect2>
-
-<refsect2>
-<title>TXT4 <option>queryid</option> <option>A.B.C.D</option></title>
-<para>
-This request looks up the TXT resource record found in the reverse map for
-the IP version 4 address <option>A.B.C.D</option>, i.e. it looks
-up D.C.B.A.in-addr.arpa.
-</para>
-</refsect2>
-
-<refsect2>
-<title>TXT6 <option>queryid</option> <option>A:B::C:D</option></title>
-<para>
-This request looks up the TXT resource record found in the reverse map
-for the IPv6 address <option>A:B::C:D</option>, i.e.
-it looks the 32-nibble long entry in ip6.arpa (and ip6.int).
-</para>
-</refsect2>
-
-<refsect2>
-<title>KEY <option>queryid</option> <option>FQDN</option></title>
-<para>
-This request looks up the IPSECKEY resource record for the given
-<option>FQDN.</option>. See note about IPSECKEY processing, below.
-</para>
-</refsect2>
-
-<refsect2>
-<title>IPSECKEY4 <option>queryid</option> <option>A.B.C.D</option></title>
-<para>
-This request looks up the IPSECKEY resource record found in the reverse map for
-the IP version 4 address <option>A.B.C.D</option>, i.e. it looks
-up D.C.B.A.in-addr.arpa. See special note about IPSECKEY processing, below.
-</para>
-</refsect2>
-
-<refsect2>
-<title>IPSECKEY6 <option>queryid</option> <option>A:B::C:D</option></title>
-<para>
-This request looks up the IPSECKEY resource record found in the reverse map
-for the IPv6 address <option>A:B::C:D</option>, i.e.
-it looks the 32-nibble long entry in ip6.arpa (and ip6.int). See
-special note about IPSECKEY processing, below.
-</para>
-</refsect2>
-
-<refsect2>
-<title>OE4 <option>queryid</option> <option>A.B.C.D</option></title>
-<para>
-This request looks an appropriate record for Opportunistic
-Encryption for the given IP address. This attempts to look for the
-delegation record. This may be one of IPSECKEY, KEY, or TXT
-record. Unless configured otherwise, (see OE4 Directives, below), then
-a query type of ANY will be used to retrieve all relevant records, and
-all will be returned.
-</para>
-</refsect2>
-
-<refsect2>
-<title>OE6 <option>queryid</option> <option>A:B::C:D</option></title>
-<para>
-This request looks an appropriate record for Opportunistic
-Encryption for the given IPv6 address. This attempts to look for the
-delegation record. This may be one of IPSECKEY, KEY, or TXT
-record. Unless configured otherwise, (see OE Directives, below), then
-a query type of ALL will be used to retrieve all relevant records, and
-all will be returned.
-i.e. it looks the 32-nibble long entry in ip6.arpa (and ip6.int).
-</para>
-</refsect2>
-
-<refsect2>
-<title>A <option>queryid</option> <option>FQDN</option></title>
-<para>
-This request looks up the A (IPv4) resource record for the given
-<option>FQDN.</option>.
-</para>
-</refsect2>
-
-<refsect2>
-<title>AAAA <option>queryid</option> <option>FQDN</option></title>
-<para>
-This request looks up the AAAA (IPv6) resource record for the given
-<option>FQDN.</option>.
-</para>
-</refsect2>
-
-</refsect1>
-
-<refsect1><title>Replies to queries</title>
-
-<para>
-All replies from the queries are in the following format:
-<programlisting>
-&lt;ID&gt; &lt;TIME&gt; &lt;TTL&gt; &lt;TYPE&gt; &lt;TYPE-SPECIFIC&gt; \n
-</programlisting>
-
-<variablelist>
-
-<varlistentry><term><parameter>ID</parameter></term>
-<listitem>
-<para>
-this is the <option>queryid</option> value that was provided in
-the query. It is repeated on every line to permit the replies to be
-properly associated with the query. When the response is not ascribable to
-particular query (such as for a mis-formed query), then the query ID "0" will
-be used.
-</para>
-</listitem>
-</varlistentry>
-
-<varlistentry><term><parameter>TIME</parameter></term>
-<listitem>
-<para>
-this is the current time in seconds since epoch.
-</para>
-</listitem>
-</varlistentry>
-
-<varlistentry><term><parameter>TTL</parameter></term>
-<listitem>
-<para>
-for answers which have a time to live, this is the current value. The
-answer is valid for this number of seconds. If there is no useful
-value here, then the number 0 is used.
-</para>
-</listitem>
-</varlistentry>
-
-
-<varlistentry><term><parameter>TYPE</parameter></term>
-<listitem>
-<para>
-This is the type of the record that is being returned. The types are
-described in the next section. The TYPE specific data that follows is
-specific to the type.
-</para>
-</listitem>
-</varlistentry>
-</variablelist>
-
-</para>
-
-<para>
-The replies are limited to 4096 bytes, a value defined as
-<constant>LWDNSQ_RESULT_LEN_MAX</constant>. This is defined in
-<filename>freeswan.h</filename>.
-</para>
-
-<para>All of the replies which include resource records use the
-standard presentation format (with no line feeds or carriage returns)
-in their answer.</para>
-
-<refsect2>
-<title>START</title>
-<para>
-This reply indicates that a query has been received and has been
-started. It serves as an anchor point for timing, as well as an acknowledgement.
-</para>
-</refsect2>
-
-<refsect2>
-<title>DONE</title>
-<para>
-This reply indicates that a query is entirely over, and no further
-information from this query will be sent.
-</para>
-</refsect2>
-
-<refsect2>
-<title>RETRY</title>
-<para>
-This reply indicates that a query is entirely over, but that no
-data was found. The records may exist, but appropriate servers could
-not be reached.
-</para>
-</refsect2>
-
-<refsect2>
-<title>FATAL</title>
-<para>
-This reply indicates that a query is entirely over, and that no
-data of the type requested could be found. There were no timeouts, and
-all servers were available and confirmed non-existances. There may be
-NXT records returned prior to this.
-</para>
-</refsect2>
-
-<refsect2>
-<title>CNAME</title>
-<para>
-This is an interim reply, and indicates that a CNAME was found (and
-followed) while performing the query. The value of the CNAME is
-present in the type specific section.
-</para>
-</refsect2>
-
-<refsect2>
-<title>CNAMEFROM</title>
-<para>
-This is an interim reply, and indicates that a CNAME was found. The
-original name that was queries for was not the canonical name, and
-this reply indicates the name that was actually followed.
-</para>
-</refsect2>
-
-<refsect2>
-<title>NAME</title>
-<para>
-This is an interim reply. The original name that was queries for was
-not the canonical name. This reply indicates the canonical name.
-</para>
-</refsect2>
-
-<refsect2>
-<title>DNSSEC</title>
-<para>
-This is an interim reply. It is followed either by "OKAY" or "not
-present.
-It indicates if DNSSEC was available on the reply.
-</para>
-</refsect2>
-
-<refsect2>
-<title>TXT and AD-TXT</title>
-<para>
-This is an interim reply. If there are TXT resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-<refsect2>
-<title>A and AD-A</title>
-<para>
-This is an interim reply. If there are A resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-<refsect2>
-<title>AAAA and AD-AAAA</title>
-<para>
-This is an interim reply. If there are AAAA resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-<refsect2>
-<title>PTR and AD-PTR</title>
-<para>
-This is an interim reply. If there are PTR resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-<refsect2>
-<title>KEY and AD-KEY</title>
-<para>
-This is an interim reply. If there are KEY resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-
-<refsect2>
-<title>IPSECKEY and AD-IPSECKEY</title>
-<para>
-This is an interim reply. If there are IPSEC resource records in the
-reply, then each one is presented using this type. If preceeded by
-AD-, then this record was signed with DNSSEC.
-</para>
-</refsect2>
-
-
-</refsect1>
-
-<refsect1><title>Special IPSECKEY processing</title>
-
-<para>
-At the time of this writing, the IPSECKEY resource record is not
-entirely specified. In particular no resource record number has been
-assigned. This program assumes that it is resource record number
-45. If the file
-@IPSEC_CONFDDIR@/lwdnsq.conf
-exists, and contains a line like
-<programlisting>
-ipseckey_rr=<option>number</option>
-</programlisting>
-then this number will be used instead. The file is read only once at
-startup.
-</para>
-</refsect1>
-
-<refsect1><title>OE Directives</title>
-
-<para>
-If the file
-@IPSEC_CONFDDIR@/lwdnsq.conf
-exists, and contains a line like
-<programlisting>
-queryany=false
-</programlisting>
-then instead of doing an ALL query when looking for OE delegation
-records, lwdnsq will do a series of queries. It will first look for
-IPSECKEY, and then TXT record. If it finds neither, it will then look
-for KEY records of all kinds, although they do not contain delegation
-information.
-</para>
-</refsect1>
-
-<refsect1><title>Special IPSECKEY processing</title>
-
-<programlisting>
-/etc/ipsec.d/lwdnsq.conf
-</programlisting>
-
-</refsect1>
-
-</refentry>
-</section>
-</article>
-
-
-
-
-
-
diff --git a/programs/lwdnsq/states.fig b/programs/lwdnsq/states.fig
deleted file mode 100644
index 6a28249ee..000000000
--- a/programs/lwdnsq/states.fig
+++ /dev/null
@@ -1,66 +0,0 @@
-#FIG 3.2
-Landscape
-Center
-Metric
-A4
-100.00
-Single
--2
-1200 2
-6 1305 1530 3330 2205
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
- 3330 2205 3330 1530 1305 1530 1305 2205 3330 2205
-4 1 0 50 0 0 20 0.0000 4 255 1575 2385 1935 initial request\001
--6
-6 1350 5850 3375 6525
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
- 3375 6525 3375 5850 1350 5850 1350 6525 3375 6525
-4 1 0 50 0 0 20 0.0000 4 135 825 2430 6255 success\001
--6
-6 4275 2700 6525 3375
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
- 6525 3375 6525 2700 4275 2700 4275 3375 6525 3375
-4 1 0 50 0 0 20 0.0000 4 195 2115 5400 3150 ASK for CNAME\001
--6
-6 225 3825 2250 4500
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
- 2250 4500 2250 3825 225 3825 225 4500 2250 4500
-4 1 0 50 0 0 20 0.0000 4 195 750 1305 4230 failure\001
--6
-6 5625 4545 7875 5220
-2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
- 7875 5220 7875 4545 5625 4545 5625 5220 7875 5220
-4 1 0 50 0 0 20 0.0000 4 255 1740 6750 4995 ASK for target\001
--6
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 3330 1935 4275 2745
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 2250 2205 1305 3825
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 4275 3330 2250 4050
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 2880 2250 2880 5850
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 5895 5220 3375 6120
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 5625 4950 2250 4275
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 6030 3375 6570 4545
-2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
- 2 0 1.00 60.00 120.00
- 7695 4545 6525 3150
-4 0 0 50 0 0 14 0.0000 4 195 1830 3825 2295 ERRSET_NODATA\001
-4 2 0 50 0 0 14 0.0000 4 195 1875 1575 3150 ERRSET_NONAME\001
-4 0 0 50 0 0 14 0.0000 4 150 300 2970 5175 OK\001
-4 0 0 50 0 0 14 0.0000 4 150 300 4500 5895 OK\001
-4 0 0 50 0 0 14 0.0000 4 195 1875 3420 3825 ERRSET_NONAME\001
-4 0 0 50 0 0 14 0.0000 4 195 1875 3420 4500 ERRSET_NONAME\001
-4 0 0 50 0 0 14 0.0000 4 150 300 6390 3960 OK\001
-4 0 0 50 0 0 14 0.0000 4 195 1830 7110 3825 ERRSET_NODATA\001
diff --git a/programs/lwdnsq/states.png b/programs/lwdnsq/states.png
deleted file mode 100644
index ceb5b3c45..000000000
--- a/programs/lwdnsq/states.png
+++ /dev/null
Binary files differ
diff --git a/programs/mailkey/.cvsignore b/programs/mailkey/.cvsignore
deleted file mode 100644
index 5af485234..000000000
--- a/programs/mailkey/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-mailkey
diff --git a/programs/mailkey/Makefile b/programs/mailkey/Makefile
deleted file mode 100644
index 4b0385823..000000000
--- a/programs/mailkey/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=mailkey
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.1 2003/02/22 03:26:55 sam
-# remaining pieces of mailkey
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/mailkey/mailkey.8 b/programs/mailkey/mailkey.8
deleted file mode 100644
index be6b4ff93..000000000
--- a/programs/mailkey/mailkey.8
+++ /dev/null
@@ -1,47 +0,0 @@
-.TH IPSEC_MAILKEY 8 "21 Feb 2002"
-.\" RCSID $Id: mailkey.8,v 1.1 2004/03/15 20:35:28 as Exp $
-.SH NAME
-ipsec mailkey \- mail DNS records for Opportunistic Encryption
-.SH SYNOPSIS
-.B ipsec
-.B mailkey
-\-\-me
-my@address.tld
-[
-.B \-\-reverse
-1.2.3.4
-] [
-.B \-\-forward
-hostname.domain.tld
-]
-.SH DESCRIPTION
-.I mailkey
-is a meta-program. It generates a script which will attempt to mail the TXT
-records required to enable Opportunistic Encryption (OE).
-.PP
-An e-mail address for the domain's DNS administrator is derived from SOA records.
-The mail body and destination address are freely editable in the script.
-.PP
-If no administrator can be located, the output file will not be executable.
-.PP
-.TP
-\fB\-\-me\fP\ \fImy@address.tld\fP
-set the Reply-To: address of the mail to be sent.
-.TP
-\fB\-\-forward\fP\ \fIhostname.domain.tld\fP
-the domain name to be used for initator-only OE.
-.TP
-\fB\-\-reverse\fP\ \fI1.2.3.4\fP
-the IP address to be used for full Opportunistic Encryption.
-.PP
-Only one of --forward or --reverse may be specified.
-.SH FILES
-.nf
-/etc/ipsec.secrets
-.fi
-.SH SEE ALSO
-ipsec_showhostkey(8), host(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project <http://www.freeswan.org> by Sam Sgro.
-.SH BUGS
-May produce indeterminate results when processing non-routable IPs.
diff --git a/programs/mailkey/mailkey.in b/programs/mailkey/mailkey.in
deleted file mode 100755
index fecdcf62c..000000000
--- a/programs/mailkey/mailkey.in
+++ /dev/null
@@ -1,241 +0,0 @@
-#! /bin/sh
-# mail OE DNS RR info to relevent administrator
-#
-# Copyright (C) 2003 Sam Sgro <sam@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: mailkey.in,v 1.1 2004/03/15 20:35:28 as Exp $
-
-me="ipsec mailkey"
-
-PATH=/sbin:/usr/bin:/usr/local/sbin:@IPSEC_SBINDIR@:$PATH export PATH
-
-reverse=0
-forward=0
-mymail=""
-usage="Usage:
- $me --me my@address.tld --forward hostname.domain.tld
- $me --me my@address.tld --reverse 1.2.3.4"
-
-for dummy
-do
- case "$1" in
- --help) echo "$usage" ; exit 0 ;;
- --forward) forward=1 ; reverse=0 ; hostname="$2" ; shift ;;
- --reverse) reverse=1 ; forward=0 ; reverseip="$2" ; shift ;;
- --me) mymail="$2" ; shift ;;
- --) shift ; break ;;
- -*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-# only do one of iOE || (pOE/rOE/fOE/insert acronym here) at a time
-# but you have to choose one. Plus, if ya ain't specified your mail address...
-if [ "$forward" -eq "$reverse" ] || [ ! "$mymail" ]
-then
-{
-echo "$usage"; exit 0;
-}
-fi
-
-# Test to see if there is a key to process in the first place.
-test1st=`ipsec showhostkey --txt 1.2.3.4 2>&1`
-test2nd=`echo $test1st | grep TXT`
-if [ ! "$test2nd" ]
-then
-{
-echo "Our attempt to retrieve your RSA key using 'ipsec showhostkey' failed
-with the following error:
-
-"$test1st"
-
-Common concerns: This account must be able to read /etc/ipsec.secrets.
-If you haven't generated your key yet, please run 'ipsec newhostkey'."
-exit 0
-}
-fi
-
-
-# This is where we will save the script.
-save_mail_file=~/"OE_mail_""$reverseip$hostname"
-
-# RSA/SOA processing functions.
-# takes two arguments - the IP address/hostname to be used, and an attempt to guess the
-# beginning of the DNS record for the administrator
-txtprocess(){
-ipsec showhostkey --txt $1 | sed "s/^.* IN TXT/$2. IN TXT/" | grep TXT
-}
-
-# Find the hostmaster part of the SOA.
-# This only works with the "net" portion of in-addr.arpa. commands - 20.168.192.in-addr.arpa. -
-# or the domain portion of FQDNs. The data is prepped using host_data in the individual sections
-# for $forward and $reverse.
-# Note: I've experienced it returning SOAs for non-routeable IP addresses! This needs to be
-# addressed.
-hostprocess(){
-host -t soa $1 | grep SOA | while read a b c d e
-do
-echo $d | sed -e "s/\(^[a-zA-Z0-9-]*\)\.\([a-zA-Z0-9-\.]*\).$/\1@\2/"
-done
-}
-
-# generate the pieces that go into the template, which are dependent on the type of OE.
-if [ "$reverse" -eq 1 ]; then
-{
-# convert the reverse ip to something appropriate for a DNS record.
-arpaip=`echo $reverseip | sed -e "s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\4.\3.\2.\1.in-addr.arpa/"`
-# prepare data for hostprocess()
-host_data=`echo $arpaip | sed -e "s/^[0-9]*\.\(.*\)/\1/"`
-
-firstsub=" I'm contacting you in your role as the administrator of the domain
-\"$arpaip\" as listed in its SOA record.
-
- My network security software, which employs IPSec, requires the
-below keying information to be published as a RR in the DNS domain
-which you are responsible for.
-
-"
-
-txt=`txtprocess $reverseip $arpaip`
-secondsub=" To this end, I need you to publish the following TXT record:
-
---DNS_RESOURCE_RECORDS--
-
-"$txt"
-
---DNS_RESOURCE_RECORDS--"
-
-thirdsub="to enable full Opportunistic Encryption using the IP address:
-
-"$reverseip
-
-fourthsub="and TXT records are"
-
-proposed_email=`hostprocess $host_data`
-}
-elif [ "$forward" -eq 1 ]; then
-{
-# prepare data for hostprocess()
-# leave only the domain name
-domain_data=`echo $hostname | sed -e "s/.*\.\([a-zA-Z0-9-]*\.[a-zA-Z0-9-]*$\)/\1/"`
-# leave only the host name
-host_data=`echo $hostname | sed -e "s/\(.*\)\.[a-zA-Z0-9-]*\.[a-zA-Z0-9-]*$/\1/"`
-
-firstsub=" I'm contacting you in your role as the administrator of the domain
-\"$hostname\" as listed in its SOA record.
-
- My network security software, which employs IPSec, requires the
-below keying information to be published as a RR in the DNS domain
-which you are responsible for.
-
-"
-
-txt=`txtprocess @$hostname $host_data`
-secondsub=" To this end, please publish the following TXT record for the hostname
-$hostname:
-
-
---DNS_RESOURCE_RECORDS--
-
-$txt
-
---DNS_RESOURCE_RECORDS--"
-thirdsub="to allow me to use the hostname:
-
-"$hostname"
-
-for initiator-only Opportunistic Encryption."
-fourthsub="record is"
-
-proposed_email=`hostprocess $domain_data`
-}
-fi
-
-# Create the template used for the body of the e-mail.
-
-mailbody=$firstsub$secondsub"
-
-
- Please be careful to preserve the spaces and/or quotation marks as written.
-These are important for the RSA key to survive DNS processing.
-
- Thanks for your help in securing the 'net!
-
- $mymail
- (Generated by '$me' for $mymail)
-
-
-
-Opportunistic Encryption (OE) is the result of ongoing effort by the FreeS/WAN
-project (www.freeswan.org). It allows for the creation of dynamic IPSec
-connections between hosts without pre-arrangement, authenticated via RSA keys
-stored in DNS records.
-
-Technical information on OE can be found in this RFC draft:
-
-http://www.freeswan.org/freeswan_snaps/CURRENT-SNAP/doc/draft-richardson-ipsec-opportunistic.txt
-
-If you have any questions about these TXT records, or about OE in general,
-please direct them to the FreeS/WAN support lists:
-
-users@lists.freeswan.org
-"
-
-# If we managed to find a hostmaster, make the appropriate modifications to the mail's body and
-# our instructions to the user.
-if [ "$proposed_email" ]; then
-{
-
-# This is now converting the mail test into an executable script.
-# Most users will have reached this stage; they can edit the contact_email
-# if they know better than us.
-# -s - Subject line. By extending it, we can "hack" the mail program to
-# include a customized Reply-To header.
-
-mailbody="#!/bin/sh
-#
-# Edit this variable to send this message to an alternate destination
-contact_email=$proposed_email
-
-mail \$contact_email -s 'DNS records for Opportunistic Encryption ($hostname$reverseip)
-Reply-To: $mymail' <<EOF
-
-"$mailbody"
-
-EOF
-"
-
-screenoutput="Executable mail file saved to: "$save_mail_file
-}
-else
-{
-# Slightly different instructions if we have nothing to tell the user.
-
-screenoutput="$me: error: Unable to locate SOA record for this domain. Not generating executable file.
-Sample mail file saved to: "$save_mail_file
-}
-fi
-
-# Create the output that has been prepared.
-echo "$mailbody" > $save_mail_file
-
-# Only make it executable if we've guessed a destination e-mail address.
-if [ "$proposed_email" ]; then
-{
-chmod u+x $save_mail_file
-}
-fi
-
-# Tell the user what'sgoing on.
-echo "$screenoutput"
diff --git a/programs/manual/.cvsignore b/programs/manual/.cvsignore
deleted file mode 100644
index 2905494b6..000000000
--- a/programs/manual/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-manual
diff --git a/programs/manual/Makefile b/programs/manual/Makefile
deleted file mode 100644
index 68cfb9110..000000000
--- a/programs/manual/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=manual
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/manual/manual.8 b/programs/manual/manual.8
deleted file mode 100644
index a439544da..000000000
--- a/programs/manual/manual.8
+++ /dev/null
@@ -1,267 +0,0 @@
-.TH IPSEC_MANUAL 8 "17 July 2001"
-.\" RCSID $Id: manual.8,v 1.1 2004/03/15 20:35:28 as Exp $
-.SH NAME
-ipsec manual \- take manually-keyed IPsec connections up and down
-.SH SYNOPSIS
-.B ipsec
-.B manual
-[
-.B \-\-show
-] [
-.B \-\-showonly
-] [
-.B \-\-other
-]
-.br
-\ \ \ [
-.B \-\-iam
-.RB address "@" interface
-] [
-.B \-\-config
-configfile
-]
-.br
-\ \ \ operation connection
-.sp 0.5
-.B ipsec
-.B manual
-[
-.I options
-]
-.B \-\-union
-operation part ...
-.SH DESCRIPTION
-.I Manual
-manipulates manually-keyed FreeS/WAN IPsec connections,
-setting them up and shutting them down,
-based on the information in the IPsec configuration file.
-In the normal usage,
-.I connection
-is the name of a connection specification in the configuration file;
-.I operation
-is
-.BR \-\-up ,
-.BR \-\-down ,
-.BR \-\-route ,
-or
-.BR \-\-unroute .
-.I Manual
-generates setup (\c
-.BR \-\-route
-or
-.BR \-\-up )
-or
-teardown (\c
-.BR \-\-down
-or
-.BR \-\-unroute )
-commands for the connection and feeds them to a shell for execution.
-.PP
-The
-.B \-\-up
-operation brings the specified connection up, including establishing a
-suitable route for it if necessary.
-.PP
-The
-.B \-\-route
-operation just establishes the route for a connection.
-Unless and until an
-.B \-\-up
-operation is done, packets routed by that route will simply be discarded.
-.PP
-The
-.B \-\-down
-operation tears the specified connection down,
-.I except
-that it leaves the route in place.
-Unless and until an
-.B \-\-unroute
-operation is done, packets routed by that route will simply be discarded.
-This permits establishing another connection to the same destination
-without any ``window'' in which packets can pass without encryption.
-.PP
-The
-.B \-\-unroute
-operation (and only the
-.B \-\-unroute
-operation) deletes any route established for a connection.
-.PP
-In the
-.B \-\-union
-usage, each
-.I part
-is the name of a partial connection specification in the configuration file,
-and the union of all the partial specifications is the
-connection specification used.
-The effect is as if the contents of the partial specifications were
-concatenated together;
-restrictions on duplicate parameters, etc., do apply to the result.
-(The same effect can now be had, more gracefully, using the
-.B also
-parameter in connection descriptions;
-see
-.IR ipsec.conf (5)
-for details.)
-.PP
-The
-.B \-\-show
-option turns on the
-.B \-x
-option of the shell used to execute the commands,
-so each command is shown as it is executed.
-.PP
-The
-.B \-\-showonly
-option causes
-.I manual
-to show the commands it would run, on standard output,
-and not run them.
-.PP
-The
-.B \-\-other
-option causes
-.I manual
-to pretend it is the other end of the connection.
-This is probably not useful except in combination with
-.BR \-\-showonly .
-.PP
-The
-.B \-\-iam
-option causes
-.I manual
-to believe it is running on the host with the specified IP
-.IR address ,
-and that it should use the specified
-.I interface
-(normally it determines all this automatically,
-based on what IPsec interfaces are up and how they are configured).
-.PP
-The
-.B \-\-config
-option specifies a non-standard location for the FreeS/WAN IPsec
-configuration file (default
-.IR /etc/ipsec.conf ).
-.PP
-See
-.IR ipsec.conf (5)
-for details of the configuration file.
-Apart from the basic parameters which specify the endpoints and routing
-of a connection (\fBleft\fR
-and
-.BR right ,
-plus possibly
-.BR leftsubnet ,
-.BR leftnexthop ,
-.BR leftfirewall ,
-their
-.B right
-equivalents,
-and perhaps
-.BR type ),
-a non-\fBpassthrough\fR
-.I manual
-connection needs an
-.B spi
-or
-.B spibase
-parameter and some parameters specifying encryption, authentication, or
-both, most simply
-.BR esp ,
-.BR espenckey ,
-and
-.BR espauthkey .
-Moderately-secure keys can be obtained from
-.IR ipsec_ranbits (8).
-For production use of manually-keyed connections,
-it is strongly recommended that the keys be kept in a separate file
-(with permissions
-.BR rw\-\-\-\-\-\-\- )
-using the
-.B include
-and
-.B also
-facilities of the configuration file (see
-.IR ipsec.conf (5)).
-.PP
-If an
-.B spi
-parameter is given,
-.I manual
-uses that value as the SPI number for all the SAs
-(which are in separate number spaces anyway).
-If an
-.B spibase
-parameter is given instead,
-.I manual
-assigns SPI values by altering the bottom digit
-of that value;
-SAs going from left to right get even digits starting at 0,
-SAs going from right to left get odd digits starting at 1.
-Either way, it is suggested that manually-keyed connections use
-three-digit SPIs with the first digit non-zero,
-i.e. in the range
-.B 0x100
-through
-.BR 0xfff ;
-FreeS/WAN reserves those for manual keying and will not
-attempt to use them for automatic keying (unless requested to,
-presumably by a non-FreeS/WAN other end).
-.SH FILES
-.ta \w'/var/run/ipsec.nexthop'u+4n
-/etc/ipsec.conf default IPsec configuration file
-.br
-/var/run/ipsec.info \fB%defaultroute\fR information
-.SH SEE ALSO
-ipsec(8), ipsec.conf(5), ipsec_spi(8), ipsec_eroute(8), ipsec_spigrp(8),
-route(8)
-.SH HISTORY
-Written for the FreeS/WAN project
-<http://www.freeswan.org/>
-by Henry Spencer.
-.SH BUGS
-It's not nearly as generous about the syntax of subnets,
-addresses, etc. as the usual FreeS/WAN user interfaces.
-Four-component dotted-decimal must be used for all addresses.
-It
-.I is
-smart enough to translate bit-count netmasks to dotted-decimal form.
-.PP
-If the connection specification for a connection is changed between an
-.B \-\-up
-and the ensuing
-.BR \-\-down ,
-chaos may ensue.
-.PP
-The
-.B \-\-up
-operation is not smart enough to notice whether the connection is already up.
-.PP
-.I Manual
-is not smart enough to reject insecure combinations of algorithms,
-e.g. encryption with no authentication at all.
-.PP
-Any non-IPsec route to the other end which is replaced by the
-.B \-\-up
-or
-.B \-\-route
-operation will not be re-established by
-.BR \-\-unroute .
-Whether this is a feature or a bug depends on your viewpoint.
-.PP
-The optional parameters which
-override the automatic
-.BR spibase -based
-SPI assignment are a messy area of the code and bugs are likely.
-.PP
-``Road warrior'' handling,
-and other special forms of setup which
-require negotiation between the two security gateways,
-inherently cannot be done with
-.IR manual .
-.PP
-.I Manual
-generally lags behind
-.I auto
-in support of various features,
-even when implementation \fIwould\fR be possible.
-For example, currently it does not do IPComp content compression.
diff --git a/programs/manual/manual.in b/programs/manual/manual.in
deleted file mode 100755
index bda4bafa0..000000000
--- a/programs/manual/manual.in
+++ /dev/null
@@ -1,637 +0,0 @@
-#! /bin/sh
-# user interface to manual keying
-# Copyright (C) 1998, 1999 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: manual.in,v 1.1 2004/03/15 20:35:28 as Exp $
-
-me='ipsec manual'
-usage="Usage:
- $me [--showonly] --{up|down|route|unroute} name
- $me [--showonly] --{up|down|route|unroute} --union partname ...
-
- other options: [--config ipsecconfigfile] [--other] [--show]
- [--iam ipaddress@interface]"
-
-# make sure outputs of (e.g.) ifconfig are in English
-unset LANG LANGUAGE LC_ALL LC_MESSAGES
-
-showonly=
-config=
-info=/var/run/ipsec.info
-shopts=
-other=0
-union=0
-noinclude=
-interfs=
-op=
-
-for dummy
-do
- case "$1" in
- --help) echo "$usage" ; exit 0 ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --show) shopts=-x ;;
- --showonly) showonly=yes ;;
- --other) other=1 ;;
- --union) union=1 ;;
- --config) config="--config $2" ; shift ;;
- --noinclude) noinclude=--noinclude ;;
- --iam) interfs="$2" ; shift ;;
- --up|--down|--route|--unroute)
- if test " $op" != " "
- then
- echo "$usage" >&2
- exit 2
- fi
- op="$1"
- ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-
-case "$op$#:$union" in
-[01]:*) echo "$usage" >&2 ; exit 2 ;;
-2:0) echo "$me: warning: obsolete command syntax used" >&2
- op="--$2"
- names="$1"
- ;;
-[0-9]*:1) ;;
---*) if test $# -eq 0
- then
- echo "$usage" >&2
- exit 2
- fi
- names="$*"
- ;;
-*) echo "$usage" >&2 ; exit 2 ;;
-esac
-if test " $op" = " "
-then
- # --union obsolete-syntax case, op is last argument
- echo "$me: warning: obsolete command syntax used" >&2
- names=
- prev=
- for arg
- do
- names="$names $prev"
- prev="$arg"
- done
- op="--$prev"
-fi
-case "$op" in
---up|--down|--route|--unroute) ;;
-*) echo "$usage" >&2 ; exit 2 ;;
-esac
-
-case "$interfs" in
-'') interfs="`ifconfig |
- awk ' /^ipsec/ { interf = $1 ; next }
- /^[^ \t]/ { interf = "" ; next }
- /^[ \t]*inet addr/ {
- sub(/:/, " ", $0)
- if (interf != "")
- print $3 "@" interf
- }' | tr '\n' ' '`"
- ;;
-esac
-
-if test -s $info
-then
- . $info
-fi
-
-ipsec _confread $config $noinclude $names |
-awk ' BEGIN {
- FS = "\t"
- myname = "'"$me"'"
- err = "cat >&2"
- op = "'"$op"'"
- other = '"$other"'
- names = "'"$names"'"
- interfs = "'"$interfs"'"
- ni = split(interfs, terfs, " ")
- if (ni == 0)
- fail("no IPsec-enabled interfaces found")
- for (i = 1; i <= ni; i++) {
- nc = split(terfs[i], cpts, "@")
- if (nc != 2)
- fail("internal error on " terfs[i])
- interface[cpts[1]] = cpts[2]
- }
- draddr = "'"$defaultrouteaddr"'"
- drnexthop = "'"$defaultroutenexthop"'"
- s[""] = ""
- nlspi = 0
- nrspi = 0
- failed = 0
- maskbits[0] = "0.0.0.0"
- maskbits[1] = "128.0.0.0"
- maskbits[2] = "192.0.0.0"
- maskbits[3] = "224.0.0.0"
- maskbits[4] = "240.0.0.0"
- maskbits[5] = "248.0.0.0"
- maskbits[6] = "252.0.0.0"
- maskbits[7] = "254.0.0.0"
- maskbits[8] = "255.0.0.0"
- maskbits[9] = "255.128.0.0"
- maskbits[10] = "255.192.0.0"
- maskbits[11] = "255.224.0.0"
- maskbits[12] = "255.240.0.0"
- maskbits[13] = "255.248.0.0"
- maskbits[14] = "255.252.0.0"
- maskbits[15] = "255.254.0.0"
- maskbits[16] = "255.255.0.0"
- maskbits[17] = "255.255.128.0"
- maskbits[18] = "255.255.192.0"
- maskbits[19] = "255.255.224.0"
- maskbits[20] = "255.255.240.0"
- maskbits[21] = "255.255.248.0"
- maskbits[22] = "255.255.252.0"
- maskbits[23] = "255.255.254.0"
- maskbits[24] = "255.255.255.0"
- maskbits[25] = "255.255.255.128"
- maskbits[26] = "255.255.255.192"
- maskbits[27] = "255.255.255.224"
- maskbits[28] = "255.255.255.240"
- maskbits[29] = "255.255.255.248"
- maskbits[30] = "255.255.255.252"
- maskbits[31] = "255.255.255.254"
- maskbits[32] = "255.255.255.255"
- }
- $1 == "=" {
- next
- }
- $1 == "!" {
- if ($2 != "")
- fail($2)
- next
- }
- $1 != ":" {
- fail("internal error, unknown type code \"" $1 "\"")
- }
- { s[$2] = $3 }
- function q(s) {
- return "\"" s "\""
- }
- function fail(m) {
- print myname ": fatal error in " q(names) ": " m |err
- failed = 1
- exit
- }
- function swap(k, t, l, r) {
- l = "left" k
- r = "right" k
- if ((l in s) && (r in s)) {
- t = s[l]
- s[l] = s[r]
- s[r] = t
- } else if (l in s) { # but not r
- s[r] = s[l]
- delete s[l]
- } else if (r in s) { # but not l
- s[l] = s[r]
- delete s[r]
- }
- }
- function yesno(k) {
- if ((k in s) && s[k] != "yes" && s[k] != "no")
- fail("parameter \"" k "\" must be \"yes\" or \"no\"")
- }
- function default(k, v) {
- if (!(k in s))
- s[k] = v
- }
- function need(k) {
- if (!(k in s))
- fail("connection has no \"" k "\" parameter specified")
- if (s[k] == "")
- fail("parameter \"" k "\" value must be non-empty")
- }
- function integer(k) {
- if (!(k in s))
- return
- if (s[k] !~ /^[0-9]+$/)
- fail("parameter \"" k "\" value must be integer")
- }
- function nexthopset(dir, val, k) {
- k = dir "nexthop"
- if (k in s)
- fail("non-default value of " k " is being overridden")
- if (val != "")
- s[k] = val
- else if (k in s)
- delete s[k]
- }
- function leftward( t) {
- nlspi++
- if ("spi" in s)
- return s["spi"]
- t = spibase spil
- spil += 2
- return t
- }
- function rightward( t) {
- nrspi++
- if ("spi" in s)
- return s["spi"]
- t = spibase spir
- spir += 2
- return t
- }
- function netfix(dir, n, t) {
- n = s[dir "subnet"]
- if (n == "%default")
- n = "0.0.0.0/0"
- if (n !~ /\//)
- fail(dir "subnet=" n " has no mask specified")
- t = split(n, netfixarray, "/")
- if (t != 2)
- fail("bad syntax in " dir "subnet=" n)
- s[dir "net"] = netfixarray[1]
- s[dir "mask"] = mask(netfixarray[2])
- }
- function mask(m) {
- if (m ~ /\./)
- return m
- if (!(m in maskbits))
- fail("unknown mask syntax \"" m "\"")
- return maskbits[m]
- }
- function bidir(name, l, r) {
- l = "left" name
- r = "right" name
- if (!(l in s) && (name in s))
- s[l] = s[name]
- if (!(r in s) && (name in s))
- s[r] = s[name]
- if ((l in s) != (r in s))
- fail("must give both or neither \"" l "\" and \"" \
- r "\"")
- }
- function espspi(src, dest, spi, dir) {
- if (!("esp" in s))
- return
- dir = (dest == me) ? "left" : "right"
- print "ipsec spi --label", q(names), "--af inet",
- "--said", ("esp" spi "@" dest), "\\"
- print "\t--esp", s["esp"], "--src", src, "\\"
- if ((dir "espauthkey") in s)
- print "\t--authkey", s[dir "espauthkey"], "\\"
- if ("espreplay_window" in s)
- print "\t--replay_window", s["espreplay_window"], "\\"
- if ((dir "espenckey") in s)
- print "\t--enckey", s[dir "espenckey"], "&&"
- else
- print "\t&&"
- }
- function ahspi(src, dest, spi, dir) {
- if (!("ah" in s))
- return
- dir = (dest == me) ? "left" : "right"
- if (!((dir "ahkey") in s))
- fail("AH specified but no ahkey= given")
- print "ipsec spi --label", q(names), "--af inet",
- "--said", ("ah" spi "@" dest), "\\"
- print "\t--ah", s["ah"], "--src", src, "\\"
- if ("ahreplay_window" in s)
- print "\t--replay_window", s["ahreplay_window"], "\\"
- print "\t--authkey", s[dir "ahkey"], "&&"
- }
- # issue a suitable invocation of updown command
- function updown(verb, suffix, cmd) {
- if ("leftupdown" in s) {
- cmd = s["leftupdown"]
- if (s["leftfirewall"] == "yes")
- fail("cannot specify both updown and firewall")
- } else {
- cmd = "ipsec _updown"
- if (s["leftfirewall"] == "yes")
- cmd = cmd " ipfwadm"
- }
- print "PLUTO_VERB=" verb verbsuf " " cmd " " suffix
- }
- END {
- #########
- if (failed)
- exit 1
- default("type", "tunnel")
- type = s["type"]
- shunt = 0
- if (type == "transport") {
- if ("leftsubnet" in s)
- fail("type=transport incompatible with leftsubnet")
- if ("rightsubnet" in s)
- fail("type=transport incompatible with rightsubnet")
- } else if (type == "passthrough") {
- shunt = 1;
- p = "%pass"
- } else if (type == "drop" || type == "reject") {
- shunt = 1;
- p = "%" type
- } else if (type != "tunnel")
- fail("only know how to do types tunnel/transport/passthrough")
- if (shunt) {
- if (("ah" in s) || ("esp" in s))
- fail(type " connection may not specify AH or ESP")
- } else {
- if (!("ah" in s) && !("esp" in s))
- fail("neither AH nor ESP specified for connection")
- }
-
- need("left")
- need("right")
- if (s["left"] == "%defaultroute") {
- if (s["right"] == "%defaultroute")
- fail("left and right cannot both be %defaultroute")
- if (draddr == "")
- fail("%defaultroute requested but not known")
- s["left"] = draddr
- nexthopset("left", drnexthop)
- } else if (s["right"] == "%defaultroute") {
- if (draddr == "")
- fail("%defaultroute requested but not known")
- s["right"] = draddr
- nexthopset("right", drnexthop)
- }
-
- leftsub = ("leftsubnet" in s) ? 1 : 0
- default("leftsubnet", s["left"] "/32")
- rightsub = ("rightsubnet" in s) ? 1 : 0
- default("rightsubnet", s["right"] "/32")
- default("leftfirewall", "no")
- default("rightfirewall", "no")
- yesno("leftfirewall")
- yesno("rightfirewall")
- integer("espreplay_window")
- if (("espreplay_window" in s) && s["espreplay_window"] == 0)
- delete s["espreplay_window"]
- integer("ahreplay_window")
- if (("ahreplay_window" in s) && s["ahreplay_window"] == 0)
- delete s["ahreplay_window"]
- netfix("left")
- netfix("right")
-
- default("leftnexthop", s["right"])
- default("rightnexthop", s["left"])
- if (s["leftnexthop"] == s["left"])
- fail("left and leftnexthop must not be the same")
- if (s["rightnexthop"] == s["right"])
- fail("right and rightnexthop must not be the same")
-
- bidir("espenckey")
- bidir("espauthkey")
- bidir("ahkey")
- if ("spi" in s && "spibase" in s)
- fail("cannot specify both spi and spibase")
- if (!shunt) {
- if ("spibase" in s) {
- b = s["spibase"]
- if (b !~ /^0x[0-9a-fA-F]+0$/)
- fail("bad syntax in spibase -- must be 0x...0")
- spibase = substr(b, 1, length(b)-1)
- } else {
- need("spi")
- if (s["spi"] !~ /^0x[0-9a-fA-F]+$/)
- fail("bad syntax in spi -- must be 0x...")
- }
- }
- spir = 0
- spil = 1
-
- # who am I?
- me = ""
- for (addr in interface) {
- if (addr == s["left"] || addr == s["right"]) {
- if (me != "")
- fail("ambiguous: could be on \"" iface \
- "\" or \"" interface[addr] "\"")
- me = addr
- iface = interface[addr]
- }
- }
- if (me == "")
- fail("cannot find interface for " s["left"] " or " s["right"])
- if (other) {
- if (s["left"] == me)
- me = s["right"]
- else if (s["right"] == me)
- me = s["left"]
- }
- havesubnet = leftsubnet
- if (s["right"] == me) {
- swap("") # swaps "left" and "right"
- swap("subnet")
- swap("nexthop")
- swap("net")
- swap("mask")
- swap("firewall")
- swap("espspi")
- swap("ahspi")
- swap("espenckey")
- swap("espauthkey")
- swap("ahkey")
- swap("updown")
- t = spil
- spil = spir
- spir = t
- havesubnet = rightsubnet
- }
- him = s["right"]
-
- if (s["leftnexthop"] == "%defaultroute") {
- if (drnexthop == "")
- fail("%defaultroute requested but not known")
- s["leftnexthop"] = drnexthop
- }
-
- tspi = rightward()
- if (type == "tunnel") {
- espi = rightward()
- intspi = leftward()
- } else
- espi = tspi
- if (s["rightespspi"] != "")
- espi = s["rightespspi"]
- respi = leftward()
- if (s["leftespspi"] != "")
- respi = s["leftespspi"]
- if ("ah" in s) {
- if ("esp" in s) {
- aspi = rightward()
- raspi = leftward()
- } else {
- aspi = espi
- raspi = respi
- }
- if (s["rightahspi"] != "")
- aspi = s["rightahspi"]
- if (s["leftahspi"] != "")
- raspi = s["leftahspi"]
- }
- routeid = "-net " s["rightnet"] " netmask " s["rightmask"]
- if (s["rightmask"] == "255.255.255.255")
- routeid = "-host " s["rightnet"]
-
- print "PATH=\"'"$PATH"'\""
- print "export PATH"
- print "PLUTO_VERSION=1.1"
- verbsuf = (havesubnet) ? "-client" : "-host"
- print "PLUTO_CONNECTION=" q(names)
- print "PLUTO_NEXT_HOP=" s["leftnexthop"]
- print "PLUTO_INTERFACE=" iface
- print "PLUTO_ME=" me
- print "PLUTO_MY_CLIENT=" s["leftsubnet"]
- print "PLUTO_MY_CLIENT_NET=" s["leftnet"]
- print "PLUTO_MY_CLIENT_MASK=" s["leftmask"]
- print "PLUTO_PEER=" him
- print "PLUTO_PEER_CLIENT=" s["rightsubnet"]
- print "PLUTO_PEER_CLIENT_NET=" s["rightnet"]
- print "PLUTO_PEER_CLIENT_MASK=" s["rightmask"]
- print "export PLUTO_VERSION PLUTO_CONNECTION PLUTO_NEXT_HOP"
- print "export PLUTO_INTERFACE PLUTO_ME PLUTO_MY_CLIENT"
- print "export PLUTO_MY_CLIENT_NET PLUTO_MY_CLIENT_MASK PLUTO_PEER"
- print "export PLUTO_PEER_CLIENT PLUTO_PEER_CLIENT_NET"
- print "export PLUTO_PEER_CLIENT_MASK"
-
- if (op == "--up") {
- print "{"
- # first, the outbound SAs
- if (type == "tunnel") {
- print "ipsec spi --label", q(names), "--af inet",
- "--said", ("tun" tspi "@" him), "\\"
- print "\t--ip4", "--src", me, "--dst", him, "&&"
- }
- espspi(me, him, espi)
- ahspi(me, him, aspi)
- if (nrspi > 1) {
- # group them
- printf "ipsec spigrp --label %s --said ", q(names)
- if (type == "tunnel")
- printf "tun%s@%s ", tspi, him
- if (("esp" in s))
- printf "esp%s@%s ", espi, him
- if ("ah" in s)
- printf "ah%s@%s ", aspi, him
- printf " &&\n"
- }
- # inbound SAs
- if (type == "tunnel") {
- print "ipsec spi --label", q(names), "--af inet",
- "--said", ("tun" intspi "@" me), "\\"
- print "\t--ip4", "--src", him, "--dst", me, "&&"
- }
- espspi(him, me, respi)
- ahspi(him, me, raspi)
- if (nlspi > 1) {
- # group them
- printf "ipsec spigrp --label %s --said ", q(names)
- if (type == "tunnel")
- printf "tun%s@%s ", intspi, me
- if (("esp" in s))
- printf "esp%s@%s ", respi, me
- if ("ah" in s)
- printf "ah%s@%s ", raspi, me
- printf " &&\n"
- }
- # with the SAs in place, eroute to them
- print "ipsec eroute --label", q(names),
- "--eraf inet --replace", "\\"
- if (!shunt) {
- if (type == "tunnel")
- p = "tun"
- else if (("esp" in s))
- p = "esp"
- else
- p = "ah"
- p = p tspi "@" him
- }
- print "\t--src", s["leftsubnet"], "--dst", s["rightsubnet"],
- "--said", p, "&&"
- # with the eroute in place, NOW we can route to it
- #print "{ route del", routeid, "2>/dev/null ; true ; } &&"
- updown("prepare", "&&")
- #print "route add", routeid, "dev", iface, "gw",
- # s["leftnexthop"], "&&"
- updown("route", "&&")
- # and with all processing in place, we can penetrate firewall
- #if (s["leftfirewall"] == "yes") {
- # print "ipfwadm -F -i accept -b -S", s["leftsubnet"],
- # "-D", s["rightsubnet"], "&&"
- #}
- updown("up", "&&")
- print "true"
- print "} || {"
- } else if (op == "--route") {
- #print "{ route del", routeid, "2>/dev/null ; true ; } &&"
- updown("prepare", "&&")
- #print "route add", routeid, "dev", iface, "gw",
- # s["leftnexthop"]
- updown("route")
- exit 0
- } else if (op == "--unroute") {
- #print "route del", routeid, "dev", iface, "gw",
- # s["leftnexthop"]
- updown("unroute")
- exit 0
- } else # down
- print "{"
-
- # now do "down", unconditionally, since the desired output for "up"
- # is { up && up && up && true } || { down ; down ; down }
- # tear things down in fairly strict reverse order
- #if (s["leftfirewall"] == "yes")
- # print "ipfwadm -F -d accept -b -S", s["leftsubnet"],
- # "-D", s["rightsubnet"]
- updown("down")
- #print "route del", routeid, "dev", iface, "gw", s["leftnexthop"]
- print "# do not delete route"
- print "ipsec eroute --label", q(names), "--eraf inet --del", "\\"
- print "\t--src", s["leftsubnet"], "--dst", s["rightsubnet"]
- #if ("ah" in s) {
- # print "ipsec spi --label", q(names), "--af inet", "--del",
- # "--said", ("ah" raspi "@" me)
- #}
- #if ("esp" in s) {
- # print "ipsec spi --label", q(names), "--af inet", "--del",
- # "--said", ("esp" respi "@" me)
- #}
- if (!shunt) {
- if (type == "tunnel")
- p = "tun"
- else if (("esp" in s))
- p = "esp"
- else
- p = "ah"
- print "ipsec spi --label", q(names), "--af inet", "--del",
- "--said", (p tspi "@" him),
- " # outbound"
- print "ipsec spi --label", q(names), "--af inet", "--del",
- "--said", (p intspi "@" me),
- " # inbound"
- }
-
- if (op == "--up")
- print "} 2>/dev/null"
- else
- print "}"
- #########
- }' |
-if test $showonly
-then
- cat
-else
- sh $shopts
-fi
diff --git a/programs/openac/Makefile b/programs/openac/Makefile
deleted file mode 100644
index 98051f7bc..000000000
--- a/programs/openac/Makefile
+++ /dev/null
@@ -1,162 +0,0 @@
-# Makefile for the openac attribute certificate generation tool
-# Copyright (C) 2004 Andreas Steffen
-# Zuercher Hochschule Winterthur
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.17 2007/02/21 14:19:45 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-CONFDIR=$(DESTDIR)/etc/openac
-PLUTODIR=../pluto
-
-PROGRAM=openac
-EXTRA8PROC=${PROGRAM}.8
-
-# where to find sha2.h
-LIBCRYPTO=$(FREESWANSRCDIR)/lib/libcrypto
-LIBSHA2=$(LIBCRYPTO)/libsha2
-CFLAGS+= -I$(LIBCRYPTO)
-
-LIBS=${FREESWANLIB} $(LIBDESLITE) -lgmp
-CFLAGS+= -DDEBUG -DNO_PLUTO
-
-# This compile option activates the leak detective
-ifeq ($(USE_LEAK_DETECTIVE),true)
- CFLAGS+= -DLEAK_DETECTIVE
-endif
-
-X509_OBJS= ac.o asn1.o ca.o certs.o constants.o crl.o defs.o mp_defs.o fetch.o \
- id.o keys.o lex.o md2.o md5.o ocsp.o oid.o pem.o pgp.o pkcs1.o \
- rnd.o sha1.o sha2.o smartcard.o x509.o
-
-OBJS= build.o loglite.o ${X509_OBJS}
-
-include ../Makefile.program
-
-build.o : build.c build.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-loglite.o : loglite.c $(PLUTODIR)/log.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-# X.509 library
-
-ac.o : $(PLUTODIR)/ac.c $(PLUTODIR)/ac.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-certs.o : $(PLUTODIR)/certs.c $(PLUTODIR)/certs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-constants.o : $(PLUTODIR)/constants.c $(PLUTODIR)/constants.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-crl.o : $(PLUTODIR)/crl.c $(PLUTODIR)/crl.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-mp_defs.o : $(PLUTODIR)/mp_defs.c $(PLUTODIR)/mp_defs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-fetch.o : $(PLUTODIR)/fetch.c $(PLUTODIR)/fetch.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-id.o : $(PLUTODIR)/id.c $(PLUTODIR)/id.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-keys.o : $(PLUTODIR)/keys.c $(PLUTODIR)/keys.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-lex.o : $(PLUTODIR)/lex.c $(PLUTODIR)/lex.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-md2.o : $(PLUTODIR)/md2.c $(PLUTODIR)/md2.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-md5.o : $(PLUTODIR)/md5.c $(PLUTODIR)/md5.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-ocsp.o : $(PLUTODIR)/ocsp.c $(PLUTODIR)/ocsp.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-oid.o : $(PLUTODIR)/oid.c $(PLUTODIR)/oid.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pem.o : $(PLUTODIR)/pem.c $(PLUTODIR)/pem.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pgp.o : $(PLUTODIR)/pgp.c $(PLUTODIR)/pgp.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-sha2.o : $(LIBSHA2)/sha2.c $(LIBSHA2)/sha2.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-smartcard.o : $(PLUTODIR)/smartcard.c $(PLUTODIR)/smartcard.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-x509.o : $(PLUTODIR)/x509.c $(PLUTODIR)/x509.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-# Stolen from pluto/Makefile
-
-gatherdeps:
- @ls | grep '\.c$$' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
- @echo
- @ls | grep '\.c$$' | xargs grep '^#[ ]*include[ ]*"' | \
- sed -e 's/\.c:#[ ]*include[ ]*"/.o: /' -e 's/".*//'
-
-# Dependencies generated by "make gatherdeps":
-
-build.o: build.c
-loglite.o: loglite.c
-openac.o: openac.c
-
-build.o: ../pluto/constants.h
-build.o: ../pluto/defs.h
-build.o: ../pluto/oid.h
-build.o: ../pluto/asn1.h
-build.o: ../pluto/x509.h
-build.o: ../pluto/log.h
-build.o: build.h
-loglite.o: ../pluto/constants.h
-loglite.o: ../pluto/defs.h
-loglite.o: ../pluto/log.h
-loglite.o: ../pluto/whack.h
-openac.o: ../pluto/constants.h
-openac.o: ../pluto/defs.h
-openac.o: ../pluto/mp_defs.h
-openac.o: ../pluto/log.h
-openac.o: ../pluto/asn1.h
-openac.o: ../pluto/certs.h
-openac.o: ../pluto/x509.h
-openac.o: ../pluto/crl.h
-openac.o: ../pluto/keys.h
-openac.o: ../pluto/ac.h
-openac.o: build.h
diff --git a/programs/openac/build.c b/programs/openac/build.c
deleted file mode 100644
index bd3df6fee..000000000
--- a/programs/openac/build.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* Build a X.509 attribute certificate
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2004 Andreas Steffen
- * Zuercher Hochschule Winterthur, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: build.c,v 1.14 2005/09/06 11:47:57 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/oid.h"
-#include "../pluto/asn1.h"
-#include "../pluto/x509.h"
-#include "../pluto/log.h"
-
-#include "build.h"
-
-static u_char ASN1_group_oid_str[] = {
- 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
-};
-
-static const chunk_t ASN1_group_oid = strchunk(ASN1_group_oid_str);
-
-static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
- 0x06, 0x03,
- 0x55, 0x1d, 0x23
-};
-
-static const chunk_t ASN1_authorityKeyIdentifier_oid
- = strchunk(ASN1_authorityKeyIdentifier_oid_str);
-
-static u_char ASN1_noRevAvail_ext_str[] = {
- 0x30, 0x09,
- 0x06, 0x03,
- 0x55, 0x1d, 0x38,
- 0x04, 0x02,
- 0x05, 0x00
-};
-
-static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
-
-/*
- * build directoryName
- */
-static chunk_t
-build_directoryName(asn1_t tag, chunk_t name)
-{
- return asn1_wrap(tag, "m"
- , asn1_simple_object(ASN1_CONTEXT_C_4, name));
-}
-
-/*
- * build holder
- */
-static chunk_t
-build_holder(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , asn1_wrap(ASN1_CONTEXT_C_0, "mm"
- , build_directoryName(ASN1_SEQUENCE, user->issuer)
- , asn1_simple_object(ASN1_INTEGER, user->serialNumber)
- )
- , build_directoryName(ASN1_CONTEXT_C_1, user->subject));
-}
-
-/*
- * build v2Form
- */
-static chunk_t
-build_v2_form(void)
-{
- return asn1_wrap(ASN1_CONTEXT_C_0, "m"
- , build_directoryName(ASN1_SEQUENCE, signer->subject));
-}
-
-/*
- * build attrCertValidityPeriod
- */
-static chunk_t
-build_attr_cert_validity(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , timetoasn1(&notBefore, ASN1_GENERALIZEDTIME)
- , timetoasn1(&notAfter, ASN1_GENERALIZEDTIME));
-}
-
-/*
- * build attributes
- */
-static chunk_t
-build_ietfAttributes(ietfAttrList_t *list)
-{
- chunk_t ietfAttributes;
- ietfAttrList_t *item = list;
- size_t size = 0;
- u_char *pos;
-
- /* precalculate the total size of all values */
- while (item != NULL)
- {
- size_t len = item->attr->value.len;
-
- size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
- item = item->next;
- }
- pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
-
- while (list != NULL)
- {
- ietfAttr_t *attr = list->attr;
- asn1_t type = ASN1_NULL;
-
- switch (attr->kind)
- {
- case IETF_ATTRIBUTE_OCTETS:
- type = ASN1_OCTET_STRING;
- break;
- case IETF_ATTRIBUTE_STRING:
- type = ASN1_UTF8STRING;
- break;
- case IETF_ATTRIBUTE_OID:
- type = ASN1_OID;
- break;
- }
- mv_chunk(&pos, asn1_simple_object(type, attr->value));
-
- list = list->next;
- }
-
- return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
-}
-
-/*
- * build attribute type
- */
-static chunk_t
-build_attribute_type(const chunk_t type, chunk_t content)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , type
- , asn1_wrap(ASN1_SET, "m", content));
-}
-
-/*
- * build attributes
- */
-static chunk_t
-build_attributes(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "m"
- , build_attribute_type(ASN1_group_oid
- , build_ietfAttributes(groups)));
-}
-
-/*
- * build authorityKeyIdentifier
- */
-static chunk_t
-build_authorityKeyID(x509cert_t *signer)
-{
- chunk_t keyIdentifier = (signer->subjectKeyID.ptr == NULL)
- ? empty_chunk
- : asn1_simple_object(ASN1_CONTEXT_S_0
- , signer->subjectKeyID);
-
- chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1
- , signer->issuer);
-
- chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2
- , signer->serialNumber);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_authorityKeyIdentifier_oid
- , asn1_wrap(ASN1_OCTET_STRING, "m"
- , asn1_wrap(ASN1_SEQUENCE, "mmm"
- , keyIdentifier
- , authorityCertIssuer
- , authorityCertSerialNumber
- )
- )
- );
-}
-
-/*
- * build extensions
- */
-static chunk_t
-build_extensions(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mc"
- , build_authorityKeyID(signer)
- , ASN1_noRevAvail_ext);
-}
-
-/*
- * build attributeCertificateInfo
- */
-static chunk_t
-build_attr_cert_info(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm"
- , ASN1_INTEGER_1
- , build_holder()
- , build_v2_form()
- , ASN1_sha1WithRSA_id
- , asn1_simple_object(ASN1_INTEGER, serial)
- , build_attr_cert_validity()
- , build_attributes()
- , build_extensions());
-}
-
-/*
- * build an X.509 attribute certificate
- */
-chunk_t
-build_attr_cert(void)
-{
- chunk_t attributeCertificateInfo = build_attr_cert_info();
- chunk_t signatureValue = pkcs1_build_signature(attributeCertificateInfo
- , OID_SHA1, signerkey, TRUE);
-
- return asn1_wrap(ASN1_SEQUENCE, "mcm"
- , attributeCertificateInfo
- , ASN1_sha1WithRSA_id
- , signatureValue);
-}
diff --git a/programs/openac/build.h b/programs/openac/build.h
deleted file mode 100644
index deeddda04..000000000
--- a/programs/openac/build.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Build a X.509 attribute certificate
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2004 Andreas Steffen
- * Zuercher Hochschule Winterthur, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: build.h,v 1.4 2004/11/03 14:28:52 as Exp $
- */
-
-#ifndef _BUILD_H
-#define _BUILD_H
-
-#include <time.h>
-
-#include "../pluto/x509.h"
-#include "../pluto/keys.h"
-#include "../pluto/ac.h"
-
-/*
- * global variables accessible by both main() and build.c
- */
-extern x509cert_t *user;
-extern x509cert_t *signer;
-
-extern ietfAttrList_t *groups;
-extern struct RSA_private_key *signerkey;
-
-extern time_t notBefore;
-extern time_t notAfter;
-
-extern chunk_t serial;
-
-/*
- * exported functions
- */
-extern chunk_t build_attr_cert(void);
-
-#endif /* _BUILD_H */
diff --git a/programs/openac/loglite.c b/programs/openac/loglite.c
deleted file mode 100644
index b1763cc9f..000000000
--- a/programs/openac/loglite.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* error logging functions
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: loglite.c,v 1.2 2005/07/11 18:38:16 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
-#include <libgen.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-#include "../pluto/whack.h"
-
-bool
- log_to_stderr = FALSE, /* should log go to stderr? */
- log_to_syslog = TRUE; /* should log go to syslog? */
-
-void
-init_log(const char *program)
-{
- if (log_to_stderr)
- setbuf(stderr, NULL);
- if (log_to_syslog)
- openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
-}
-
-void
-close_log(void)
-{
- if (log_to_syslog)
- closelog();
-}
-
-void
-plog(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
-}
-
-void
-loglog(int mess_no, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
-}
-
-void
-log_errno_routine(int e, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
-}
-
-void
-exit_log(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s\n", m);
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s", m);
- exit(1);
-}
-
-void
-exit_log_errno_routine(int e, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- exit(1);
-}
-
-void
-whack_log(int mess_no, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- fprintf(stderr, "%s\n", m);
-}
-
-/* Build up a diagnostic in a static buffer.
- * Although this would be a generally useful function, it is very
- * hard to come up with a discipline that prevents different uses
- * from interfering. It is intended that by limiting it to building
- * diagnostics, we will avoid this problem.
- * Juggling is performed to allow an argument to be a previous
- * result: the new string may safely depend on the old one. This
- * restriction is not checked in any way: violators will produce
- * confusing results (without crashing!).
- */
-char diag_space[sizeof(diag_space)];
-
-err_t
-builddiag(const char *fmt, ...)
-{
- static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
- char t[sizeof(diag_space)]; /* build result here first */
- va_list args;
-
- va_start(args, fmt);
- t[0] = '\0'; /* in case nothing terminates string */
- vsnprintf(t, sizeof(t), fmt, args);
- va_end(args);
- strcpy(diag_space, t);
- return diag_space;
-}
-
-/* Debugging message support */
-
-#ifdef DEBUG
-
-void
-switch_fail(int n, const char *file_str, unsigned long line_no)
-{
- char buf[30];
-
- snprintf(buf, sizeof(buf), "case %d unexpected", n);
- passert_fail(buf, file_str, line_no);
-}
-
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
-{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- abort(); /* exiting correctly doesn't always work */
-}
-
-lset_t
- base_debugging = DBG_NONE, /* default to reporting nothing */
- cur_debugging = DBG_NONE;
-
-void
-pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
-{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
-}
-
-/* log a debugging message (prefixed by "| ") */
-
-void
-DBG_log(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "| %s\n", m);
- if (log_to_syslog)
- syslog(LOG_DEBUG, "| %s", m);
-}
-
-/* dump raw bytes in hex to stderr (for lack of any better destination) */
-
-void
-DBG_dump(const char *label, const void *p, size_t len)
-{
-# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
-# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
- char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
- char *bp;
- const unsigned char *cp = p;
-
- bp = buf;
-
- if (label != NULL && label[0] != '\0')
- {
- /* Handle the label. Care must be taken to avoid buffer overrun. */
- size_t llen = strlen(label);
-
- if (llen + 1 > sizeof(buf))
- {
- DBG_log("%s", label);
- }
- else
- {
- strcpy(buf, label);
- if (buf[llen-1] == '\n')
- {
- buf[llen-1] = '\0'; /* get rid of newline */
- DBG_log("%s", buf);
- }
- else if (llen < DUMP_LABEL_WIDTH)
- {
- bp = buf + llen;
- }
- else
- {
- DBG_log("%s", buf);
- }
- }
- }
-
- do {
- int i, j;
-
- for (i = 0; len!=0 && i!=4; i++)
- {
- *bp++ = ' ';
- for (j = 0; len!=0 && j!=4; len--, j++)
- {
- static const char hexdig[] = "0123456789abcdef";
-
- *bp++ = ' ';
- *bp++ = hexdig[(*cp >> 4) & 0xF];
- *bp++ = hexdig[*cp & 0xF];
- cp++;
- }
- }
- *bp = '\0';
- DBG_log("%s", buf);
- bp = buf;
- } while (len != 0);
-# undef DUMP_LABEL_WIDTH
-# undef DUMP_WIDTH
-}
-
-#endif /* DEBUG */
diff --git a/programs/openac/openac.8 b/programs/openac/openac.8
deleted file mode 100644
index 8e609a1b1..000000000
--- a/programs/openac/openac.8
+++ /dev/null
@@ -1,180 +0,0 @@
-.TH IPSEC_OPENAC 8 "29 September 2005"
-.SH NAME
-ipsec openac \- Generation of X.509 attribute certificates
-.SH SYNOPSIS
-.B ipsec
-.B openac
-[
-.B \-\-help
-] [
-.B \-\-version
-] [
-.B \-\-optionsfrom
-\fIfilename\fP
-] [
-.B \-\-quiet
-]
-.br
-\ \ \ [
-.B \-\-debug\(hyall
-] [
-.B \-\-debug\(hyparsing
-] [
-.B \-\-debug\(hyraw
-] [
-.B \-\-debug\(hyprivate
-]
-.br
-\ \ \ [
-.B \-\-days
-\fIdays\fP
-] [
-.B \-\-hours
-\fIhours\fP
-]
-.br
-\ \ \ [
-.B \-\-startdate
-\fIYYYYMMDDHHMMSSZ\fP
-] [
-.B \-\-stopdate
-\fIYYYYMMDDHHMMSSZ\fP
-]
-.br
-.B \ \ \ \-\-cert
-\fIcertfile\fP
-.B \-\-key
-\fIkeyfile\fP
-[
-.B \-\-password
-\fIpassword\fP
-]
-.br
-.B \ \ \ \-\-usercert
-\fIcertfile\fP
-.B \-\-groups
-\fIattr1,attr2,...\fP
-.B \-\-out
-\fIfilename\fP
-.SH DESCRIPTION
-.BR openac
-is intended to be used by an Authorization Authority (AA) to generate and sign
-X.509 attribute certificates. Currently only the inclusion of one ore several group
-attributes is supported. An attribute certificate is linked to a holder by
-including the issuer and serial number of the holder's X.509 certificate.
-.SH OPTIONS
-.TP
-\fB\-\-help\fP
-display the usage message.
-.TP
-\fB\-\-version\fP
-display the version of \fBopenac\fP.
-.TP
-\fB\-\-optionsfrom\fP\ \fIfilename\fP
-adds the contents of the file to the argument list.
-If \fIfilename\fP is a relative path then the file is searched in the directory
-\fI/etc/openac\fP.
-.TP
-\fB\-\-quiet\fP
-By default \fBopenac\fP logs all control output both to syslog and stderr.
-With the \fB\-\-quiet\fP option no output is written to stderr.
-.TP
-\fB\-\-days\fP\ \fIdays\fP
-Validity of the X.509 attribute certificate in days. If neiter the \fB\-\-days\fP\ nor
-the \fB\-\-hours\fP\ option is specified then a default validity interval of 1 day is assumed.
-The \fB\-\-days\fP\ option can be combined with the \fB\-\-hours\fP\ option.
-.TP
-\fB\-\-hours\fP\ \fIhours\fP
-Validity of the X.509 attribute certificate in hours. If neiter the \fB\-\-hours\fP\ nor
-the \fB\-\-days\fP\ option is specified then a default validity interval of 24 hours is assumed.
-The \fB\-\-hours\fP\ option can be combined with the \fB\-\-days\fP\ option.
-.TP
-\fB\-\-startdate\fP\ \fIYYYYMMDDHHMMSSZ\fP
-defines the \fBnotBefore\fP date when the X.509 attribute certificate becomes valid.
-The date \fIYYYYMMDDHHMMSS\fP must be specified in UTC (\fIZ\fPulu time).
-If the \fB\-\-startdate\fP option is not specified then the current date is taken as a default.
-
-.TP
-\fB\-\-stopdate\fP\ \fIYYYYMMDDHHMMSSZ\fP
-defines the \fBnotAfter\fP date when the X.509 attribute certificate will expire.
-The date \fIYYYYMMDDHHMMSS\fP must be specified in UTC (\fIZ\fPulu time).
-If the \fB\-\-stopdate\fP option is not specified then the default \fBnotAfter\fP value is computed
-by adding the validity interval specified by the \fB\-\-days\fP\ and/or \fB\-\-days\fP\ options
-to the \fBnotBefore\fP date.
-.TP
-\fB\-\-cert\fP\ \fIcertfile\fP
-specifies the file containing the X.509 certificate of the Authorization Authority.
-The certificate is stored either in PEM or DER format.
-.TP
-\fB\-\-key\fP\ \fIkeyfile\fP
-specifies the encrypted file containing the private RSA key of the Authoritzation
-Authority. The private key is stored in PKCS#1 format.
-.TP
-\fB\-\-password\fP\ \fIpassword\fP
-specifies the password with which the private RSA keyfile defined by the
-\fB\-\-key\fP option has been protected. If the option is missing then the
-password is prompted for on the command line.
-.TP
-\fB\-\-usercert\fP\ \fIcertfile\fP
-specifies file containing the X.509 certificate of the user to which the generated attribute
-certificate will apply. The certificate file is stored either in PEM or DER format.
-.TP
-\fB\-\-groups\fP\ \fIattr1,attr2\fP
-specifies a comma-separated list of group attributes that will go into the
-X.509 attribute certificate.
-.TP
-\fB\-\-out\fP\ \fIfilename\fP
-specifies the file where the generated X.509 attribute certificate will be stored to.
-.SS Debugging
-.LP
-\fBopenac\fP produces a prodigious amount of debugging information. To do so,
-it must be compiled with \-DDEBUG. There are several classes of debugging output,
-and \fBopenac\fP may be directed to produce a selection of them. All lines of
-debugging output are prefixed with ``|\ '' to distinguish them from error messages.
-.LP
-When \fBopenac\fP is invoked, it may be given arguments to specify
-which classes to output. The current options are:
-.TP
-\fB\-\-debug-raw\fP
-show the raw bytes of the parsed user and authorization authority certificates
-as well as of the generated X.509 attribute certificate.
-.TP
-\fB\-\-debug-parsing\fP
-show the parsed structure of user and authorization authority certificats
-as well as of the generated X.509 attribute certificate.
-.TP
-\fB\-\-debug-all\fP
-all of the above.
-.TP
-\fB\-\-debug-private\fP
-enables debugging output of the authorization authority's private key.
-.SH EXIT STATUS
-.LP
-The execution of \fBopenac\fP terminates with one of the following two exit codes:
-.TP
-0
-means that the attribute certificate was successfully generated and stored.
-.TP
-1
-means that something went wrong.
-.SH FILES
-\fI/etc/openac/serial\fP\ \ \ serial number of latest attribute certificate
-.SH SEE ALSO
-.LP
-The X.509 attribute certificates generated with \fBopenac\fP can be used to
-enforce group policies defined by \fIipsec.conf\fP(5). Use \fIipsec_auto\fP(8)
-to load and list X.509 attribute certificates.
-.LP
-For more information on X.509 attribute certificates, refer to the following
-IETF RFC:
-.IP
-RFC 3281 An Internet Attribute Certificate Profile for Authorization
-.SH HISTORY
-The \fBopenac\fP program was originally written by Ariane Seiler and Ueli Galizzi.
-The software was recoded by Andreas Steffen using strongSwan's X.509 library and
-the ASN.1 code synthesis functions written by Christoph Gysin and Christoph Zwahlen.
-All authors were with the Zurich University of Applied Sciences in Winterthur,
-Switzerland.
-.LP
-.SH BUGS
-Bugs should be reported to the <users@lists.strongswan.org> mailing list.
diff --git a/programs/openac/openac.c b/programs/openac/openac.c
deleted file mode 100755
index 524a302d7..000000000
--- a/programs/openac/openac.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/* Generation of X.509 attribute certificates
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2004 Andreas Steffen
- * Zuercher Hochschule Winterthur, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: openac.c,v 1.18 2006/01/04 21:12:33 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <time.h>
-#include <gmp.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/mp_defs.h"
-#include "../pluto/log.h"
-#include "../pluto/asn1.h"
-#include "../pluto/certs.h"
-#include "../pluto/x509.h"
-#include "../pluto/crl.h"
-#include "../pluto/keys.h"
-#include "../pluto/ac.h"
-
-#include "build.h"
-
-#define OPENAC_PATH "/etc/openac"
-#define OPENAC_SERIAL "/etc/openac/serial"
-
-const char openac_version[] = "openac 0.3";
-
-/* by default the CRL policy is lenient */
-bool strict_crl_policy = FALSE;
-
-/* by default pluto does not check crls dynamically */
-long crl_check_interval = 0;
-
-/* by default pluto logs out after every smartcard use */
-bool pkcs11_keep_state = FALSE;
-
-static void
-usage(const char *mess)
-{
- if (mess != NULL && *mess != '\0')
- fprintf(stderr, "%s\n", mess);
- fprintf(stderr
- , "Usage: openac"
- " [--help]"
- " [--version]"
- " [--optionsfrom <filename>]"
- " [--quiet]"
-#ifdef DEBUG
- " \\\n\t"
- " [--debug-all]"
- " [--debug-parsing]"
- " [--debug-raw]"
- " [--debug-private]"
-#endif
- " \\\n\t"
- " [--days <days>]"
- " [--hours <hours>]"
- " \\\n\t"
- " [--startdate <YYYYMMDDHHMMSSZ>]"
- " [--enddate <YYYYMMDDHHMMSSZ>]"
- " \\\n\t"
- " --cert <certfile>"
- " --key <keyfile>"
- " [--password <password>]"
- " \\\n\t"
- " --usercert <certfile>"
- " --groups <attr1,attr2,..>"
- " --out <filename>"
- "\n"
- );
- exit(mess == NULL? 0 : 1);
-}
-
-/*
- * read the last serial number from file
- */
-static chunk_t
-read_serial(void)
-{
- MP_INT number;
-
- char buf[BUF_LEN];
- char bytes[BUF_LEN];
-
- FILE *fd = fopen(OPENAC_SERIAL, "r");
-
- /* serial number defaults to 0 */
- size_t len = 1;
- bytes[0] = 0x00;
-
- if (fd)
- {
- if (fscanf(fd, "%s", buf))
- {
- err_t ugh = ttodata(buf, 0, 16, bytes, BUF_LEN, &len);
-
- if (ugh != NULL)
- plog(" error reading serial number from %s: %s"
- , OPENAC_SERIAL, ugh);
- }
- fclose(fd);
- }
- else
- plog(" file '%s' does not exist yet - serial number set to 01"
- , OPENAC_SERIAL);
-
- /* conversion of read serial number to a multiprecision integer
- * and incrementing it by one
- * and representing it as a two's complement octet string
- */
- n_to_mpz(&number, bytes, len);
- mpz_add_ui(&number, &number, 0x01);
- serial = mpz_to_n(&number, 1 + mpz_sizeinbase(&number, 2)/BITS_PER_BYTE);
- mpz_clear(&number);
-
- return serial;
-}
-
-/*
- * write back the last serial number to file
- */
-static void
-write_serial(chunk_t serial)
-{
- char buf[BUF_LEN];
-
- FILE *fd = fopen(OPENAC_SERIAL, "w");
-
- if (fd)
- {
- datatot(serial.ptr, serial.len, 16, buf, BUF_LEN);
- plog(" serial number is %s", buf);
- fprintf(fd, "%s\n", buf);
- fclose(fd);
- }
- else
- plog(" could not open file '%s' for writing", OPENAC_SERIAL);
-}
-
-/*
- * global variables accessible by both main() and build.c
- */
-x509cert_t *user = NULL;
-x509cert_t *signer = NULL;
-
-ietfAttrList_t *groups = NULL;
-struct RSA_private_key *signerkey = NULL;
-
-time_t notBefore = 0;
-time_t notAfter = 0;
-
-chunk_t serial;
-
-
-int
-main(int argc, char **argv)
-{
- char *keyfile = NULL;
- char *certfile = NULL;
- char *usercertfile = NULL;
- char *outfile = NULL;
-
- cert_t signercert = empty_cert;
- cert_t usercert = empty_cert;
-
- chunk_t attr_cert = empty_chunk;
- x509acert_t *ac = NULL;
-
- const time_t default_validity = 24*3600; /* 24 hours */
- time_t validity = 0;
-
- prompt_pass_t pass;
-
- pass.secret[0] = '\0';
- pass.prompt = TRUE;
- pass.fd = STDIN_FILENO;
-
- log_to_stderr = TRUE;
-
- /* handle arguments */
- for (;;)
- {
-# define DBG_OFFSET 256
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "quiet", no_argument, NULL, 'q' },
- { "cert", required_argument, NULL, 'c' },
- { "key", required_argument, NULL, 'k' },
- { "password", required_argument, NULL, 'p' },
- { "usercert", required_argument, NULL, 'u' },
- { "groups", required_argument, NULL, 'g' },
- { "days", required_argument, NULL, 'D' },
- { "hours", required_argument, NULL, 'H' },
- { "startdate", required_argument, NULL, 'S' },
- { "enddate", required_argument, NULL, 'E' },
- { "out", required_argument, NULL, 'o' },
-#ifdef DEBUG
- { "debug-all", no_argument, NULL, 'A' },
- { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
- { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
- { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
-#endif
- { 0,0,0,0 }
- };
-
- int c = getopt_long(argc, argv, "hv+:qc:k:p;u:g:D:H:S:E:o:", long_opts, NULL);
-
- /* Note: "breaking" from case terminates loop */
- switch (c)
- {
- case EOF: /* end of flags */
- break;
-
- case 0: /* long option already handled */
- continue;
-
- case ':': /* diagnostic already printed by getopt_long */
- case '?': /* diagnostic already printed by getopt_long */
- usage(NULL);
- break; /* not actually reached */
-
- case 'h': /* --help */
- usage(NULL);
- break; /* not actually reached */
-
- case 'v': /* --version */
- printf("%s\n", openac_version);
- exit(0);
- break; /* not actually reached */
-
- case '+': /* --optionsfrom <filename> */
- {
- char path[BUF_LEN];
-
- if (*optarg == '/') /* absolute pathname */
- strncpy(path, optarg, BUF_LEN);
- else /* relative pathname */
- snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg);
- optionsfrom(path, &argc, &argv, optind, stderr);
- /* does not return on error */
- }
- continue;
-
- case 'q': /* --quiet */
- log_to_stderr = TRUE;
- continue;
-
- case 'c': /* --cert */
- certfile = optarg;
- continue;
-
- case 'k': /* --key */
- keyfile = optarg;
- continue;
-
- case 'p': /* --key */
- pass.prompt = FALSE;
- strncpy(pass.secret, optarg, sizeof(pass.secret));
- continue;
-
- case 'u': /* --usercert */
- usercertfile = optarg;
- continue;
-
- case 'g': /* --groups */
- decode_groups(optarg, &groups);
- continue;
-
- case 'D': /* --days */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing number of days");
- {
- char *endptr;
- long days = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || days <= 0)
- usage("<days> must be a positive number");
- validity += 24*3600*days;
- }
- continue;
-
- case 'H': /* --hours */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing number of hours");
- {
- char *endptr;
- long hours = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || hours <= 0)
- usage("<hours> must be a positive number");
- validity += 3600*hours;
- }
- continue;
-
- case 'S': /* --startdate */
- if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
- usage("date format must be YYYYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 15 };
- notBefore = asn1totime(&date, ASN1_GENERALIZEDTIME);
- }
- continue;
-
- case 'E': /* --enddate */
- if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
- usage("date format must be YYYYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 15 };
- notAfter = asn1totime(&date, ASN1_GENERALIZEDTIME);
- }
- continue;
-
- case 'o': /* --outt */
- outfile = optarg;
- continue ;
-
-#ifdef DEBUG
- case 'A': /* --debug-all */
- base_debugging = DBG_ALL;
- continue;
-#endif
- default:
-#ifdef DEBUG
- if (c >= DBG_OFFSET)
- {
- base_debugging |= c - DBG_OFFSET;
- continue;
- }
-#undef DBG_OFFSET
-#endif
- bad_case(c);
- }
- break;
- }
-
- init_log("openac");
- cur_debugging = base_debugging;
-
- if (optind != argc)
- usage("unexpected argument");
-
- /* load the signer's RSA private key */
- if (keyfile != NULL)
- {
- err_t ugh = NULL;
-
- signerkey = alloc_thing(RSA_private_key_t, "RSA private key");
- ugh = load_rsa_private_key(keyfile, &pass, signerkey);
-
- if (ugh != NULL)
- {
- free_RSA_private_content(signerkey);
- pfree(signerkey);
- plog("%s", ugh);
- exit(1);
- }
- }
-
- /* load the signer's X.509 certificate */
- if (certfile != NULL)
- {
- if (!load_cert(certfile, "signer cert", &signercert))
- exit(1);
- signer = signercert.u.x509;
- }
-
- /* load the users's X.509 certificate */
- if (usercertfile != NULL)
- {
- if (!load_cert(usercertfile, "user cert", &usercert))
- exit(1);
- user = usercert.u.x509;
- }
-
- /* compute validity interval */
- validity = (validity)? validity : default_validity;
- notBefore = (notBefore) ? notBefore : time(NULL);
- notAfter = (notAfter) ? notAfter : notBefore + validity;
-
- /* build and parse attribute certificate */
- if (user != NULL && signer != NULL && signerkey != NULL)
- {
- /* read the serial number and increment it by one */
- serial = read_serial();
-
- attr_cert = build_attr_cert();
- ac = alloc_thing(x509acert_t, "x509acert");
- *ac = empty_ac;
- parse_ac(attr_cert, ac);
-
- /* write the attribute certificate to file */
- if (write_chunk(outfile, "attribute cert", attr_cert, 0022, TRUE))
- write_serial(serial);
- }
-
- /* delete all dynamic objects */
- if (signerkey != NULL)
- {
- free_RSA_private_content(signerkey);
- pfree(signerkey);
- }
- free_x509cert(signercert.u.x509);
- free_x509cert(usercert.u.x509);
- free_ietfAttrList(groups);
- free_acert(ac);
- pfree(serial.ptr);
-
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- exit(0);
-}
diff --git a/programs/pf_key/.cvsignore b/programs/pf_key/.cvsignore
deleted file mode 100644
index 323068235..000000000
--- a/programs/pf_key/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-pf_key
diff --git a/programs/pf_key/Makefile b/programs/pf_key/Makefile
deleted file mode 100644
index 6af45c8d1..000000000
--- a/programs/pf_key/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:28 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM:=pf_key
-EXTRA5MAN=${PROGRAM}.5
-
-LIBS:=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:28 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.3 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/pf_key/pf_key.5 b/programs/pf_key/pf_key.5
deleted file mode 100644
index f5eab9a96..000000000
--- a/programs/pf_key/pf_key.5
+++ /dev/null
@@ -1,122 +0,0 @@
-.TH IPSEC_PF_KEY 5 "29 Jun 2000"
-.\"
-.\" RCSID $Id: pf_key.5,v 1.1 2004/03/15 20:35:28 as Exp $
-.\"
-.SH NAME
-ipsec_pf_key \- lists PF_KEY sockets registered with KLIPS
-.SH SYNOPSIS
-.B cat
-.B /proc/net/pf_key
-.SH DESCRIPTION
-.I /proc/net/pf_key
-is a read-only file which lists the presently open PF_KEY sockets on the
-local system and their parameters.
-.PP
-Each line lists one PF_KEY socket.
-A table entry consists of:
-.IP + 3
-sock pointer (sock)
-.IP +
-PID of the socket owner (pid)
-.IP +
-flag to indicate if the socket is dead (d)
-.IP +
-socket wait queue (sleep)
-.IP +
-socket pointer (socket)
-.IP +
-next socket in chain (next)
-.IP +
-previous socket in chain (prev)
-.IP +
-last socket error (e)
-.IP +
-pointer to destruct routine (destruct)
-.IP +
-is this a reused socket (r)
-.IP +
-has this socket been zapped (z)
-.IP +
-socket family to which this socket belongs (fa)
-.IP +
-local port number (n)
-.IP +
-protocol version number (p)
-.IP +
-Receive queue bytes committed (r)
-.IP +
-Transmit queue bytes committed (w)
-.IP +
-option memory allocations (o)
-.IP +
-size of send buffer in bytes (sndbf)
-.IP +
-timestamp in seconds (stamp)
-.IP +
-socket flags (Flags)
-.IP +
-socket type (Type)
-.IP +
-connection state (St)
-.BR
-.SH EXAMPLES
-.TP
-.\".B "sock pid d sleep socket next prev e destruct r z fa n p r w o sndbf stamp Flags Type St"
-.TP
-.B c3b8c140 3553 0 c0599818 c05997fc 0 0 0 0 1 0 15 0 2 0 0 0 65535 0.103232 00000000 00000003 01
-.LP
-shows that there is one pf_key socket set up that starts at
-.BR c3b8c140 ,
-whose owning process has PID
-.BR 3553 ,
-the socket is not dead, its wait queue is at
-.BR c0599818 ,
-whose owning socket is at
-.BR c05997fc ,
-with no other sockets in the chain, no errors, no destructor, it is a
-reused socket which has not been zapped, from protocol family
-.BR 15
-(PF_KEY), local port number
-.BR 0 ,
-protocol socket version
-.BR 2 ,
-no memory allocated to transmit, receive or option queues, a send buffer
-of almost
-.BR 64kB ,
-a timestamp of
-.BR 0.103232 ,
-no flags set, type
-.BR 3 ,
-in state
-.BR 1 .
-.SH "FILES"
-/proc/net/pf_key
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_eroute(5), ipsec_spi(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_tncfg(8), ipsec_version(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: pf_key.5,v $
-.\" Revision 1.1 2004/03/15 20:35:28 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.4 2002/04/24 07:35:39 mcr
-.\" Moved from ./klips/utils/pf_key.5,v
-.\"
-.\" Revision 1.3 2001/01/23 23:51:49 rgb
-.\" Fix outdated references to /proc/net/ipsec_pf_key.
-.\"
-.\" Revision 1.2 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.1 2000/06/30 06:19:27 rgb
-.\" manpages for the last two /proc/net/ipsec* files that don't have a
-.\" corresponding utility.
-.\"
-.\"
-.\"
diff --git a/programs/pf_key/pf_key.8 b/programs/pf_key/pf_key.8
deleted file mode 100644
index dd42bf541..000000000
--- a/programs/pf_key/pf_key.8
+++ /dev/null
@@ -1,73 +0,0 @@
-.TH IPSEC_PF_KEY 8 "17 Oct 2001"
-.\"
-.\" RCSID $Id: pf_key.8,v 1.2 2005/07/07 19:07:43 as Exp $
-.\"
-.SH NAME
-pf_key \- shows pfkey messages emitted by the kernel
-.SH SYNOPSIS
-.B pf_key
-.B \-\-ah
-.B \-\-esp
-.B \-\-ipip
-.B \-\-ipcomp
-.B \-\-daemon
-.I file
-.BR hmac-md5-96 | hmac-sha1-96
-.SH DESCRIPTION
-.B pf_key
-is a program to open a PF_KEY socket and print all messages that are received
-from it. With no options, it will register itself to receive key requests for
-AH, ESP, IPIP and IPCOMP security associations. If given more specific
-options, then it will listen only to those protocols which are listed.
-.PP
-If the messages are recognized, the messages will be decoded.
-.PP
-If the option
-.B \-\-daemon
-is provided, then after doing the registrations, the program will fork
-into the background. The provided file will be opened and the process ID of
-the background process will be written to it. This option is present to
-present race conditions in regression testing.
-.SH EXAMPLES
-.TP
-.\".B "pfkey v.2 msg. type 3 seq=20 len=2 errno=22 satype=3"
-.SH "FILES"
-/proc/net/pf_key
-.SH "SEE ALSO"
-pf_key(5), ipsec(8), ipsec_manual(8), ipsec_eroute(5), ipsec_spi(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_tncfg(8), ipsec_version(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Michael Richardson <mcr@freeswan.org>
-.\"
-.\" $Log: pf_key.8,v $
-.\" Revision 1.2 2005/07/07 19:07:43 as
-.\" fixed man page type
-.\"
-.\" Revision 1.1 2004/03/15 20:35:28 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.4 2002/07/16 02:53:42 mcr
-.\" added --daemon <pidfile> to "ipsec pf_key" command.
-.\" this is used in *-trap-* tests to avoid race conditions between
-.\" registration of PF_KEY listeners and arrival of first test packet.
-.\"
-.\" Revision 1.3 2002/04/24 07:35:39 mcr
-.\" Moved from ./klips/utils/pf_key.8,v
-.\"
-.\" Revision 1.2 2001/11/23 07:23:14 mcr
-.\" pulled up klips2 Makefile and pf_key code.
-.\"
-.\" Revision 1.1.2.1 2001/10/23 18:49:12 mcr
-.\" renamed man page to section 8.
-.\" added --ah, --esp, --ipcomp and --ipip to control which
-.\" protocols are printed.
-.\" incomplete messages which include at least an sadb header are printed.
-.\"
-.\" Revision 1.1.2.1 2001/10/17 23:25:37 mcr
-.\" added "pk_key" program to dump raw kernel pf messages.
-.\" (program is still skeletal)
-.\"
-.\"
-.\"
diff --git a/programs/pf_key/pf_key.c b/programs/pf_key/pf_key.c
deleted file mode 100644
index af7365d65..000000000
--- a/programs/pf_key/pf_key.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * @(#) pfkey socket manipulator/observer
- *
- * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pf_key.c,v 1.2 2004/04/20 21:23:25 as Exp $
- *
- */
-
-/*
- * This program opens a pfkey socket and prints all messages that it sees.
- *
- * This can be used to diagnose problems.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#include <sys/socket.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-char *progname;
-uint32_t pfkey_seq = 0;
-int pfkey_sock;
-
-static void
-Usage(char *progname)
-{
- fprintf(stderr, "%s: Usage: %s [--help]\n"
- "\tby default listens for AH, ESP, IPIP and IPCOMP\n"
- "\t--daemon <file> fork before printing, stuffing the PID in the file\n"
- "\t--ah listen for AH messages\n"
- "\t--esp listen for ESP messages\n"
- "\t--ipip listen for IPIP messages\n"
- "\t--ipcomp listen for IPCOMP messages\n",
- progname, progname);
- exit(1);
-}
-
-void
-pfkey_register(uint8_t satype) {
- /* for registering SA types that can be negotiated */
- int error = 0;
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
-
- pfkey_extensions_init(extensions);
- if((error = pfkey_msg_hdr_build(&extensions[0],
- SADB_REGISTER,
- satype,
- 0,
- ++pfkey_seq,
- getpid()))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- progname, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
- progname, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
- if(write(pfkey_sock, pfkey_msg,
- pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) !=
- (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
- /* cleanup code here */
- fprintf(stderr, "%s: Trouble writing to channel PF_KEY.\n", progname);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
-}
-
-int dienow;
-
-void controlC(int foo)
-{
- fflush(stdout);
- printf("%s: Exiting on signal 15\n", progname);
- fflush(stderr);
- exit(0);
-}
-
-int
-main(int argc, char *argv[])
-{
- int opt;
- ssize_t readlen;
- unsigned char pfkey_buf[256];
- struct sadb_msg *msg;
- int fork_after_register;
- char *pidfilename;
-
- static int ah_register;
- static int esp_register;
- static int ipip_register;
- static int ipcomp_register;
-
- static struct option long_options[] =
- {
- {"help", no_argument, 0, 'h'},
- {"daemon", required_argument, 0, 'f'},
- {"ah", no_argument, &ah_register, 1},
- {"esp", no_argument, &esp_register, 1},
- {"ipip", no_argument, &ipip_register, 1},
- {"ipcomp", no_argument, &ipcomp_register, 1},
- };
-
- ah_register = 0;
- esp_register = 0;
- ipip_register = 0;
- ipcomp_register=0;
- dienow = 0;
- fork_after_register=0;
- pidfilename=NULL;
-
- progname = argv[0];
- if(strrchr(progname, '/')) {
- progname=strrchr(progname, '/')+1;
- }
-
- while((opt = getopt_long(argc, argv, "hf:",
- long_options, NULL)) != EOF) {
- switch(opt) {
- case 'f':
- pidfilename=optarg;
- fork_after_register=1;
- break;
- case 'h':
- Usage(progname);
- break;
- case '0':
- /* it was a long option with a flag */
- break;
- }
- }
-
- if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
- fprintf(stderr, "%s: failed to open PF_KEY family socket: %s\n",
- progname, strerror(errno));
- exit(1);
- }
-
- if(ah_register == 0 &&
- esp_register== 0 &&
- ipip_register==0 &&
- ipcomp_register==0) {
- ah_register=1;
- esp_register=1;
- ipip_register=1;
- ipcomp_register=1;
- }
-
- if(ah_register) {
- pfkey_register(SADB_SATYPE_AH);
- }
- if(esp_register) {
- pfkey_register(SADB_SATYPE_ESP);
- }
- if(ipip_register) {
- pfkey_register(SADB_X_SATYPE_IPIP);
- }
- if(ipcomp_register) {
- pfkey_register(SADB_X_SATYPE_COMP);
- }
-
- if(fork_after_register) {
- /*
- * to aid in regression testing, we offer to register
- * everything first, and then we fork. As part of this
- * we write the PID of the new process to a file
- * provided.
- */
- int pid;
- FILE *pidfile;
-
- fflush(stdout);
- fflush(stderr);
-
- pid=fork();
- if(pid!=0) {
- /* in parent! */
- exit(0);
- }
-
- if((pidfile=fopen(pidfilename, "w"))==NULL) {
- perror(pidfilename);
- } else {
- fprintf(pidfile, "%d", getpid());
- fclose(pidfile);
- }
- }
-
- signal(SIGINT, controlC);
- signal(SIGTERM, controlC);
-
- while((readlen = read(pfkey_sock, pfkey_buf, sizeof(pfkey_buf))) > 0) {
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- msg = (struct sadb_msg *)pfkey_buf;
-
- /* first, see if we got enough for an sadb_msg */
- if((size_t)readlen < sizeof(struct sadb_msg)) {
- printf("%s: runt packet of size: %d (<%lu)\n",
- progname, (int)readlen, (unsigned long)sizeof(struct sadb_msg));
- continue;
- }
-
- /* okay, we got enough for a message, print it out */
- printf("\npfkey v%d msg. type=%d(%s) seq=%d len=%d pid=%d errno=%d satype=%d(%s)\n",
- msg->sadb_msg_version,
- msg->sadb_msg_type,
- pfkey_v2_sadb_type_string(msg->sadb_msg_type),
- msg->sadb_msg_seq,
- msg->sadb_msg_len,
- msg->sadb_msg_pid,
- msg->sadb_msg_errno,
- msg->sadb_msg_satype,
- satype2name(msg->sadb_msg_satype));
-
- if((size_t)readlen != msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)
- {
- printf("%s: packet size read from socket=%d doesn't equal sadb_msg_len %d * %u; message not decoded\n",
- progname,
- (int)readlen,
- msg->sadb_msg_len,
- (int) IPSEC_PFKEYv2_ALIGN);
- continue;
- }
-
- pfkey_lib_debug = PF_KEY_DEBUG_PARSE_STRUCT;
- if (pfkey_msg_parse(msg, NULL, extensions, EXT_BITS_OUT)) {
- printf("%s: unparseable PF_KEY message.\n",
- progname);
- } else {
- printf("%s: parseable PF_KEY message.\n",
- progname);
- }
- }
- printf("%s: exited normally\n", progname);
- exit(0);
-}
-
-/*
- * $Log: pf_key.c,v $
- * Revision 1.2 2004/04/20 21:23:25 as
- * int cast fix for 64 bit platforms
- *
- * Revision 1.1 2004/03/15 20:35:28 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.15 2003/09/10 00:01:30 mcr
- * fixes for gcc 3.3 from Matthias Bethke <Matthias.Bethke@gmx.net>
- *
- * Revision 1.14 2002/10/09 03:12:05 dhr
- *
- * [kenb+dhr] 64-bit fixes
- *
- * Revision 1.13 2002/09/20 05:02:15 rgb
- * Cleaned up pfkey_lib_debug usage.
- *
- * Revision 1.12 2002/09/13 23:02:23 rgb
- * Type fiddling to tame ia64 compiler.
- * Added text labels to elucidate numeric values presented.
- *
- * Revision 1.11 2002/08/26 03:05:25 mcr
- * duh, pf_key much catch SIGTERM as well as SIGINT...
- *
- * Revision 1.10 2002/08/13 19:01:27 mcr
- * patches from kenb to permit compilation of FreeSWAN on ia64.
- * des library patched to use proper DES_LONG type for ia64.
- *
- * Revision 1.9 2002/07/16 02:53:42 mcr
- * added --daemon <pidfile> to "ipsec pf_key" command.
- * this is used in *-trap-* tests to avoid race conditions between
- * registration of PF_KEY listeners and arrival of first test packet.
- *
- * Revision 1.8 2002/06/17 04:32:55 mcr
- * exit nicely from pf_key when SIGINT (^C) is sent.
- * This is needed so that the stdout will flush properly.
- *
- * Revision 1.7 2002/04/24 07:55:32 mcr
- * #include patches and Makefiles for post-reorg compilation.
- *
- * Revision 1.6 2002/04/24 07:35:39 mcr
- * Moved from ./klips/utils/pf_key.c,v
- *
- * Revision 1.5 2002/03/08 21:44:04 rgb
- * Update for all GNU-compliant --version strings.
- *
- * Revision 1.4 2001/11/27 05:19:06 mcr
- * added extra newline between packets.
- * set pfkey_lib_debug to enum rather than just to "1".
- *
- * Revision 1.3 2001/11/27 03:35:29 rgb
- * Added stdlib *again*.
- *
- * Revision 1.2 2001/11/23 07:23:14 mcr
- * pulled up klips2 Makefile and pf_key code.
- *
- * Revision 1.1.2.5 2001/10/23 18:49:12 mcr
- * renamed man page to section 8.
- * added --ah, --esp, --ipcomp and --ipip to control which
- * protocols are printed.
- * incomplete messages which include at least an sadb header are printed.
- *
- * Revision 1.1.2.4 2001/10/22 21:50:51 rgb
- * Added pfkey register for AH, ESP, IPIP and COMP.
- *
- * Revision 1.1.2.3 2001/10/21 21:51:06 rgb
- * Bug fixes to get working.
- *
- * Revision 1.1.2.2 2001/10/20 22:45:31 rgb
- * Added check for exact length and a call to message parser to get some
- * idea of the contents of each extension.
- *
- * Revision 1.1.2.1 2001/10/17 23:25:37 mcr
- * added "pk_key" program to dump raw kernel pf messages.
- * (program is still skeletal)
- *
- *
- * Local variables:
- * c-file-style: "linux"
- * End:
- *
- */
diff --git a/programs/pluto/.cvsignore b/programs/pluto/.cvsignore
deleted file mode 100644
index fb96dae41..000000000
--- a/programs/pluto/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-_pluto_adns
-pluto
-whack
diff --git a/programs/pluto/Makefile b/programs/pluto/Makefile
deleted file mode 100644
index d466d0209..000000000
--- a/programs/pluto/Makefile
+++ /dev/null
@@ -1,1090 +0,0 @@
-# Pluto Makefile
-# Copyright (C) 1997 Angelos D. Keromytis.
-# Copyright (C) 1998-2001 D. Hugh Redelmeier
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.49 2007/01/29 08:27:19 as Exp $
-
-# relative path to top directory of FreeS/WAN source
-# Note: referenced in ${FREESWANSRCDIR}/Makefile.inc
-FREESWANSRCDIR=../..
-
-include ${FREESWANSRCDIR}/Makefile.inc
-
-FMANDIR=$(MANTREE)/man5
-PMANDIR=$(MANTREE)/man8
-
-# -O on Linux makes gcc coredump when compiling sha1.c
-# -Wundef is nice but RHL5.2 compiler doesn't support it
-CFLAGS = -g -Wall -W -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast \
- -Wcast-qual -Wmissing-declarations -Wwrite-strings \
- -Wstrict-prototypes # -Wundef
-
-# where to find klips headers and FreeS/WAN headers
-HDRDIRS = -I$(KLIPSINC) -I${FREESWANSRCDIR}/programs/pluto/linux26
-
-# where to find sha2.h
-LIBCRYPTO=$(FREESWANSRCDIR)/lib/libcrypto
-HDRDIRS += -I$(LIBCRYPTO)
-
-# On non-LINUX systems, these one of these may be needed (see endian.h)
-# BYTE_ORDER = -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234 -DBYTE_ORDER=BIG_ENDIAN
-# BYTE_ORDER = -DBIG_ENDIAN=4321 -DLITTLE_ENDIAN=1234 -DBYTE_ORDER=LITTLE_ENDIAN
-
-# -DKLIPS enables interface to Kernel LINUX IPsec code
-# -DDEBUG enables debugging code, allowing for debugging output
-# (note that output must also be selected at runtime, so it is
-# reasonable to always define this)
-# -DVENDORID enables Pluto to send out a VendorID payload.
-# this can be used by remote nodes to work around faults (bugs),
-# but is most useful to humans who are debugging things.
-# -DGCC_LINT uses gcc-specific declarations to improve compile-time
-# diagnostics.
-# -DLEAK_DETECTIVE enables crude code to find memory allocation leaks.
-# -DOLD_RESOLVER. At some point, the resolver interface changed.
-# This macro enables Pluto support for the old interface.
-# It is automatically defined, based on the value of the <resolver.h>
-# macro __RES. We don't know the correct threshold, so you may
-# find that you must manually define this. If so, please inform
-# us so that we can refine the threshold.
-# -DLIBCURL includes libcurl functions for the support of http-based protocols.
-# -DLDAP_VER includes openldap functions for the support of ldap-based queries.
-# LDAPv2 and LDAPv3 are supported.
-# -DTHREADS enables an asynchronous thread managing CRL fetching.
-# This option is activated either by -DLIBCURL or -DLDAP_VER.
-# -DSMARTCARD enables PKCS11-based smartcard support
-# -DPKCS11_DEFAULT_LIB defines a default PKCS11 library module which will be
-# loaded during runtime and is overridden by the pkcs11module parameter in
-# ipsec.conf. This option is activated by -DSMARTCARD.
-# -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-# allows IPsec transport mode in NAT-ed environments. Because of the
-# inherent security risks of such scenarios this options is deactivated
-# by default.
-
-# The following are best left undefined -- each can be overridden at runtime
-# if need be.
-# -DPORT=n sets the default UDP port for IKE messages (otherwise 500)
-# -DSHARED_SECRETS_FILE=string overrides /etc/ipsec.secrets as the
-# default name of the file containing secrets used to authenticate other
-# IKE daemons. In the Makefile, two levels of quoting are needed:
-# -DSHARED_SECRETS_FILE='"/etc/ipsec.secrets"'
-# -DDEFAULT_CTLBASE=string overrides /var/run/pluto as default directory
-# and basename for pluto's lockfile (.pid) and control socket (.ctl).
-# Double quoting may be needed.
-
-ifeq ($(USE_LWRES),true)
- LWRESDEF=-DUSE_LWRES
- USE_ADNS=false
- BINNAMEADNSIFNEEDE=
-else
- USE_ADNS=true
- BINNAMEADNSIFNEEDED=$(BINNAMEADNS)
-endif
-
-ifeq ($(USE_KEYRR),true)
- KEYRR_DEFINES=-DUSE_KEYRR
-endif
-
-ifeq ($(USE_KERNEL26),true)
- KERNEL26_DEFS=-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES
- KERNEL26_SRCS=kernel_netlink.c kernel_netlink.h
- KERNEL26_OBJS=kernel_netlink.o
-endif
-
-ifeq ($(USE_NAT_TRAVERSAL),true)
- NAT_DEFS=-DNAT_TRAVERSAL -DVIRTUAL_IP
-endif
-
-ifeq ($(USE_NAT_TRAVERSAL_TRANSPORT_MODE),true)
- NAT_DEFS+=-DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-endif
-
-DEFINES = $(EXTRA_DEFINES) \
- $(IPSECPOLICY_DEFINES) \
- $(KEYRR_DEFINES) \
- $(BYTE_ORDER) \
- $(LWRESDEF) \
- $(KERNEL26_DEFS) \
- -DPLUTO \
- -DKLIPS \
- -DDEBUG \
- -DGCC_LINT \
- $(NAT_DEFS)
-
-# libefence is a free memory allocation debugger
-# Solaris 2 needs -lsocket -lnsl
-LIBSPLUTO = $(OBJSGCRYPT) $(LIBDESLITE) $(FREESWANLIB) $(IPSECPOLICY_LIBS)
-LIBSPLUTO+= -lgmp -ldl -lresolv # -lefence
-
-
-ifeq ($(USE_VENDORID),true)
- DEFINES+= -DVENDORID
-endif
-
-ifeq ($(USE_CISCO_QUIRKS),true)
- DEFINES+= -DCISCO_QUIRKS
-endif
-
-# This compile option activates dynamic URL fetching using libcurl
-ifeq ($(USE_LIBCURL),true)
- DEFINES+= -DLIBCURL
- LIBSPLUTO+= -lcurl
- THREADS=1 # Asynchronous cURL queries require threads
-endif
-
-# This compile option activates dynamic LDAP CRL fetching
-ifeq ($(USE_LDAP),true)
- DEFINES+= -DLDAP_VER=$(LDAP_VERSION)
- LIBSPLUTO+= -lldap -llber
- THREADS=1 # Asynchronous LDAP queries require threads
-endif
-
-# This compile option activates the use of threads
-ifdef THREADS
- DEFINES+= -DTHREADS
- LIBSPLUTO+= -lpthread
-endif
-
-# This compile option activates smartcard support
-ifeq ($(USE_SMARTCARD),true)
- DEFINES+= -DSMARTCARD
- ifdef PKCS11_DEFAULT_LIB
- DEFINES+= -DPKCS11_DEFAULT_LIB=$(PKCS11_DEFAULT_LIB)
- endif
-endif
-
-# This compile option activates the leak detective
-ifeq ($(USE_LEAK_DETECTIVE),true)
- DEFINES+= -DLEAK_DETECTIVE
-endif
-
-CPPFLAGS = $(HDRDIRS) $(DEFINES) \
- -DSHARED_SECRETS_FILE=\"${FINALCONFDIR}/ipsec.secrets\" \
- -DPOLICYGROUPSDIR=\"${FINALCONFDDIR}/policies\" \
- -DPERPEERLOGDIR=\"${FINALLOGDIR}/pluto/peer\"
-
-ALLFLAGS = $(CPPFLAGS) $(CFLAGS) $(USERCOMPILE)
-
-ifneq ($(LD_LIBRARY_PATH),)
- LDFLAGS=-L$(LD_LIBRARY_PATH)
-endif
-
-LIBSADNS = $(FREESWANLIB)
-LIBSADNS += -lresolv # -lefence
-
-# Solaris needs -lsocket -lnsl
-LIBSWHACK = ${FREESWANLIB}
-
-BINNAMEPLUTO = pluto
-BINNAMEWHACK = whack
-BINNAMEADNS = _pluto_adns
-
-RM = /bin/rm
-RMFLAGS = -f
-
-.SUFFIXES:
-.SUFFIXES: .c .o
-
-# files for a (source) distribution
-
-DISTMISC = CHANGES PLUTO-CONVENTIONS TODO ipsec.secrets Makefile routing.txt \
- pluto.8 ipsec.secrets.5 .cvsignore
-
-DISTGCRYPT = \
- gcryptfix.c gcryptfix.h \
- dsa.c dsa.h \
- elgamal.c elgamal.h \
- primegen.c \
- smallprime.c
-
-DISTSRC = \
- ac.c ac.h \
- asn1.c asn1.h \
- ca.c ca.h \
- certs.c certs.h \
- connections.c connections.h \
- crl.c crl.h \
- foodgroups.c foodgroups.h \
- constants.c constants.h \
- cookie.c cookie.h \
- crypto.h crypto.c \
- defs.h defs.c \
- mp_defs.h mp_defs.c \
- demux.c demux.h \
- dnskey.c dnskey.h \
- fetch.c fetch.h \
- id.c id.h \
- ipsec_doi.c ipsec_doi.h \
- kernel.c kernel.h \
- kernel_netlink.c kernel_netlink.h \
- kernel_pfkey.c kernel_pfkey.h \
- kernel_noklips.c kernel_noklips.h \
- kernel_alg.c kernel_alg.h \
- ike_alg.c ike_alg.h \
- alg_info.c alg_info.h \
- rcv_whack.c rcv_whack.h \
- $(IPSECPOLICY_FILES) \
- log.c log.h \
- plutomain.c \
- md2.c md2.h \
- md5.c md5.h \
- modecfg.c modecfg.h \
- ocsp.c ocsp.h \
- oid.txt oid.pl oid.c oid.h \
- packet.c packet.h \
- pem.c pem.h \
- pgp.c pgp.h \
- pkcs1.c pkcs1.h \
- pkcs7.c pkcs7.h \
- lex.c lex.h \
- keys.c keys.h \
- rnd.c rnd.h \
- server.c server.h \
- sha1.c sha1.h \
- smartcard.c smartcard.h \
- spdb.c spdb.h \
- state.c state.h \
- timer.c timer.h \
- xauth.c xauth.h \
- x509.c x509.h \
- $(DISTGCRYPT) \
- vendor.c nat_traversal.c virtual.c \
- adns.c adns.h \
- whack.c whack.h
-
-DIST = $(DISTMISC) $(DISTSRC)
-
-
-# start of support for DSS/DSA. Not currently used.
-# OBJSGCRYPT = gcryptfix.o dsa.o elgamal.o primegen.o smallprime.o
-OBJSGCRYPT =
-
-OBJSPLUTO = asn1.o connections.o constants.o cookie.o crypto.o defs.o fetch.o foodgroups.o \
- log.o state.o plutomain.o server.o timer.o oid.o pem.o pgp.o pkcs1.o pkcs7.o x509.o \
- ca.o certs.o id.o ipsec_doi.o kernel.o $(KERNEL26_OBJS) kernel_pfkey.o mp_defs.o \
- kernel_noklips.o rcv_whack.o ${IPSECPOLICY_OBJS} demux.o packet.o lex.o keys.o \
- dnskey.o smartcard.o ac.o rnd.o spdb.o sha1.o md5.o md2.o modecfg.o ocsp.o crl.o \
- vendor.o nat_traversal.o virtual.o xauth.o
-
-OBJSADNS = adns.o
-
-OBJSWHACK = whack.o
-
-all: $(BINNAMEPLUTO) $(BINNAMEADNSIFNEEDED) $(BINNAMEWHACK)
-programs: $(BINNAMEPLUTO) $(BINNAMEADNSIFNEEDED) $(BINNAMEWHACK)
-
-oid.c: oid.txt oid.pl
- perl oid.pl
-
-oid.h: oid.txt oid.pl
- perl oid.pl
-
-install: all
- mkdir -p ${LIBEXECDIR} ${LIBDIR}
- mkdir -p -m 755 $(CONFDIR)/ipsec.d
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/cacerts
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/ocspcerts
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/certs
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/acerts
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/aacerts
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/crls
- mkdir -p -m 755 $(CONFDIR)/ipsec.d/reqs
- mkdir -p -m 700 $(CONFDIR)/ipsec.d/private
- $(INSTALL) $(INSTBINFLAGS) $(BINNAMEPLUTO) $(BINNAMEWHACK) $(LIBEXECDIR)
- if $(USE_ADNS) ; then $(INSTALL) $(INSTBINFLAGS) $(BINNAMEADNS) $(LIBDIR) ; fi
- $(INSTALL) $(INSTMANFLAGS) pluto.8 $(PMANDIR)/ipsec_pluto.8
- sh ${FREESWANSRCDIR}/packaging/utils/manlink pluto.8 | \
- while read from to ; \
- do \
- ln -s -f ipsec_$$from $(PMANDIR)/$$to; \
- done
- $(INSTALL) $(INSTMANFLAGS) ipsec.secrets.5 $(FMANDIR)
- sh ${FREESWANSRCDIR}/packaging/utils/manlink ipsec.secrets.5 | \
- while read from to ; \
- do \
- ln -s -f $$from $(FMANDIR)/$$to; \
- done
-
-install_file_list:
- @echo $(LIBEXECDIR)/$(BINNAMEPLUTO)
- @if $(USE_ADNS) ; then echo $(LIBDIR)/$(BINNAMEADNS) ; fi
- @echo $(LIBEXECDIR)/$(BINNAMEWHACK)
- @echo $(PMANDIR)/ipsec_pluto.8
- @sh ${FREESWANSRCDIR}/packaging/utils/manlink pluto.8 | \
- while read from to; \
- do\
- echo $(PMANDIR)/$$to; \
- done
- @echo $(FMANDIR)/ipsec.secrets.5
- @sh ${FREESWANSRCDIR}/packaging/utils/manlink ipsec.secrets.5 | \
- while read from to; \
- do \
- echo $(FMANDIR)/$$to; \
- done
-
-alg_info_test: alg_info_test.o alg_info.o kernel_alg.o ike_alg.o constants.o defs.o log.o db_ops.o crypto.o $(LIBDESLITE) $(FREESWANLIB)
- $(CC) -o $@ $^ $(LIBSPLUTO)
-
-# alg/libalg.o contains an already resolved object built with
-# additional crypto algos inside.
-OBJSPLUTO:= kernel_alg.o ike_alg.o alg_info.o db_ops.o $(OBJSPLUTO) alg/libalg.o
-# if new alg source is created in alg directory,
-# trigger libalg.o rebuild
-alg/libalg.o: alg alg/Config.ike_alg
- make -C alg libalg.o
- touch alg/libalg.o
-
-# helper for creating alg/Make.common
-showdefs:
- @echo DEFINES=$(DEFINES)
- @echo CFLAGS=$(CFLAGS)
- @echo CPPFLAGS=$(CPPFLAGS)
- @echo COPTS=$(COPTS)
-
-$(BINNAMEPLUTO): $(OBJSPLUTO) $(ALG_LIBS)
- $(CC) -o $(BINNAMEPLUTO) $(LDFLAGS) $(OBJSPLUTO) $(LIBSPLUTO)
-
-$(BINNAMEADNS): $(OBJSADNS)
- $(CC) -o $(BINNAMEADNS) $(OBJSADNS) $(LIBSADNS)
-
-$(BINNAMEWHACK): $(OBJSWHACK)
- $(CC) -o $(BINNAMEWHACK) $(OBJSWHACK) $(LIBSWHACK)
-
-distlist:
- @echo $(DIST)
-
-# Exuberant Ctags doesn't work if LC_ALL is set to something other than C
-
-CTAGSFLAGS = -N --format=1 # fishy options required for Exuberant Ctags
-
-tags: $(DISTSRC)
- LC_ALL=C ctags $(CTAGSFLAGS) $(DISTSRC) $(LIBFREESWANDIR)/*.[ch]
-
-TAGS: $(DISTSRC)
- LC_ALL=C etags $(ETAGSFLAGS) $(DISTSRC) $(LIBFREESWANDIR)/*.[ch]
-
-cleanall: clean
-
-distclean: clean
-
-mostlyclean: clean
-
-realclean: clean
-
-clean:
- $(RM) $(RMFLAGS) *.core core *~ a.out ktrace.out \
- $(OBJSPLUTO) $(BINNAMEPLUTO) \
- $(OBJSWHACK) $(BINNAMEWHACK) \
- $(OBJSADNS) $(BINNAMEADNS)
- make -C alg clean
-
-check:
- echo no checks in lib right now.
-
-checkprograms:
-
-.c.o:
- $(CC) $(COPTS) $(ALLFLAGS) -c $<
-
-# Gather dependencies caused by explicit #includes within .c files
-#
-# Each .c is assumed to compile into a .o with the corresponding name.
-# Only dependencies on based on "" includes are considered, not <>.
-# Dependencies caused by includes within headers are not noticed.
-# Unlike dependencies generated by the compiler, these include dependencies
-# suppressed by conditional compilation (good, we think).
-# This code can be tricked by embeding #include in comments or
-# vice-versa, but we're among friends.
-
-gatherdeps:
- @ls $(DISTSRC) | grep '\.c' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
- @echo
- @ls $(DISTSRC) | grep '\.c' | xargs grep '^#[ ]*include[ ]*"' | \
- sed -e 's/\.c:#[ ]*include[ ]*"/.o: /' -e 's/".*//'
-
-# Dependencies generated by "make gatherdeps":
-
-ac.o: ac.c
-adns.o: adns.c
-alg_info.o: alg_info.c
-asn1.o: asn1.c
-ca.o: ca.c
-certs.o: certs.c
-connections.o: connections.c
-constants.o: constants.c
-cookie.o: cookie.c
-crl.o: crl.c
-crypto.o: crypto.c
-defs.o: defs.c
-demux.o: demux.c
-dnskey.o: dnskey.c
-dsa.o: dsa.c
-elgamal.o: elgamal.c
-fetch.o: fetch.c
-foodgroups.o: foodgroups.c
-gcryptfix.o: gcryptfix.c
-id.o: id.c
-ike_alg.o: ike_alg.c
-ipsec_doi.o: ipsec_doi.c
-kernel.o: kernel.c
-kernel_alg.o: kernel_alg.c
-kernel_netlink.o: kernel_netlink.c
-kernel_noklips.o: kernel_noklips.c
-kernel_pfkey.o: kernel_pfkey.c
-keys.o: keys.c
-lex.o: lex.c
-log.o: log.c
-md2.o: md2.c
-md5.o: md5.c
-modecfg.o: modecfg.c
-mp_defs.o: mp_defs.c
-nat_traversal.o: nat_traversal.c
-ocsp.o: ocsp.c
-oid.o: oid.c
-packet.o: packet.c
-pem.o: pem.c
-pgp.o: pgp.c
-pkcs1.o: pkcs1.c
-pkcs7.o: pkcs7.c
-plutomain.o: plutomain.c
-primegen.o: primegen.c
-rcv_whack.o: rcv_whack.c
-rnd.o: rnd.c
-server.o: server.c
-sha1.o: sha1.c
-smallprime.o: smallprime.c
-smartcard.o: smartcard.c
-spdb.o: spdb.c
-state.o: state.c
-timer.o: timer.c
-vendor.o: vendor.c
-virtual.o: virtual.c
-whack.o: whack.c
-x509.o: x509.c
-xauth.o: xauth.c
-
-ac.o: constants.h
-ac.o: defs.h
-ac.o: asn1.h
-ac.o: oid.h
-ac.o: ac.h
-ac.o: x509.h
-ac.o: crl.h
-ac.o: ca.h
-ac.o: certs.h
-ac.o: log.h
-ac.o: whack.h
-ac.o: fetch.h
-adns.o: constants.h
-adns.o: adns.h
-alg_info.o: alg_info.h
-alg_info.o: constants.h
-alg_info.o: defs.h
-alg_info.o: log.h
-alg_info.o: whack.h
-alg_info.o: sha1.h
-alg_info.o: md5.h
-alg_info.o: crypto.h
-alg_info.o: kernel_alg.h
-alg_info.o: ike_alg.h
-asn1.o: constants.h
-asn1.o: defs.h
-asn1.o: mp_defs.h
-asn1.o: asn1.h
-asn1.o: oid.h
-asn1.o: log.h
-ca.o: constants.h
-ca.o: defs.h
-ca.o: log.h
-ca.o: x509.h
-ca.o: ca.h
-ca.o: certs.h
-ca.o: whack.h
-ca.o: fetch.h
-certs.o: constants.h
-certs.o: defs.h
-certs.o: log.h
-certs.o: asn1.h
-certs.o: id.h
-certs.o: x509.h
-certs.o: pgp.h
-certs.o: pem.h
-certs.o: certs.h
-certs.o: pkcs1.h
-connections.o: kameipsec.h
-connections.o: constants.h
-connections.o: defs.h
-connections.o: id.h
-connections.o: x509.h
-connections.o: ca.h
-connections.o: crl.h
-connections.o: pgp.h
-connections.o: certs.h
-connections.o: ac.h
-connections.o: smartcard.h
-connections.o: fetch.h
-connections.o: connections.h
-connections.o: foodgroups.h
-connections.o: demux.h
-connections.o: state.h
-connections.o: timer.h
-connections.o: ipsec_doi.h
-connections.o: server.h
-connections.o: kernel.h
-connections.o: log.h
-connections.o: keys.h
-connections.o: adns.h
-connections.o: dnskey.h
-connections.o: whack.h
-connections.o: alg_info.h
-connections.o: ike_alg.h
-connections.o: kernel_alg.h
-connections.o: nat_traversal.h
-connections.o: virtual.h
-constants.o: constants.h
-constants.o: defs.h
-constants.o: log.h
-constants.o: packet.h
-cookie.o: constants.h
-cookie.o: defs.h
-cookie.o: sha1.h
-cookie.o: rnd.h
-cookie.o: cookie.h
-crl.o: constants.h
-crl.o: defs.h
-crl.o: log.h
-crl.o: asn1.h
-crl.o: oid.h
-crl.o: x509.h
-crl.o: crl.h
-crl.o: ca.h
-crl.o: certs.h
-crl.o: keys.h
-crl.o: whack.h
-crl.o: fetch.h
-crl.o: sha1.h
-crypto.o: constants.h
-crypto.o: defs.h
-crypto.o: state.h
-crypto.o: log.h
-crypto.o: md5.h
-crypto.o: sha1.h
-crypto.o: crypto.h
-crypto.o: alg_info.h
-crypto.o: ike_alg.h
-defs.o: constants.h
-defs.o: defs.h
-defs.o: log.h
-defs.o: whack.h
-demux.o: constants.h
-demux.o: defs.h
-demux.o: cookie.h
-demux.o: connections.h
-demux.o: state.h
-demux.o: packet.h
-demux.o: md5.h
-demux.o: sha1.h
-demux.o: crypto.h
-demux.o: ike_alg.h
-demux.o: log.h
-demux.o: demux.h
-demux.o: ipsec_doi.h
-demux.o: timer.h
-demux.o: whack.h
-demux.o: server.h
-demux.o: nat_traversal.h
-demux.o: vendor.h
-demux.o: modecfg.h
-dnskey.o: constants.h
-dnskey.o: adns.h
-dnskey.o: defs.h
-dnskey.o: log.h
-dnskey.o: id.h
-dnskey.o: connections.h
-dnskey.o: keys.h
-dnskey.o: dnskey.h
-dnskey.o: packet.h
-dnskey.o: timer.h
-dsa.o: constants.h
-dsa.o: defs.h
-dsa.o: log.h
-dsa.o: rnd.h
-dsa.o: gcryptfix.h
-dsa.o: dsa.h
-elgamal.o: constants.h
-elgamal.o: defs.h
-elgamal.o: log.h
-elgamal.o: rnd.h
-elgamal.o: gcryptfix.h
-elgamal.o: elgamal.h
-fetch.o: constants.h
-fetch.o: defs.h
-fetch.o: log.h
-fetch.o: id.h
-fetch.o: asn1.h
-fetch.o: pem.h
-fetch.o: x509.h
-fetch.o: ca.h
-fetch.o: whack.h
-fetch.o: ocsp.h
-fetch.o: crl.h
-fetch.o: fetch.h
-foodgroups.o: constants.h
-foodgroups.o: defs.h
-foodgroups.o: connections.h
-foodgroups.o: foodgroups.h
-foodgroups.o: kernel.h
-foodgroups.o: lex.h
-foodgroups.o: log.h
-foodgroups.o: whack.h
-gcryptfix.o: constants.h
-gcryptfix.o: defs.h
-gcryptfix.o: log.h
-gcryptfix.o: rnd.h
-gcryptfix.o: gcryptfix.h
-id.o: constants.h
-id.o: defs.h
-id.o: id.h
-id.o: log.h
-id.o: connections.h
-id.o: packet.h
-id.o: whack.h
-ike_alg.o: constants.h
-ike_alg.o: defs.h
-ike_alg.o: sha1.h
-ike_alg.o: md5.h
-ike_alg.o: crypto.h
-ike_alg.o: state.h
-ike_alg.o: packet.h
-ike_alg.o: log.h
-ike_alg.o: whack.h
-ike_alg.o: spdb.h
-ike_alg.o: alg_info.h
-ike_alg.o: ike_alg.h
-ike_alg.o: db_ops.h
-ike_alg.o: connections.h
-ike_alg.o: kernel.h
-ipsec_doi.o: constants.h
-ipsec_doi.o: defs.h
-ipsec_doi.o: mp_defs.h
-ipsec_doi.o: state.h
-ipsec_doi.o: id.h
-ipsec_doi.o: x509.h
-ipsec_doi.o: crl.h
-ipsec_doi.o: ca.h
-ipsec_doi.o: certs.h
-ipsec_doi.o: smartcard.h
-ipsec_doi.o: connections.h
-ipsec_doi.o: keys.h
-ipsec_doi.o: packet.h
-ipsec_doi.o: demux.h
-ipsec_doi.o: adns.h
-ipsec_doi.o: dnskey.h
-ipsec_doi.o: kernel.h
-ipsec_doi.o: log.h
-ipsec_doi.o: cookie.h
-ipsec_doi.o: server.h
-ipsec_doi.o: spdb.h
-ipsec_doi.o: timer.h
-ipsec_doi.o: rnd.h
-ipsec_doi.o: ipsec_doi.h
-ipsec_doi.o: whack.h
-ipsec_doi.o: fetch.h
-ipsec_doi.o: pkcs7.h
-ipsec_doi.o: asn1.h
-ipsec_doi.o: sha1.h
-ipsec_doi.o: md5.h
-ipsec_doi.o: crypto.h
-ipsec_doi.o: vendor.h
-ipsec_doi.o: alg_info.h
-ipsec_doi.o: ike_alg.h
-ipsec_doi.o: kernel_alg.h
-ipsec_doi.o: nat_traversal.h
-ipsec_doi.o: virtual.h
-kernel.o: kameipsec.h
-kernel.o: constants.h
-kernel.o: defs.h
-kernel.o: rnd.h
-kernel.o: id.h
-kernel.o: connections.h
-kernel.o: state.h
-kernel.o: timer.h
-kernel.o: kernel.h
-kernel.o: kernel_netlink.h
-kernel.o: kernel_pfkey.h
-kernel.o: kernel_noklips.h
-kernel.o: log.h
-kernel.o: ca.h
-kernel.o: server.h
-kernel.o: whack.h
-kernel.o: keys.h
-kernel.o: packet.h
-kernel.o: nat_traversal.h
-kernel.o: alg_info.h
-kernel.o: kernel_alg.h
-kernel_alg.o: constants.h
-kernel_alg.o: defs.h
-kernel_alg.o: connections.h
-kernel_alg.o: state.h
-kernel_alg.o: packet.h
-kernel_alg.o: spdb.h
-kernel_alg.o: kernel.h
-kernel_alg.o: kernel_alg.h
-kernel_alg.o: alg_info.h
-kernel_alg.o: log.h
-kernel_alg.o: whack.h
-kernel_alg.o: db_ops.h
-kernel_netlink.o: kameipsec.h
-kernel_netlink.o: linux26/rtnetlink.h
-kernel_netlink.o: linux26/xfrm.h
-kernel_netlink.o: constants.h
-kernel_netlink.o: defs.h
-kernel_netlink.o: kernel.h
-kernel_netlink.o: kernel_netlink.h
-kernel_netlink.o: kernel_pfkey.h
-kernel_netlink.o: log.h
-kernel_netlink.o: whack.h
-kernel_netlink.o: kernel_alg.h
-kernel_noklips.o: constants.h
-kernel_noklips.o: defs.h
-kernel_noklips.o: kernel.h
-kernel_noklips.o: kernel_noklips.h
-kernel_noklips.o: log.h
-kernel_noklips.o: whack.h
-kernel_pfkey.o: constants.h
-kernel_pfkey.o: defs.h
-kernel_pfkey.o: kernel.h
-kernel_pfkey.o: kernel_pfkey.h
-kernel_pfkey.o: log.h
-kernel_pfkey.o: whack.h
-kernel_pfkey.o: demux.h
-kernel_pfkey.o: nat_traversal.h
-kernel_pfkey.o: alg_info.h
-kernel_pfkey.o: kernel_alg.h
-keys.o: constants.h
-keys.o: defs.h
-keys.o: mp_defs.h
-keys.o: id.h
-keys.o: x509.h
-keys.o: pgp.h
-keys.o: certs.h
-keys.o: smartcard.h
-keys.o: connections.h
-keys.o: state.h
-keys.o: lex.h
-keys.o: keys.h
-keys.o: adns.h
-keys.o: dnskey.h
-keys.o: log.h
-keys.o: whack.h
-keys.o: timer.h
-keys.o: fetch.h
-keys.o: xauth.h
-lex.o: constants.h
-lex.o: defs.h
-lex.o: log.h
-lex.o: whack.h
-lex.o: lex.h
-log.o: constants.h
-log.o: defs.h
-log.o: log.h
-log.o: server.h
-log.o: state.h
-log.o: connections.h
-log.o: kernel.h
-log.o: whack.h
-log.o: timer.h
-md2.o: md2.h
-md5.o: md5.h
-modecfg.o: constants.h
-modecfg.o: defs.h
-modecfg.o: state.h
-modecfg.o: demux.h
-modecfg.o: timer.h
-modecfg.o: ipsec_doi.h
-modecfg.o: log.h
-modecfg.o: md5.h
-modecfg.o: sha1.h
-modecfg.o: crypto.h
-modecfg.o: modecfg.h
-modecfg.o: whack.h
-modecfg.o: xauth.h
-mp_defs.o: constants.h
-mp_defs.o: defs.h
-mp_defs.o: mp_defs.h
-mp_defs.o: log.h
-nat_traversal.o: constants.h
-nat_traversal.o: defs.h
-nat_traversal.o: log.h
-nat_traversal.o: server.h
-nat_traversal.o: state.h
-nat_traversal.o: connections.h
-nat_traversal.o: packet.h
-nat_traversal.o: demux.h
-nat_traversal.o: kernel.h
-nat_traversal.o: whack.h
-nat_traversal.o: timer.h
-nat_traversal.o: cookie.h
-nat_traversal.o: sha1.h
-nat_traversal.o: md5.h
-nat_traversal.o: crypto.h
-nat_traversal.o: vendor.h
-nat_traversal.o: ike_alg.h
-nat_traversal.o: nat_traversal.h
-ocsp.o: constants.h
-ocsp.o: defs.h
-ocsp.o: log.h
-ocsp.o: x509.h
-ocsp.o: crl.h
-ocsp.o: ca.h
-ocsp.o: rnd.h
-ocsp.o: asn1.h
-ocsp.o: certs.h
-ocsp.o: smartcard.h
-ocsp.o: oid.h
-ocsp.o: whack.h
-ocsp.o: pkcs1.h
-ocsp.o: keys.h
-ocsp.o: fetch.h
-ocsp.o: ocsp.h
-oid.o: oid.h
-packet.o: constants.h
-packet.o: defs.h
-packet.o: log.h
-packet.o: packet.h
-packet.o: whack.h
-pem.o: constants.h
-pem.o: defs.h
-pem.o: log.h
-pem.o: md5.h
-pem.o: whack.h
-pem.o: pem.h
-pgp.o: constants.h
-pgp.o: defs.h
-pgp.o: mp_defs.h
-pgp.o: log.h
-pgp.o: id.h
-pgp.o: pgp.h
-pgp.o: certs.h
-pgp.o: md5.h
-pgp.o: whack.h
-pgp.o: pkcs1.h
-pgp.o: keys.h
-pkcs1.o: constants.h
-pkcs1.o: defs.h
-pkcs1.o: mp_defs.h
-pkcs1.o: asn1.h
-pkcs1.o: oid.h
-pkcs1.o: log.h
-pkcs1.o: pkcs1.h
-pkcs1.o: md2.h
-pkcs1.o: md5.h
-pkcs1.o: sha1.h
-pkcs1.o: rnd.h
-pkcs7.o: constants.h
-pkcs7.o: defs.h
-pkcs7.o: asn1.h
-pkcs7.o: oid.h
-pkcs7.o: log.h
-pkcs7.o: x509.h
-pkcs7.o: certs.h
-pkcs7.o: pkcs7.h
-pkcs7.o: rnd.h
-plutomain.o: constants.h
-plutomain.o: defs.h
-plutomain.o: id.h
-plutomain.o: ca.h
-plutomain.o: certs.h
-plutomain.o: ac.h
-plutomain.o: connections.h
-plutomain.o: foodgroups.h
-plutomain.o: packet.h
-plutomain.o: demux.h
-plutomain.o: server.h
-plutomain.o: kernel.h
-plutomain.o: log.h
-plutomain.o: keys.h
-plutomain.o: adns.h
-plutomain.o: dnskey.h
-plutomain.o: rnd.h
-plutomain.o: state.h
-plutomain.o: ipsec_doi.h
-plutomain.o: ocsp.h
-plutomain.o: crl.h
-plutomain.o: fetch.h
-plutomain.o: xauth.h
-plutomain.o: sha1.h
-plutomain.o: md5.h
-plutomain.o: crypto.h
-plutomain.o: virtual.h
-plutomain.o: nat_traversal.h
-primegen.o: constants.h
-primegen.o: defs.h
-primegen.o: log.h
-primegen.o: rnd.h
-primegen.o: gcryptfix.h
-rcv_whack.o: constants.h
-rcv_whack.o: defs.h
-rcv_whack.o: id.h
-rcv_whack.o: ca.h
-rcv_whack.o: certs.h
-rcv_whack.o: ac.h
-rcv_whack.o: smartcard.h
-rcv_whack.o: connections.h
-rcv_whack.o: foodgroups.h
-rcv_whack.o: whack.h
-rcv_whack.o: packet.h
-rcv_whack.o: demux.h
-rcv_whack.o: state.h
-rcv_whack.o: ipsec_doi.h
-rcv_whack.o: kernel.h
-rcv_whack.o: rcv_whack.h
-rcv_whack.o: log.h
-rcv_whack.o: keys.h
-rcv_whack.o: adns.h
-rcv_whack.o: dnskey.h
-rcv_whack.o: server.h
-rcv_whack.o: fetch.h
-rcv_whack.o: ocsp.h
-rcv_whack.o: crl.h
-rcv_whack.o: kernel_alg.h
-rcv_whack.o: ike_alg.h
-rnd.o: sha1.h
-rnd.o: constants.h
-rnd.o: defs.h
-rnd.o: rnd.h
-rnd.o: log.h
-rnd.o: timer.h
-server.o: constants.h
-server.o: defs.h
-server.o: state.h
-server.o: connections.h
-server.o: kernel.h
-server.o: log.h
-server.o: server.h
-server.o: timer.h
-server.o: packet.h
-server.o: demux.h
-server.o: rcv_whack.h
-server.o: keys.h
-server.o: adns.h
-server.o: dnskey.h
-server.o: whack.h
-server.o: kameipsec.h
-server.o: nat_traversal.h
-sha1.o: sha1.h
-smallprime.o: constants.h
-smallprime.o: defs.h
-smallprime.o: gcryptfix.h
-smartcard.o: constants.h
-smartcard.o: rsaref/unix.h
-smartcard.o: rsaref/pkcs11.h
-smartcard.o: defs.h
-smartcard.o: mp_defs.h
-smartcard.o: log.h
-smartcard.o: x509.h
-smartcard.o: ca.h
-smartcard.o: certs.h
-smartcard.o: keys.h
-smartcard.o: smartcard.h
-smartcard.o: whack.h
-smartcard.o: fetch.h
-spdb.o: constants.h
-spdb.o: defs.h
-spdb.o: id.h
-spdb.o: connections.h
-spdb.o: state.h
-spdb.o: packet.h
-spdb.o: keys.h
-spdb.o: kernel.h
-spdb.o: log.h
-spdb.o: spdb.h
-spdb.o: whack.h
-spdb.o: sha1.h
-spdb.o: md5.h
-spdb.o: crypto.h
-spdb.o: alg_info.h
-spdb.o: kernel_alg.h
-spdb.o: ike_alg.h
-spdb.o: db_ops.h
-spdb.o: nat_traversal.h
-state.o: constants.h
-state.o: defs.h
-state.o: connections.h
-state.o: state.h
-state.o: kernel.h
-state.o: log.h
-state.o: packet.h
-state.o: keys.h
-state.o: rnd.h
-state.o: timer.h
-state.o: whack.h
-state.o: demux.h
-state.o: ipsec_doi.h
-state.o: sha1.h
-state.o: md5.h
-state.o: crypto.h
-timer.o: constants.h
-timer.o: defs.h
-timer.o: connections.h
-timer.o: state.h
-timer.o: demux.h
-timer.o: ipsec_doi.h
-timer.o: kernel.h
-timer.o: server.h
-timer.o: log.h
-timer.o: rnd.h
-timer.o: timer.h
-timer.o: whack.h
-timer.o: nat_traversal.h
-vendor.o: constants.h
-vendor.o: defs.h
-vendor.o: log.h
-vendor.o: md5.h
-vendor.o: connections.h
-vendor.o: packet.h
-vendor.o: demux.h
-vendor.o: whack.h
-vendor.o: vendor.h
-vendor.o: kernel.h
-vendor.o: nat_traversal.h
-virtual.o: constants.h
-virtual.o: defs.h
-virtual.o: log.h
-virtual.o: connections.h
-virtual.o: whack.h
-virtual.o: virtual.h
-whack.o: constants.h
-whack.o: defs.h
-whack.o: whack.h
-x509.o: constants.h
-x509.o: defs.h
-x509.o: mp_defs.h
-x509.o: log.h
-x509.o: id.h
-x509.o: asn1.h
-x509.o: oid.h
-x509.o: pkcs1.h
-x509.o: x509.h
-x509.o: crl.h
-x509.o: ca.h
-x509.o: certs.h
-x509.o: keys.h
-x509.o: whack.h
-x509.o: fetch.h
-x509.o: ocsp.h
-x509.o: sha1.h
-xauth.o: constants.h
-xauth.o: defs.h
-xauth.o: xauth.h
-xauth.o: keys.h
-xauth.o: log.h
diff --git a/programs/pluto/PLUTO-CONVENTIONS b/programs/pluto/PLUTO-CONVENTIONS
deleted file mode 100644
index 5288dd2bb..000000000
--- a/programs/pluto/PLUTO-CONVENTIONS
+++ /dev/null
@@ -1,127 +0,0 @@
-Notes on Pluto Conventions
-==========================
-
-RCSID $Id: PLUTO-CONVENTIONS,v 1.1 2004/03/15 20:35:28 as Exp $
-
-Pluto has its own stylistic conventions. They are fairly easily
-inferred by reading the code.
-
-- sample formatting:
-
-void
-fun(char *s)
-{
- if (s == NULL)
- {
- return "";
- }
- else
- {
- switch (*s)
- {
- default:
- s++;
- /* fall through */
- case '\0':
- return s;
- }
- }
-}
-
-- a function definition has its function identifier at the margin
-
-- indentation is in steps of 4 columns (tabstops are every 8 columns)
-
-- try to keep lines shorter than 80 columns
-
-- space should be canonical:
- + no line should have trailing whitespace
- + leading whitespace should use tabs where possible
- + indentation should be precise
- + there should be no empty lines at the end of a file.
-
-- braces go on their own line, indented the same as the start of what they are part of
-
-- switch labels are indented the same as the enclosing braces
-
-- if a case falls through, say so explicitly
-
-- spaces follow control flow reserved words (but not function names)
-
-- the operand of return need not be parenthesized
-
-- be careful with types. For example, use size_t and ssize_t.
- Use const wherever possible.
-
-- we pretend that C has a strong boolean type.
- We actually define bool with constants TRUE and FALSE.
- Other types cannot be used as the complete expression in a test.
- Hence:
- if (s == NULL)
- One exception: lset_t values can be treated as booleans
- (technically they are, in the original sense of the word)
-
-
-- memsetting a pointer to binary zero is not guaranteed to make it NULL
-
-- side-effects of expressions are to be avoided.
- BAD: if (i++ == 9)
- OK: i++;
-
-- variables are to have as small a scope as is possible.
- Move definitions into inner blocks whenever possible.
- Often initializing definitions become possible and are clearer.
-
-- within a block that has declarations, separate the declarations from
- the other statements with a blank line.
-
-- "magic numbers" are suspect. Most integers in code stand for something.
- They should be given a name, and that name used consistently.
-
-- don't use malloc/free -- use the wrappers (see defs.h)
-
-- it is good to put comments on #else and #endif to show what
- they match with. I use ! to indicate the sense of the test:
- #ifdef CRUD
- #else /* !CRUD */
- #endif /* !CRUD */
-
- #ifndef CRUD
- #else /* CRUD */
- #endif /* CRUD */
-
-- all functions and variables that are exported from a .c file should
- be declared in that file's header file. Because the .c includes the
- header, the declaration and the definition will be checked by the
- compiler. There is almost no excuse for the "extern" keyword
- in a .c file.
-
-- when lines are too long and expressions are to be broken, try to
- break just before a binary operator. The outermost binary operator
- is preferred. This is perhaps the most unconventional convention.
- It allows the structure of code to be evident from a scan of the
- left margin. Example:
- if (next_step == vos_his_client
- && sameaddr(&c->spd.that.host_addr, &his_client))
- next_step = vos_done;
- and
- p = oppo_instantiate(p, &c->spd.that.host_addr, &c->spd.that.id
- , NULL, &our_client, &his_client);
- Note the different indentation of the continuations. The continuation
- of a control flow statement is not indented but other continuations are.
-
-- Never put two statements on one line.
- REALLY BAD: if (cat);
- Exception: some macro definitions.
-
-- C preprocessor macros are implemented by a kind of textual substitution.
- Be sure to put parentheses around references to macro arguments and
- around the whole macro body. If the body is meant to be a statement,
- put braces around it instead.
-
- #define RETURN_STF_FAILURE(f) \
- { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; }
-
-- adding #include statements adds dependencies. The Makefile should be
- changed to reflect them. Target "makedepend" will try to list dependencies
- in a way suitable for pasting into Makefile
diff --git a/programs/pluto/TODO b/programs/pluto/TODO
deleted file mode 100644
index 7db4a9ebc..000000000
--- a/programs/pluto/TODO
+++ /dev/null
@@ -1,129 +0,0 @@
-Pluto TODO list
-===============
-RCSID $Id: TODO,v 1.1 2004/03/15 20:35:28 as Exp $
-
-- should all log entries that are for errors say ERROR?
-
-- Add a "plug-in" facility so that others can add features without
- changing the mainline code. This is how X509/LDAP/biometric stuff
- might be added.
-
-- (internal change only) routines for outputting payloads should plug
- "np" into the previous payload so that a payload generating routine
- need not know what the next payload will be. This may be more bother
- than it is worth.
-
-- notifications, in and out
- + delete
- + first contact
- + last contact? (not part of drafts, but would be nice)
-
-- Make DNS usage for asynchronous (non-blocking)
- + looking up KEY and TXT records during negotiation
- + perhaps not for whack command arguments and ipsec.secrets since the
- library code uses gethostbyname
-
-- check that ipsec auto and whack to agree on what is worth reporting
-
-- Should Pluto (rather than ipsec manual) install %passthrough conns?
- That way Pluto would know of them.
-
-- For responding to Road Warriors, how can we decide if the RW has
- gone away? The rekeying event is perhaps too imprecise. Even if
- rekeying event is good enough, how do we know if the route should be
- torn down? Perhaps limiting a Phase 1 ID to one IP address would
- help (limiting a client subnet to one peer already helps). Perhaps
- (in some rate-limited way) we can take an ICMP host unreachable
- as a hint to do some authenticated and reliable probe.
-
-- it is annoying that Pluto and auto have different models for public keys.
- + auto specifies one per connection
- + Pluto allows one to be specified per id
- Two connections with the same id are going to use the same key:
- the one of the last conn to be added!
-
- I think auto ought to be fixed. It is hard for Pluto to warn when
- there is a conflict since the deletion of a connection doesn't
- prompt auto to tell pluto to delete the public key.
-
-- different connections with the same host IP addresses are randomly
- interchangeable until the ID payload is received. At least for the
- Responder case (and eventually for the opportunistic Initiator).
- Worse, all Road Warriors must be considered to have the
- indistinguishable IP addresses. This affects ISAKMP SA negotiation.
- Currently, there is little flexibility in this negotiation, so the
- problem is limited to the specification of acceptable authentication
- method(s). Correct, but more work than seems worthwhile, would be
- to select the conn based on what is proposed.
-
- Warning about such confusion at connection definition time isn't great
- because there is no confusion when explicitly initiated (a particular
- conn is specified). Warning for a Road Warrior conn is possible
- since it cannot be initiated (and has been implemented).
-
-- characterize and ameliorate DOS attacks. Lots of rate limiting.
-
-- look at John Denker's wish list: http://www.quintillion.com/moat/wish.list
-
-- use of random numbers needs to be audited.
-
-- unknown (not just unimplemented) transforms cause a negotiation to
- fail. Only the transform should be rejected.
-
-- we need better policy control. Our present flags need to be
- modulated (forbid, allow, offer, require)
-
-- HS will specify how --copyright and --version should behave
-
-- HS will initiate project-wide terminology replacing ISAKMP SA, IPSEC
- SA, Protection Suite, Phase 1, Main Mode, Phase 2, Quick Mode, ...
- Simplicity and clarity will be a goal.
-
-- interface discovery ought to match what is specified in ipsec.conf.
- This probably means grokking /proc/net/ipsec_tncfg. Documented in
- ipsec_tncfg(5). This won't do for Hugh's debugging setup.
-
-
-Protocol Issues
-===============
-
-Notification and delete payloads seem to be "escape hatches" for the
-protocols. As such, anything implemented using them seems to be
-kludged without being well designed or well situated or well
-constrained in the protocols. Often the precise meaning (if any) or
-usage is under specified. An implementation is allowed to ignore
-them, so they cannot really matter (but they too often do). Their
-specification ought to be scrutinized by a protocol guru.
-
-Any extra payload in last main mode message is not protected (not
-authenticated by hash).
-
-Should notification payloads be interpreted before or after the normal
-payloads (i.e. understood in the context of, executed in the context of).
-
-What is the precise result of an INITIAL_CONNECTION? What is a
-"system" (eg. does Phase 1 Identity count)? What is "earlier" or
-"before" (simultaneous negotiation is possible, with time being only a
-partial order)? Could it be used for FINAL_CONTACT (needed too)?
-
-Blasting out a pile of UDP messages, especially to a particular
-destination, is likely to provoke message loss. The exchanges are
-just that, so they individually are self-throttling. But what about
-multiple exchanges simultaneously? What about notifications (example:
-when shutting down, a flurry of delete notifications are likely).
-Should the RFCs be designed to protect against this problem?
-
-draft-jenkins-ipsec-rekeying-03.txt rekeying is way too complicated.
-Our solution looks sound and simple (we have the Responder install the
-incoming IPSEC SA before sending its first reply). In "2.2.1.4
-Responder Pre-Set-up Security Hole", the draft claims that setting up
-the IPSEC SA early leaves the Responder open to replay attacks. I
-think that this is wrong: the Message Id, since it must not be reused,
-serves to prove that this isn't a replay.
-
-The details for notification messages suggested by
-draft-ietf-ipsec-notifymsg-02.txt are over-complicated, just to make
-them machine-comprehensible. I think this is over-engineering,
-justified only if another level of negotiation is contemplated (ugh!).
-Plain text is probably sufficient for informing humans (I admit that
-there is a problem with I18N).
diff --git a/programs/pluto/ac.c b/programs/pluto/ac.c
deleted file mode 100644
index bcf5f80d1..000000000
--- a/programs/pluto/ac.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/* Support of X.509 attribute certificates
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ac.c,v 1.12 2005/12/06 22:49:32 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "asn1.h"
-#include "oid.h"
-#include "ac.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "log.h"
-#include "whack.h"
-#include "fetch.h"
-
-/* chained list of X.509 attribute certificates */
-
-static x509acert_t *x509acerts = NULL;
-
-/* chained list of ietfAttributes */
-
-static ietfAttrList_t *ietfAttributes = NULL;
-
-/* ASN.1 definition of ietfAttrSyntax */
-
-static const asn1Object_t ietfAttrSyntaxObjects[] =
-{
- { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
- { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
- ASN1_BODY }, /* 4 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 2, "oid", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 6 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "string", ASN1_UTF8STRING, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 10 */
-};
-
-#define IETF_ATTR_OCTETS 4
-#define IETF_ATTR_OID 6
-#define IETF_ATTR_STRING 8
-#define IETF_ATTR_ROOF 11
-
-/* ASN.1 definition of roleSyntax */
-
-static const asn1Object_t roleSyntaxObjects[] =
-{
- { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
-};
-
-#define ROLE_ROOF 4
-
-/* ASN.1 definition of an X509 attribute certificate */
-
-static const asn1Object_t acObjects[] =
-{
- { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_DEF |
- ASN1_BODY }, /* 2 */
- { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 7 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 10 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
- { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
- { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
- { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
- { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
- { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
- { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
- { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 25 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
- { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
- { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
- { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 31 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
- { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
- { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
- { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
- { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
- { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
- { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
- { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
- { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
- { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
- { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 50 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
-};
-
-#define AC_OBJ_CERTIFICATE 0
-#define AC_OBJ_CERTIFICATE_INFO 1
-#define AC_OBJ_VERSION 2
-#define AC_OBJ_HOLDER_ISSUER 5
-#define AC_OBJ_HOLDER_SERIAL 6
-#define AC_OBJ_ENTITY_NAME 10
-#define AC_OBJ_ISSUER_NAME 19
-#define AC_OBJ_ISSUER 23
-#define AC_OBJ_SIG_ALG 35
-#define AC_OBJ_SERIAL_NUMBER 36
-#define AC_OBJ_NOT_BEFORE 38
-#define AC_OBJ_NOT_AFTER 39
-#define AC_OBJ_ATTRIBUTE_TYPE 42
-#define AC_OBJ_ATTRIBUTE_VALUE 44
-#define AC_OBJ_EXTN_ID 49
-#define AC_OBJ_CRITICAL 50
-#define AC_OBJ_EXTN_VALUE 51
-#define AC_OBJ_ALGORITHM 53
-#define AC_OBJ_SIGNATURE 54
-#define AC_OBJ_ROOF 55
-
-const x509acert_t empty_ac = {
- NULL , /* *next */
- 0 , /* installed */
- { NULL, 0 }, /* certificate */
- { NULL, 0 }, /* certificateInfo */
- 1 , /* version */
- /* holder */
- /* baseCertificateID */
- { NULL, 0 }, /* holderIssuer */
- { NULL, 0 }, /* holderSerial */
- /* entityName */
- { NULL, 0 }, /* generalNames */
- /* v2Form */
- { NULL, 0 }, /* issuerName */
- /* signature */
- OID_UNKNOWN, /* sigAlg */
- { NULL, 0 }, /* serialNumber */
- /* attrCertValidityPeriod */
- 0 , /* notBefore */
- 0 , /* notAfter */
- /* attributes */
- NULL , /* charging */
- NULL , /* groups */
- /* extensions */
- { NULL, 0 }, /* authKeyID */
- { NULL, 0 }, /* authKeySerialNumber */
- FALSE , /* noRevAvail */
- /* signatureAlgorithm */
- OID_UNKNOWN, /* algorithm */
- { NULL, 0 }, /* signature */
-};
-
-
-/* compare two ietfAttributes, returns zero if a equals b
- * negative/positive if a is earlier/later in the alphabet than b
- */
-static int
-cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
-{
- int cmp_len, len, cmp_value;
-
- /* cannot compare OID with STRING or OCTETS attributes */
- if (a->kind == IETF_ATTRIBUTE_OID && b->kind != IETF_ATTRIBUTE_OID)
- return 1;
-
- cmp_len = a->value.len - b->value.len;
- len = (cmp_len < 0)? a->value.len : b->value.len;
- cmp_value = memcmp(a->value.ptr, b->value.ptr, len);
-
- return (cmp_value == 0)? cmp_len : cmp_value;
-}
-
-/*
- * add an ietfAttribute to the chained list
- */
-static ietfAttr_t*
-add_ietfAttr(ietfAttr_t *attr)
-{
- ietfAttrList_t **listp = &ietfAttributes;
- ietfAttrList_t *list = *listp;
- int cmp = -1;
-
- while (list != NULL)
- {
- cmp = cmp_ietfAttr(attr, list->attr);
- if (cmp <= 0)
- break;
- listp = &list->next;
- list = *listp;
- }
-
- if (cmp == 0)
- {
- /* attribute already exists, increase count */
- pfree(attr);
- list->attr->count++;
- return list->attr;
- }
- else
- {
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- /* new attribute, unshare value */
- attr->value.ptr = clone_bytes(attr->value.ptr, attr->value.len
- , "attr value");
- attr->count = 1;
- time(&attr->installed);
-
- el->attr = attr;
- el->next = list;
- *listp = el;
-
- return attr;
- }
-}
-
-/*
- * decodes a comma separated list of group attributes
- */
-void
-decode_groups(char *groups, ietfAttrList_t **listp)
-{
- if (groups == NULL)
- return;
-
- while (strlen(groups) > 0)
- {
- char *end;
- char *next = strchr(groups, ',');
-
- if (next == NULL)
- end = next = groups + strlen(groups);
- else
- end = next++;
-
- /* eat preceeding whitespace */
- while (groups < end && *groups == ' ')
- groups++;
-
- /* eat trailing whitespace */
- while (end > groups && *(end-1) == ' ')
- end--;
-
- if (groups < end)
- {
- ietfAttr_t *attr = alloc_thing(ietfAttr_t, "ietfAttr");
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- attr->kind = IETF_ATTRIBUTE_STRING;
- attr->value.ptr = groups;
- attr->value.len = end - groups;
- attr->count = 0;
-
- el->attr = add_ietfAttr(attr);
- el->next = *listp;
- *listp = el;
- }
-
- groups = next;
- }
-}
-
-static bool
-same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
-{
- return (a->kind == b->kind && a->value.len == b->value.len
- && memcmp(a->value.ptr, b->value.ptr, b->value.len) == 0);
-}
-
-bool
-group_membership(const ietfAttrList_t *peer_list
- , const char *conn
- , const ietfAttrList_t *conn_list)
-{
- if (conn_list == NULL)
- return TRUE;
-
- while (peer_list != NULL)
- {
- const ietfAttr_t *peer_attr = peer_list->attr;
- const ietfAttrList_t *list = conn_list;
-
- while (list != NULL)
- {
- ietfAttr_t *conn_attr = list->attr;
-
- if (same_attribute(conn_attr, peer_attr))
- {
- DBG(DBG_CONTROL,
- DBG_log("%s: peer matches group '%.*s'"
- , conn
- , (int)peer_attr->value.len, peer_attr->value.ptr)
- )
- return TRUE;
- }
- list = list->next;
- }
- peer_list = peer_list->next;
- }
- DBG(DBG_CONTROL,
- DBG_log("%s: peer doesn't match any group", conn)
- )
- return FALSE;
-}
-
-
-void
-unshare_ietfAttrList(ietfAttrList_t **listp)
-{
- ietfAttrList_t *list = *listp;
-
- while (list != NULL)
- {
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- el->attr = list->attr;
- el->attr->count++;
- el->next = NULL;
- *listp = el;
- listp = &el->next;
- list = list->next;
- }
-}
-
-/*
- * parses ietfAttrSyntax
- */
-static ietfAttrList_t*
-parse_ietfAttrSyntax(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- ietfAttrList_t *list = NULL;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < IETF_ATTR_ROOF)
- {
- if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- switch (objectID)
- {
- case IETF_ATTR_OCTETS:
- case IETF_ATTR_OID:
- case IETF_ATTR_STRING:
- {
- ietfAttr_t *attr = alloc_thing(ietfAttr_t, "ietfAttr");
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- attr->kind = (objectID - IETF_ATTR_OCTETS) / 2;
- attr->value = object;
- attr->count = 0;
-
- el->attr = add_ietfAttr(attr);
- el->next = list;
- list = el;
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- return list;
-}
-/*
- * parses roleSyntax
- */
-static void
-parse_roleSyntax(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < ROLE_ROOF)
- {
- if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- default:
- break;
- }
- objectID++;
- }
-}
-
-/*
- * Parses an X.509 attribute certificate
- */
-bool
-parse_ac(chunk_t blob, x509acert_t *ac)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- u_int type = OID_UNKNOWN;
- u_int extn_oid = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
- while (objectID < AC_OBJ_ROOF) {
-
- if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case AC_OBJ_CERTIFICATE:
- ac->certificate = object;
- break;
- case AC_OBJ_CERTIFICATE_INFO:
- ac->certificateInfo = object;
- break;
- case AC_OBJ_VERSION:
- ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", ac->version);
- )
- if (ac->version != 2)
- {
- plog("v%d attribute certificates are not supported"
- , ac->version);
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_ISSUER:
- ac->holderIssuer = get_directoryName(object, level, FALSE);
- break;
- case AC_OBJ_HOLDER_SERIAL:
- ac->holderSerial = object;
- break;
- case AC_OBJ_ENTITY_NAME:
- ac->entityName = get_directoryName(object, level, TRUE);
- break;
- case AC_OBJ_ISSUER_NAME:
- ac->issuerName = get_directoryName(object, level, FALSE);
- break;
- case AC_OBJ_SIG_ALG:
- ac->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SERIAL_NUMBER:
- ac->serialNumber = object;
- break;
- case AC_OBJ_NOT_BEFORE:
- ac->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_NOT_AFTER:
- ac->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_ATTRIBUTE_TYPE:
- type = known_oid(object);
- break;
- case AC_OBJ_ATTRIBUTE_VALUE:
- {
- switch (type) {
- case OID_AUTHENTICATION_INFO:
- DBG(DBG_PARSING,
- DBG_log(" need to parse authenticationInfo")
- )
- break;
- case OID_ACCESS_IDENTITY:
- DBG(DBG_PARSING,
- DBG_log(" need to parse accessIdentity")
- )
- break;
- case OID_CHARGING_IDENTITY:
- ac->charging = parse_ietfAttrSyntax(object, level);
- break;
- case OID_GROUP:
- ac->groups = parse_ietfAttrSyntax(object, level);
- break;
- case OID_ROLE:
- parse_roleSyntax(object, level);
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case AC_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case AC_OBJ_EXTN_VALUE:
- {
- switch (extn_oid) {
- case OID_CRL_DISTRIBUTION_POINTS:
- DBG(DBG_PARSING,
- DBG_log(" need to parse crlDistributionPoints")
- )
- break;
- case OID_AUTHORITY_KEY_ID:
- parse_authorityKeyIdentifier(object, level
- , &ac->authKeyID, &ac->authKeySerialNumber);
- break;
- case OID_TARGET_INFORMATION:
- DBG(DBG_PARSING,
- DBG_log(" need to parse targetInformation")
- )
- break;
- case OID_NO_REV_AVAIL:
- ac->noRevAvail = TRUE;
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_ALGORITHM:
- ac->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SIGNATURE:
- ac->signature = object;
- break;
-
- default:
- break;
- }
- objectID++;
- }
- time(&ac->installed);
- return TRUE;
-}
-
-/*
- * compare two X.509 attribute certificates by comparing their signatures
- */
-static bool
-same_x509acert(x509acert_t *a, x509acert_t *b)
-{
- return a->signature.len == b->signature.len &&
- memcmp(a->signature.ptr, b->signature.ptr, b->signature.len) == 0;
-}
-
-/*
- * release an ietfAttribute, free it if count reaches zero
- */
-static void
-release_ietfAttr(ietfAttr_t* attr)
-{
- if (--attr->count == 0)
- {
- ietfAttrList_t **plist = &ietfAttributes;
- ietfAttrList_t *list = *plist;
-
- while (list->attr != attr)
- {
- plist = &list->next;
- list = *plist;
- }
- *plist = list->next;
-
- pfree(attr->value.ptr);
- pfree(attr);
- pfree(list);
- }
-}
-
-/*
- * free an ietfAttrList
- */
-void
-free_ietfAttrList(ietfAttrList_t* list)
-{
- while (list != NULL)
- {
- ietfAttrList_t *el = list;
-
- release_ietfAttr(el->attr);
- list = list->next;
- pfree(el);
- }
-}
-
-/*
- * free a X.509 attribute certificate
- */
-void
-free_acert(x509acert_t *ac)
-{
- if (ac != NULL)
- {
- free_ietfAttrList(ac->charging);
- free_ietfAttrList(ac->groups);
- pfreeany(ac->certificate.ptr);
- pfree(ac);
- }
-}
-
-/*
- * free first X.509 attribute certificate in the chained list
- */
-static void
-free_first_acert(void)
-{
- x509acert_t *first = x509acerts;
- x509acerts = first->next;
- free_acert(first);
-}
-
-/*
- * Free all attribute certificates in the chained list
- */
-void
-free_acerts(void)
-{
- while (x509acerts != NULL)
- free_first_acert();
-}
-
-/*
- * get a X.509 attribute certificate for a given holder
- */
-x509acert_t*
-get_x509acert(chunk_t issuer, chunk_t serial)
-{
- x509acert_t *ac = x509acerts;
- x509acert_t *prev_ac = NULL;
-
- while (ac != NULL)
- {
- if (same_dn(issuer, ac->holderIssuer)
- && same_serial(serial, ac->holderSerial))
- {
- if (ac!= x509acerts)
- {
- /* bring the certificate up front */
- prev_ac->next = ac->next;
- ac->next = x509acerts;
- x509acerts = ac;
- }
- return ac;
- }
- prev_ac = ac;
- ac = ac->next;
- }
- return NULL;
-}
-
-/*
- * add a X.509 attribute certificate to the chained list
- */
-static void
-add_acert(x509acert_t *ac)
-{
- x509acert_t *old_ac = get_x509acert(ac->holderIssuer, ac->holderSerial);
-
- if (old_ac != NULL)
- {
- if (ac->notBefore >old_ac->notBefore)
- {
- /* delete the old attribute cert */
- free_first_acert();
- DBG(DBG_CONTROL,
- DBG_log("attribute cert is newer - existing cert deleted")
- )
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("attribute cert is not newer - existing cert kept");
- )
- free_acert(ac);
- return;
- }
- }
- plog("attribute cert added");
-
- /* insert new attribute cert at the root of the chain */
- ac->next = x509acerts;
- x509acerts = ac;
-}
-
-/* verify the validity of an attribute certificate by
- * checking the notBefore and notAfter dates
- */
-static err_t
-check_ac_validity(const x509acert_t *ac)
-{
- time_t current_time;
-
- time(&current_time);
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" not before : %s", timetoa(&ac->notBefore, TRUE));
- DBG_log(" current time: %s", timetoa(&current_time, TRUE));
- DBG_log(" not after : %s", timetoa(&ac->notAfter, TRUE));
- )
-
- if (current_time < ac->notBefore)
- return "attribute certificate is not valid yet";
- if (current_time > ac->notAfter)
- return "attribute certificate has expired";
- else
- return NULL;
-}
-
-/*
- * verifies a X.509 attribute certificate
- */
-bool
-verify_x509acert(x509acert_t *ac, bool strict)
-{
- u_char buf[BUF_LEN];
- x509cert_t *aacert;
- err_t ugh = NULL;
- time_t valid_until = ac->notAfter;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, ac->entityName);
- DBG_log("holder: '%s'",buf);
- dntoa(buf, BUF_LEN, ac->issuerName);
- DBG_log("issuer: '%s'",buf);
- )
-
- ugh = check_ac_validity(ac);
-
- if (ugh != NULL)
- {
- plog("%s", ugh);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("attribute certificate is valid")
- )
-
- lock_authcert_list("verify_x509acert");
- aacert = get_authcert(ac->issuerName, ac->authKeySerialNumber
- , ac->authKeyID, AUTH_AA);
- unlock_authcert_list("verify_x509acert");
-
- if (aacert == NULL)
- {
- plog("issuer aacert not found");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("issuer aacert found")
- )
-
- if (!check_signature(ac->certificateInfo, ac->signature
- , ac->algorithm, ac->algorithm, aacert))
- {
- plog("attribute certificate signature is invalid");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("attribute certificate signature is valid");
- )
-
- return verify_x509cert(aacert, strict, &valid_until);
-}
-
-/*
- * Loads X.509 attribute certificates
- */
-void
-load_acerts(void)
-{
- u_char buf[BUF_LEN];
-
- /* change directory to specified path */
- u_char *save_dir = getcwd(buf, BUF_LEN);
-
- if (!chdir(A_CERT_PATH))
- {
- struct dirent **filelist;
- int n;
-
- plog("Changing to directory '%s'",A_CERT_PATH);
- n = scandir(A_CERT_PATH, &filelist, file_select, alphasort);
-
- if (n > 0)
- {
- while (n--)
- {
- chunk_t blob = empty_chunk;
- bool pgp = FALSE;
-
- if (load_coded_file(filelist[n]->d_name, NULL, "acert", &blob, &pgp))
- {
- x509acert_t *ac = alloc_thing(x509acert_t, "x509acert");
-
- *ac = empty_ac;
-
- if (parse_ac(blob, ac)
- && verify_x509acert(ac, FALSE))
- add_acert(ac);
- else
- free_acert(ac);
- }
- free(filelist[n]);
- }
- free(filelist);
- }
- }
- /* restore directory path */
- chdir(save_dir);
-}
-
-/*
- * lists group attributes separated by commas on a single line
- */
-void
-format_groups(const ietfAttrList_t *list, char *buf, int len)
-{
- bool first_group = TRUE;
-
- while (list != NULL && len > 0)
- {
- ietfAttr_t *attr = list->attr;
-
- if (attr->kind == IETF_ATTRIBUTE_OCTETS
- || attr->kind == IETF_ATTRIBUTE_STRING)
- {
- int written = snprintf(buf, len, "%s%.*s"
- , (first_group)? "" : ", "
- , (int)attr->value.len, attr->value.ptr);
-
- first_group = FALSE;
-
- /* return value of snprintf() up to glibc 2.0.6 */
- if (written < 0)
- break;
-
- buf += written;
- len -= written;
- }
- list = list->next;
- }
-}
-
-/*
- * list all X.509 attribute certificates in the chained list
- */
-void
-list_acerts(bool utc)
-{
- x509acert_t *ac = x509acerts;
- time_t now;
-
- /* determine the current time */
- time(&now);
-
- if (ac != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 Attribute Certificates:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (ac != NULL)
- {
- u_char buf[BUF_LEN];
-
- whack_log(RC_COMMENT, "%s",timetoa(&ac->installed, utc));
- if (ac->entityName.ptr != NULL)
- {
- dntoa(buf, BUF_LEN, ac->entityName);
- whack_log(RC_COMMENT, " holder: '%s'", buf);
- }
- if (ac->holderIssuer.ptr != NULL)
- {
- dntoa(buf, BUF_LEN, ac->holderIssuer);
- whack_log(RC_COMMENT, " hissuer: '%s'", buf);
- }
- if (ac->holderSerial.ptr != NULL)
- {
- datatot(ac->holderSerial.ptr, ac->holderSerial.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " hserial: %s", buf);
- }
- if (ac->groups != NULL)
- {
- format_groups(ac->groups, buf, BUF_LEN);
- whack_log(RC_COMMENT, " groups: %s", buf);
- }
- dntoa(buf, BUF_LEN, ac->issuerName);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- datatot(ac->serialNumber.ptr, ac->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s", buf);
- whack_log(RC_COMMENT, " validity: not before %s %s",
- timetoa(&ac->notBefore, utc),
- (ac->notBefore < now)?"ok":"fatal (not valid yet)");
- whack_log(RC_COMMENT, " not after %s %s",
- timetoa(&ac->notAfter, utc),
- check_expiry(ac->notAfter, ACERT_WARNING_INTERVAL, TRUE));
- if (ac->authKeyID.ptr != NULL)
- {
- datatot(ac->authKeyID.ptr, ac->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (ac->authKeySerialNumber.ptr != NULL)
- {
- datatot(ac->authKeySerialNumber.ptr, ac->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
-
- ac = ac->next;
- }
-}
-
-/*
- * list all group attributes in alphabetical order
- */
-void
-list_groups(bool utc)
-{
- ietfAttrList_t *list = ietfAttributes;
-
- if (list != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Group Attributes:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (list != NULL)
- {
- ietfAttr_t *attr = list->attr;
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&attr->installed, utc),
- attr->count);
-
- switch (attr->kind)
- {
- case IETF_ATTRIBUTE_OCTETS:
- case IETF_ATTRIBUTE_STRING:
- whack_log(RC_COMMENT, " %.*s", (int)attr->value.len, attr->value.ptr);
- break;
- case IETF_ATTRIBUTE_OID:
- whack_log(RC_COMMENT, " OID");
- break;
- default:
- break;
- }
-
- list = list->next;
- }
-}
diff --git a/programs/pluto/ac.h b/programs/pluto/ac.h
deleted file mode 100644
index 3913d745d..000000000
--- a/programs/pluto/ac.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Support of X.509 attribute certificates
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
-
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ac.h,v 1.8 2005/02/17 20:56:04 as Exp $
- */
-
-#ifndef _AC_H
-#define _AC_H
-
-/* definition of ietfAttribute kinds */
-
-typedef enum {
- IETF_ATTRIBUTE_OCTETS = 0,
- IETF_ATTRIBUTE_OID = 1,
- IETF_ATTRIBUTE_STRING = 2
-} ietfAttribute_t;
-
-/* access structure for an ietfAttribute */
-
-typedef struct ietfAttr ietfAttr_t;
-
-struct ietfAttr {
- time_t installed;
- int count;
- ietfAttribute_t kind;
- chunk_t value;
-};
-
-typedef struct ietfAttrList ietfAttrList_t;
-
-struct ietfAttrList {
- ietfAttrList_t *next;
- ietfAttr_t *attr;
-};
-
-
-/* access structure for an X.509 attribute certificate */
-
-typedef struct x509acert x509acert_t;
-
-struct x509acert {
- x509acert_t *next;
- time_t installed;
- chunk_t certificate;
- chunk_t certificateInfo;
- u_int version;
- /* holder */
- /* baseCertificateID */
- chunk_t holderIssuer;
- chunk_t holderSerial;
- chunk_t entityName;
- /* v2Form */
- chunk_t issuerName;
- /* signature */
- int sigAlg;
- chunk_t serialNumber;
- /* attrCertValidityPeriod */
- time_t notBefore;
- time_t notAfter;
- /* attributes */
- ietfAttrList_t *charging;
- ietfAttrList_t *groups;
- /* extensions */
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- bool noRevAvail;
- /* signatureAlgorithm */
- int algorithm;
- chunk_t signature;
-};
-
-/* used for initialization */
-extern const x509acert_t empty_ac;
-
-extern void unshare_ietfAttrList(ietfAttrList_t **listp);
-extern void free_ietfAttrList(ietfAttrList_t *list);
-extern void decode_groups(char *groups, ietfAttrList_t **listp);
-extern bool group_membership(const ietfAttrList_t *my_list
- , const char *conn, const ietfAttrList_t *conn_list);
-extern bool parse_ac(chunk_t blob, x509acert_t *ac);
-extern bool verify_x509acert(x509acert_t *ac, bool strict);
-extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial);
-extern void load_acerts(void);
-extern void free_acert(x509acert_t *ac);
-extern void free_acerts(void);
-extern void list_acerts(bool utc);
-extern void list_groups(bool utc);
-extern void format_groups(const ietfAttrList_t *list, char *buf, int len);
-
-
-#endif /* _AH_H */
diff --git a/programs/pluto/adns.c b/programs/pluto/adns.c
deleted file mode 100644
index c5977d23c..000000000
--- a/programs/pluto/adns.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* Pluto Asynchronous DNS Helper Program -- for internal use only!
- * Copyright (C) 2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: adns.c,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#ifndef USE_LWRES /* whole file! */
-
-/* This program executes as multiple processes. The Master process
- * receives queries (struct adns_query messages) from Pluto and distributes
- * them amongst Worker processes. These Worker processes are created
- * by the Master whenever a query arrives and no existing Worker is free.
- * At most MAX_WORKERS will be created; after that, the Master will queue
- * queries until a Worker becomes free. When a Worker has an answer from
- * the resolver, it sends the answer as a struct adns_answer message to the
- * Master. The Master then forwards the answer to Pluto, noting that
- * the Worker is free to accept another query.
- *
- * The protocol is simple: Pluto sends a sequence of queries and receives
- * a sequence of answers. select(2) is used by Pluto and by the Master
- * process to decide when to read, but writes are done without checking
- * for readiness. Communications is via pipes. Since only one process
- * can write to each pipe, messages will not be interleaved. Fixed length
- * records are used for simplicity.
- *
- * Pluto needs a way to indicate to the Master when to shut down
- * and the Master needs to indicate this to each worker. EOF on the pipe
- * signifies this.
- *
- * The interfaces between these components are considered private to
- * Pluto. This allows us to get away with less checking. This is a
- * reason to use pipes instead of TCP/IP.
- *
- * Although the code uses plain old UNIX processes, it could be modified
- * to use threads. That might reduce resource requirements. It would
- * preclude running on systems without thread-safe resolvers.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h> /* ??? for h_errno */
-
-#include <freeswan.h>
-
-/* GCC magic! */
-#ifdef GCC_LINT
-# define UNUSED __attribute__ ((unused))
-#else
-# define UNUSED /* ignore */
-#endif
-
-#include "constants.h"
-#include "adns.h" /* needs <resolv.h> */
-
-/* shared by all processes */
-
-static const char *name; /* program name, for messages */
-
-static bool debug = FALSE;
-
-/* Read a variable-length record from a pipe (and no more!).
- * First bytes must be a size_t containing the length.
- * HES_CONTINUE if record read
- * HES_OK if EOF
- * HES_IO_ERROR_IN if errno tells the tale.
- * Others are errors.
- */
-static enum helper_exit_status
-read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
-{
- size_t n = 0;
- size_t goal = minlen;
-
- do {
- ssize_t m = read(fd, stuff + n, goal - n);
-
- if (m == -1)
- {
- if (errno != EINTR)
- {
- syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
- return HES_IO_ERROR_IN;
- }
- }
- else if (m == 0)
- {
- return HES_OK; /* treat empty message as EOF */
- }
- else
- {
- n += m;
- if (n >= sizeof(size_t))
- {
- goal = *(size_t *)(void *)stuff;
- if (goal < minlen || maxlen < goal)
- {
- if (debug)
- fprintf(stderr, "%lu : [%lu, %lu]\n"
- , (unsigned long)goal
- , (unsigned long)minlen, (unsigned long)maxlen);
- return HES_BAD_LEN;
- }
- }
- }
- } while (n < goal);
-
- return HES_CONTINUE;
-}
-
-/* Write a variable-length record to a pipe.
- * First bytes must be a size_t containing the length.
- * HES_CONTINUE if record written
- * Others are errors.
- */
-static enum helper_exit_status
-write_pipe(int fd, const unsigned char *stuff)
-{
- size_t len = *(const size_t *)(const void *)stuff;
- size_t n = 0;
-
- do {
- ssize_t m = write(fd, stuff + n, len - n);
-
- if (m == -1)
- {
- /* error, but ignore and retry if EINTR */
- if (errno != EINTR)
- {
- syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
- return HES_IO_ERROR_OUT;
- }
- }
- else
- {
- n += m;
- }
- } while (n != len);
- return HES_CONTINUE;
-}
-
-/**************** worker process ****************/
-
-/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
- * so we build some of our own :-(
- */
-
-/* Support deprecated interface to allow for older releases of the resolver.
- * Fake new interface!
- * See resolver(3) bind distribution (should be in RHL6.1, but isn't).
- * __RES was 19960801 in RHL6.2, an old resolver.
- */
-
-#if (__RES) <= 19960801
-# define OLD_RESOLVER 1
-#endif
-
-#ifdef OLD_RESOLVER
-
-# define res_ninit(statp) res_init()
-# define res_nquery(statp, dname, class, type, answer, anslen) \
- res_query(dname, class, type, answer, anslen)
-# define res_nclose(statp) res_close()
-
-static struct __res_state *statp = &_res;
-
-#else /* !OLD_RESOLVER */
-
-static struct __res_state my_res_state /* = { 0 } */;
-static res_state statp = &my_res_state;
-
-#endif /* !OLD_RESOLVER */
-
-static int
-worker(int qfd, int afd)
-{
- {
- int r = res_ninit(statp);
-
- if (r != 0)
- {
- syslog(LOG_ERR, "cannot initialize resolver");
- return HES_RES_INIT;
- }
-#ifndef OLD_RESOLVER
- statp->options |= RES_ROTATE;
-#endif
- statp->options |= RES_DEBUG;
- }
-
- for (;;)
- {
- struct adns_query q;
- struct adns_answer a;
-
- enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
- , sizeof(q), sizeof(q));
-
- if (r != HES_CONTINUE)
- return r; /* some kind of exit */
-
- if (q.qmagic != ADNS_Q_MAGIC)
- {
- syslog(LOG_ERR, "error in input from master: bad magic");
- return HES_BAD_MAGIC;
- }
-
- a.amagic = ADNS_A_MAGIC;
- a.serial = q.serial;
-
- a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans));
- a.h_errno_val = h_errno;
-
- a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result);
-
-#ifdef DEBUG
- if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
- || ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
- sleep(30); /* delay the answer */
-#endif
-
- /* write answer, possibly a bit at a time */
- r = write_pipe(afd, (const unsigned char *)&a);
-
- if (r != HES_CONTINUE)
- return r; /* some kind of exit */
- }
-}
-
-/**************** master process ****************/
-
-bool eof_from_pluto = FALSE;
-#define PLUTO_QFD 0 /* queries come on stdin */
-#define PLUTO_AFD 1 /* answers go out on stdout */
-
-#ifndef MAX_WORKERS
-# define MAX_WORKERS 10 /* number of in-flight queries */
-#endif
-
-struct worker_info {
- int qfd; /* query pipe's file descriptor */
- int afd; /* answer pipe's file descriptor */
- pid_t pid;
- bool busy;
- void *continuation; /* of outstanding request */
-};
-
-static struct worker_info wi[MAX_WORKERS];
-static struct worker_info *wi_roof = wi;
-
-/* request FIFO */
-
-struct query_list {
- struct query_list *next;
- struct adns_query aq;
-};
-
-static struct query_list *oldest_query = NULL;
-static struct query_list *newest_query; /* undefined when oldest == NULL */
-static struct query_list *free_queries = NULL;
-
-static bool
-spawn_worker(void)
-{
- int qfds[2];
- int afds[2];
- pid_t p;
-
- if (pipe(qfds) != 0 || pipe(afds) != 0)
- {
- syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
- exit(HES_PIPE);
- }
-
- wi_roof->qfd = qfds[1]; /* write end of query pipe */
- wi_roof->afd = afds[0]; /* read end of answer pipe */
-
- p = fork();
- if (p == -1)
- {
- /* fork failed: ignore if at least one worker exists */
- if (wi_roof == wi)
- {
- syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
- exit(HES_FORK);
- }
- close(qfds[0]);
- close(qfds[1]);
- close(afds[0]);
- close(afds[1]);
- return FALSE;
- }
- else if (p == 0)
- {
- /* child */
- struct worker_info *w;
-
- close(PLUTO_QFD);
- close(PLUTO_AFD);
- /* close all master pipes, including ours */
- for (w = wi; w <= wi_roof; w++)
- {
- close(w->qfd);
- close(w->afd);
- }
- exit(worker(qfds[0], afds[1]));
- }
- else
- {
- /* parent */
- struct worker_info *w = wi_roof++;
-
- w->pid = p;
- w->busy = FALSE;
- close(qfds[0]);
- close(afds[1]);
- return TRUE;
- }
-}
-
-static void
-send_eof(struct worker_info *w)
-{
- pid_t p;
- int status;
-
- close(w->qfd);
- w->qfd = NULL_FD;
-
- close(w->afd);
- w->afd = NULL_FD;
-
- /* reap child */
- p = waitpid(w->pid, &status, 0);
- /* ignore result -- what could we do with it? */
-}
-
-static void
-forward_query(struct worker_info *w)
-{
- struct query_list *q = oldest_query;
-
- if (q == NULL)
- {
- if (eof_from_pluto)
- send_eof(w);
- }
- else
- {
- enum helper_exit_status r
- = write_pipe(w->qfd, (const unsigned char *) &q->aq);
-
- if (r != HES_CONTINUE)
- exit(r);
-
- w->busy = TRUE;
-
- oldest_query = q->next;
- q->next = free_queries;
- free_queries = q;
- }
-}
-
-static void
-query(void)
-{
- struct query_list *q = free_queries;
- enum helper_exit_status r;
-
- /* find an unused queue entry */
- if (q == NULL)
- {
- q = malloc(sizeof(*q));
- if (q == NULL)
- {
- syslog(LOG_ERR, "malloc(3) failed");
- exit(HES_MALLOC);
- }
- }
- else
- {
- free_queries = q->next;
- }
-
- r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
- , sizeof(q->aq), sizeof(q->aq));
-
- if (r == HES_OK)
- {
- /* EOF: we're done, except for unanswered queries */
- struct worker_info *w;
-
- eof_from_pluto = TRUE;
- q->next = free_queries;
- free_queries = q;
-
- /* Send bye-bye to unbusy processes.
- * Note that if there are queued queries, there won't be
- * any non-busy workers.
- */
- for (w = wi; w != wi_roof; w++)
- if (!w->busy)
- send_eof(w);
- }
- else if (r != HES_CONTINUE)
- {
- exit(r);
- }
- else if (q->aq.qmagic != ADNS_Q_MAGIC)
- {
- syslog(LOG_ERR, "error in query from Pluto: bad magic");
- exit(HES_BAD_MAGIC);
- }
- else
- {
- struct worker_info *w;
-
- /* got a query */
-
- /* add it to FIFO */
- q->next = NULL;
- if (oldest_query == NULL)
- oldest_query = q;
- else
- newest_query->next = q;
- newest_query = q;
-
- /* See if any worker available */
- for (w = wi; ; w++)
- {
- if (w == wi_roof)
- {
- /* no free worker */
- if (w == wi + MAX_WORKERS)
- break; /* no more to be created */
- /* make a new one */
- if (!spawn_worker())
- break; /* cannot create one at this time */
- }
- if (!w->busy)
- {
- /* assign first to free worker */
- forward_query(w);
- break;
- }
- }
- }
- return;
-}
-
-static void
-answer(struct worker_info *w)
-{
- struct adns_answer a;
- enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
- , offsetof(struct adns_answer, ans), sizeof(a));
-
- if (r == HES_OK)
- {
- /* unexpected EOF */
- syslog(LOG_ERR, "unexpected EOF from worker");
- exit(HES_IO_ERROR_IN);
- }
- else if (r != HES_CONTINUE)
- {
- exit(r);
- }
- else if (a.amagic != ADNS_A_MAGIC)
- {
- syslog(LOG_ERR, "Input from worker error: bad magic");
- exit(HES_BAD_MAGIC);
- }
- else if (a.continuation != w->continuation)
- {
- /* answer doesn't match query */
- syslog(LOG_ERR, "Input from worker error: continuation mismatch");
- exit(HES_SYNC);
- }
- else
- {
- /* pass the answer on to Pluto */
- enum helper_exit_status r
- = write_pipe(PLUTO_AFD, (const unsigned char *) &a);
-
- if (r != HES_CONTINUE)
- exit(r);
- w->busy = FALSE;
- forward_query(w);
- }
-}
-
-/* assumption: input limited; accept blocking on output */
-static int
-master(void)
-{
- for (;;)
- {
- fd_set readfds;
- int maxfd = PLUTO_QFD; /* approximate lower bound */
- int ndes = 0;
- struct worker_info *w;
-
- FD_ZERO(&readfds);
- if (!eof_from_pluto)
- {
- FD_SET(PLUTO_QFD, &readfds);
- ndes++;
- }
- for (w = wi; w != wi_roof; w++)
- {
- if (w->busy)
- {
- FD_SET(w->afd, &readfds);
- ndes++;
- if (maxfd < w->afd)
- maxfd = w->afd;
- }
- }
-
- if (ndes == 0)
- return HES_OK; /* done! */
-
- do {
- ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
- } while (ndes == -1 && errno == EINTR);
- if (ndes == -1)
- {
- syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
- exit(HES_IO_ERROR_SELECT);
- }
- else if (ndes > 0)
- {
- if (FD_ISSET(PLUTO_QFD, &readfds))
- {
- query();
- ndes--;
- }
- for (w = wi; ndes > 0 && w != wi_roof; w++)
- {
- if (w->busy && FD_ISSET(w->afd, &readfds))
- {
- answer(w);
- ndes--;
- }
- }
- }
- }
-}
-
-/* Not to be invoked by strangers -- user hostile.
- * Mandatory args: query-fd answer-fd
- * Optional arg: -d, signifying "debug".
- */
-
-static void
-adns_usage(const char *fmt, const char *arg)
-{
- const char **sp = ipsec_copyright_notice();
-
- fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n");
-
- fprintf(stderr, fmt, arg);
- fprintf(stderr, "\n%s\n", ipsec_version_string());
-
- for (; *sp != NULL; sp++)
- fprintf(stderr, "%s\n", *sp);
-
- syslog(LOG_ERR, fmt, arg);
- exit(HES_INVOCATION);
-}
-
-int
-main(int argc UNUSED, char **argv)
-{
- int i = 1;
-
- name = argv[0];
-
- while (i < argc)
- {
- if (streq(argv[i], "-d"))
- {
- i++;
- debug = TRUE;
- }
- else
- {
- adns_usage("unexpected argument \"%s\"", argv[i]);
- /*NOTREACHED*/
- }
- }
-
- return master();
-}
-
-#endif /* !USE_LWRES */
diff --git a/programs/pluto/adns.h b/programs/pluto/adns.h
deleted file mode 100644
index 00fc4ad07..000000000
--- a/programs/pluto/adns.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Pluto Asynchronous DNS Helper Program's Header
- * Copyright (C) 2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: adns.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#ifndef USE_LWRES /* whole file! */
-
-/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
- * so we build some of our own :-(
- */
-
-# ifndef NS_MAXDNAME
-# define NS_MAXDNAME MAXDNAME /* I hope this is long enough for IPv6 */
-# endif
-
-# ifndef NS_PACKETSZ
-# define NS_PACKETSZ PACKETSZ
-# endif
-
-/* protocol version */
-
-#define ADNS_Q_MAGIC (((((('d' << 8) + 'n') << 8) + 's') << 8) + 4)
-#define ADNS_A_MAGIC (((((('d' << 8) + 'n') << 8) + 's') << 8) + 128 + 4)
-
-/* note: both struct adns_query and struct adns_answer must start with
- * size_t len;
- */
-
-struct adns_query {
- size_t len;
- unsigned int qmagic;
- unsigned long serial;
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
- u_char name_buf[NS_MAXDNAME + 2];
- int type; /* T_KEY or T_TXT */
-};
-
-struct adns_answer {
- size_t len;
- unsigned int amagic;
- unsigned long serial;
- struct adns_continuation *continuation;
- int result;
- int h_errno_val;
- u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
-};
-
-enum helper_exit_status {
- HES_CONTINUE = -1, /* not an exit */
- HES_OK = 0, /* all's well that ends well (perhaps EOF) */
- HES_INVOCATION, /* improper invocation */
- HES_IO_ERROR_SELECT, /* IO error in select() */
- HES_MALLOC, /* malloc failed */
- HES_IO_ERROR_IN, /* error reading pipe */
- HES_IO_ERROR_OUT, /* error reading pipe */
- HES_PIPE, /* pipe(2) failed */
- HES_SYNC, /* answer from worker doesn't match query */
- HES_FORK, /* fork(2) failed */
- HES_RES_INIT, /* resolver initialization failed */
- HES_BAD_LEN, /* implausible .len field */
- HES_BAD_MAGIC, /* .magic field wrong */
-};
-
-#endif /* !USE_LWRES */
diff --git a/programs/pluto/alg/Config.ike_alg b/programs/pluto/alg/Config.ike_alg
deleted file mode 100644
index 0fcda4cad..000000000
--- a/programs/pluto/alg/Config.ike_alg
+++ /dev/null
@@ -1,9 +0,0 @@
-##
-## IKE algorithms config. for static linking into pluto
-## By now 3DES,MD5 and SHA1 are already present in pluto.
-##
-CONFIG_IKE_ALG_AES=y
-CONFIG_IKE_ALG_BLOWFISH=y
-CONFIG_IKE_ALG_SERPENT=y
-CONFIG_IKE_ALG_TWOFISH=y
-CONFIG_IKE_ALG_SHA2=y
diff --git a/programs/pluto/alg/Makefile b/programs/pluto/alg/Makefile
deleted file mode 100644
index 9732cc80e..000000000
--- a/programs/pluto/alg/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-# pluto/alg Makefile
-# Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# $Id: Makefile,v 1.3 2004/06/23 04:45:20 as Exp $
-
-Make.common: ../Makefile
- make -s -C .. showdefs > $@
-
--include Make.common
-include Config.ike_alg
-
-LIBCRYPTO:=../../../lib/libcrypto
-ALLFLAGS=$(CPPFLAGS) $(CFLAGS) -I .. -I- -I ../../../linux/include -I $(LIBCRYPTO)
-LIBALG := libalg.o
-
-all : $(LIBALG)
-
-include $(wildcard Makefile.ike_alg_*)
-#include $(wildcard Makefile.ike_alg_[ab]*)
-
-ALG_DIRS:=$(ALG_DIRS-y)
-ALG_LIBS:=$(ALG_LIBS-y)
-ALG_SRCS:=$(ALG_SRCS-y)
-ALG_OBJS:=$(ALG_OBJS-y)
-$(LIBALG): ike_alginit.o $(ALG_OBJS) $(ALG_LIBS)
- $(LD) -r -o $@ $^
-
-# Search for IKE_ALG_INIT_NAME: in ike_alg_*.c to
-# build ike_alginit.c:ike_alginit()
-
-ike_alginit.c: $(ALG_SRCS) Makefile Config.ike_alg
- @awk ' \
- BEGIN { print "extern int ike_alg_init(void); \
- int ike_alg_init(void) {" } \
- /IKE_ALG_INIT_NAME:/ \
- { print "{ extern int " $$2" (void); " $$2 "();}" } \
- END { print "return 0;}" } \
- ' $(ALG_SRCS) /dev/null > $@
-
-clean :
- @for i in $(ALG_DIRS);do make -C $$i clean;done
- rm -f *.[oa] ike_alginit.c Make.common
-
-gatherdeps:
- @ls $(ALG_SRCS) | grep '\.c' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
- @echo
- @ls $(ALG_SRCS) | grep '\.c' | xargs grep '^#[ ]*include[ ]*"' | \
- sed -n -e '/#include.*"lib/d' \
- -e 's/\.c:#[ ]*include[ ]*"/.o: ..\//' -e 's/".*//p'
-
-# Dependencies generated by "make gatherdeps":
-
-ike_alg_aes.o: ike_alg_aes.c
-ike_alg_blowfish.o: ike_alg_blowfish.c
-ike_alg_serpent.o: ike_alg_serpent.c
-ike_alg_sha2.o: ike_alg_sha2.c
-ike_alg_twofish.o: ike_alg_twofish.c
-
-ike_alg_aes.o: ../constants.h
-ike_alg_aes.o: ../defs.h
-ike_alg_aes.o: ../log.h
-ike_alg_aes.o: ../alg_info.h
-ike_alg_aes.o: ../ike_alg.h
-ike_alg_blowfish.o: ../constants.h
-ike_alg_blowfish.o: ../defs.h
-ike_alg_blowfish.o: ../log.h
-ike_alg_blowfish.o: ../alg_info.h
-ike_alg_blowfish.o: ../ike_alg.h
-ike_alg_serpent.o: ../constants.h
-ike_alg_serpent.o: ../defs.h
-ike_alg_serpent.o: ../log.h
-ike_alg_serpent.o: ../alg_info.h
-ike_alg_serpent.o: ../ike_alg.h
-ike_alg_sha2.o: ../constants.h
-ike_alg_sha2.o: ../defs.h
-ike_alg_sha2.o: ../log.h
-ike_alg_sha2.o: ../alg_info.h
-ike_alg_sha2.o: ../ike_alg.h
-ike_alg_twofish.o: ../constants.h
-ike_alg_twofish.o: ../defs.h
-ike_alg_twofish.o: ../log.h
-ike_alg_twofish.o: ../alg_info.h
-ike_alg_twofish.o: ../ike_alg.h
diff --git a/programs/pluto/alg/Makefile.ike_alg_aes b/programs/pluto/alg/Makefile.ike_alg_aes
deleted file mode 100644
index 12009ba5c..000000000
--- a/programs/pluto/alg/Makefile.ike_alg_aes
+++ /dev/null
@@ -1,14 +0,0 @@
-ALG:=aes
-CONFIG_YES:=$(CONFIG_IKE_ALG_AES)
-DIR_AES:=$(LIBCRYPTO)/libaes
-
-ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_AES)
-ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_AES)/libaes.a
-ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
-ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
-
-$(DIR_AES)/libaes.a:
- make -C $(DIR_AES) CFLAGS="$(CFLAGS)" libaes.a
-
-ike_alg_$(ALG).o: ike_alg_$(ALG).c
- $(CC) -I $(LIBCRYPTO) -I$(DIR_AES) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_blowfish b/programs/pluto/alg/Makefile.ike_alg_blowfish
deleted file mode 100644
index c3af6199b..000000000
--- a/programs/pluto/alg/Makefile.ike_alg_blowfish
+++ /dev/null
@@ -1,13 +0,0 @@
-ALG:=blowfish
-CONFIG_YES:=$(CONFIG_IKE_ALG_BLOWFISH)
-DIR_BLOWFISH:=$(LIBCRYPTO)/libblowfish
-ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_BLOWFISH)
-ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_BLOWFISH)/libblowfish.a
-ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
-ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
-
-$(DIR_BLOWFISH)/libblowfish.a:
- make -C $(DIR_BLOWFISH) CFLAGS="$(CFLAGS)" libblowfish.a
-
-ike_alg_$(ALG).o: ike_alg_$(ALG).c
- $(CC) -I $(LIBCRYPTO) -I$(DIR_BLOWFISH) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_serpent b/programs/pluto/alg/Makefile.ike_alg_serpent
deleted file mode 100644
index 3395ac0ea..000000000
--- a/programs/pluto/alg/Makefile.ike_alg_serpent
+++ /dev/null
@@ -1,13 +0,0 @@
-ALG:=serpent
-CONFIG_YES:=$(CONFIG_IKE_ALG_SERPENT)
-DIR_SERPENT:=$(LIBCRYPTO)/libserpent
-ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_SERPENT)
-ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_SERPENT)/libserpent.a
-ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
-ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
-
-$(DIR_SERPENT)/libserpent.a:
- make -C $(DIR_SERPENT) CFLAGS="$(CFLAGS)" libserpent.a
-
-ike_alg_$(ALG).o: ike_alg_$(ALG).c
- $(CC) -I $(LIBCRYPTO) -I$(DIR_SERPENT) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_sha2 b/programs/pluto/alg/Makefile.ike_alg_sha2
deleted file mode 100644
index 67e68a667..000000000
--- a/programs/pluto/alg/Makefile.ike_alg_sha2
+++ /dev/null
@@ -1,13 +0,0 @@
-ALG:=sha2
-CONFIG_YES:=$(CONFIG_IKE_ALG_SHA2)
-DIR_SHA2:=$(LIBCRYPTO)/libsha2
-ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_SHA2)
-ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_SHA2)/libsha2.a
-ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
-ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
-
-$(DIR_SHA2)/libsha2.a:
- make -C $(DIR_SHA2) libsha2.a
-
-ike_alg_$(ALG).o: ike_alg_$(ALG).c
- $(CC) -I $(LIBCRYPTO) -I$(DIR_SHA2) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_twofish b/programs/pluto/alg/Makefile.ike_alg_twofish
deleted file mode 100644
index dcd30dd3e..000000000
--- a/programs/pluto/alg/Makefile.ike_alg_twofish
+++ /dev/null
@@ -1,13 +0,0 @@
-ALG:=twofish
-CONFIG_YES:=$(CONFIG_IKE_ALG_TWOFISH)
-DIR_TWOFISH:=$(LIBCRYPTO)/libtwofish
-ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_TWOFISH)
-ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_TWOFISH)/libtwofish.a
-ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
-ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
-
-$(DIR_TWOFISH)/libtwofish.a:
- make -C $(DIR_TWOFISH) CFLAGS="$(CFLAGS)" libtwofish.a
-
-ike_alg_$(ALG).o: ike_alg_$(ALG).c
- $(CC) -I $(LIBCRYPTO) -I$(DIR_TWOFISH) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/ike_alg_aes.c b/programs/pluto/alg/ike_alg_aes.c
deleted file mode 100644
index 44de09b4c..000000000
--- a/programs/pluto/alg/ike_alg_aes.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libaes/aes_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define AES_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define AES_KEY_MIN_LEN 128
-#define AES_KEY_DEF_LEN 128
-#define AES_KEY_MAX_LEN 256
-
-static void
-do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- aes_context aes_ctx;
- char iv_bak[AES_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
- aes_set_key(&aes_ctx, key, key_size, 0);
-
- /*
- * my AES cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak, (char*) buf + buf_len - AES_CBC_BLOCK_SIZE
- , AES_CBC_BLOCK_SIZE);
-
- AES_cbc_encrypt(&aes_ctx, buf, buf, buf_len, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_len-AES_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, AES_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc algo_aes =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_AES_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(aes_context),
- enc_blocksize: AES_CBC_BLOCK_SIZE,
- keyminlen: AES_KEY_MIN_LEN,
- keydeflen: AES_KEY_DEF_LEN,
- keymaxlen: AES_KEY_MAX_LEN,
- do_crypt: do_aes,
-};
-
-int ike_alg_aes_init(void);
-
-int
-ike_alg_aes_init(void)
-{
- int ret = ike_alg_register_enc(&algo_aes);
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_aes_init
-*/
diff --git a/programs/pluto/alg/ike_alg_blowfish.c b/programs/pluto/alg/ike_alg_blowfish.c
deleted file mode 100644
index 2bbef051b..000000000
--- a/programs/pluto/alg/ike_alg_blowfish.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libblowfish/blowfish.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define BLOWFISH_CBC_BLOCK_SIZE 8 /* block size */
-#define BLOWFISH_KEY_MIN_LEN 128
-#define BLOWFISH_KEY_MAX_LEN 448
-
-
-static void
-do_blowfish(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- BF_KEY bf_ctx;
-
- BF_set_key(&bf_ctx, key_size , key);
- BF_cbc_encrypt(buf, buf, buf_len, &bf_ctx, iv, enc);
-}
-
-struct encrypt_desc algo_blowfish =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_BLOWFISH_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(BF_KEY),
- enc_blocksize: BLOWFISH_CBC_BLOCK_SIZE,
- keyminlen: BLOWFISH_KEY_MIN_LEN,
- keydeflen: BLOWFISH_KEY_MIN_LEN,
- keymaxlen: BLOWFISH_KEY_MAX_LEN,
- do_crypt: do_blowfish,
-};
-
-int ike_alg_blowfish_init(void);
-
-int
-ike_alg_blowfish_init(void)
-{
- int ret = ike_alg_register_enc(&algo_blowfish);
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_blowfish_init
-*/
diff --git a/programs/pluto/alg/ike_alg_serpent.c b/programs/pluto/alg/ike_alg_serpent.c
deleted file mode 100644
index fb01caa41..000000000
--- a/programs/pluto/alg/ike_alg_serpent.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libserpent/serpent_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define SERPENT_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define SERPENT_KEY_MIN_LEN 128
-#define SERPENT_KEY_DEF_LEN 128
-#define SERPENT_KEY_MAX_LEN 256
-
-static void
-do_serpent(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- serpent_context serpent_ctx;
- char iv_bak[SERPENT_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
-
- serpent_set_key(&serpent_ctx, key, key_size);
- /*
- * my SERPENT cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak,
- (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE,
- SERPENT_CBC_BLOCK_SIZE);
-
- serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc encrypt_desc_serpent =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_SERPENT_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(struct serpent_context),
- enc_blocksize: SERPENT_CBC_BLOCK_SIZE,
- keyminlen: SERPENT_KEY_MIN_LEN,
- keydeflen: SERPENT_KEY_DEF_LEN,
- keymaxlen: SERPENT_KEY_MAX_LEN,
- do_crypt: do_serpent,
-};
-
-int ike_alg_serpent_init(void);
-
-int
-ike_alg_serpent_init(void)
-{
- int ret = ike_alg_register_enc(&encrypt_desc_serpent);
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_serpent_init
-*/
diff --git a/programs/pluto/alg/ike_alg_sha2.c b/programs/pluto/alg/ike_alg_sha2.c
deleted file mode 100644
index 6b7c8438c..000000000
--- a/programs/pluto/alg/ike_alg_sha2.c
+++ /dev/null
@@ -1,634 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libsha2/sha2.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-static void
-sha256_hash_final(u_char *hash, sha256_context *ctx)
-{
- sha256_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_256_DIGEST_SIZE);
-}
-
-static void
-sha384_hash_final(u_char *hash, sha512_context *ctx)
-{
- sha512_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_384_DIGEST_SIZE);
-}
-
-static void
-sha512_hash_final(u_char *hash, sha512_context *ctx)
-{
- sha512_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_512_DIGEST_SIZE);
-}
-
-/* SHA-256 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha256_short2_msg[] = {
- 0x19
-};
-
-static const u_char sha256_short2_msg_digest[] = {
- 0x68, 0xaa, 0x2e, 0x2e, 0xe5, 0xdf, 0xf9, 0x6e,
- 0x33, 0x55, 0xe6, 0xc7, 0xee, 0x37, 0x3e, 0x3d,
- 0x6a, 0x4e, 0x17, 0xf7, 0x5f, 0x95, 0x18, 0xd8,
- 0x43, 0x70, 0x9c, 0x0c, 0x9b, 0xc3, 0xe3, 0xd4
-};
-
-static const u_char sha256_short4_msg[] = {
- 0xe3, 0xd7, 0x25, 0x70, 0xdc, 0xdd, 0x78, 0x7c,
- 0xe3, 0x88, 0x7a, 0xb2, 0xcd, 0x68, 0x46, 0x52
-};
-
-static const u_char sha256_short4_msg_digest[] = {
- 0x17, 0x5e, 0xe6, 0x9b, 0x02, 0xba, 0x9b, 0x58,
- 0xe2, 0xb0, 0xa5, 0xfd, 0x13, 0x81, 0x9c, 0xea,
- 0x57, 0x3f, 0x39, 0x40, 0xa9, 0x4f, 0x82, 0x51,
- 0x28, 0xcf, 0x42, 0x09, 0xbe, 0xab, 0xb4, 0xe8
-};
-
-static const u_char sha256_long2_msg[] = {
- 0x83, 0x26, 0x75, 0x4e, 0x22, 0x77, 0x37, 0x2f,
- 0x4f, 0xc1, 0x2b, 0x20, 0x52, 0x7a, 0xfe, 0xf0,
- 0x4d, 0x8a, 0x05, 0x69, 0x71, 0xb1, 0x1a, 0xd5,
- 0x71, 0x23, 0xa7, 0xc1, 0x37, 0x76, 0x00, 0x00,
- 0xd7, 0xbe, 0xf6, 0xf3, 0xc1, 0xf7, 0xa9, 0x08,
- 0x3a, 0xa3, 0x9d, 0x81, 0x0d, 0xb3, 0x10, 0x77,
- 0x7d, 0xab, 0x8b, 0x1e, 0x7f, 0x02, 0xb8, 0x4a,
- 0x26, 0xc7, 0x73, 0x32, 0x5f, 0x8b, 0x23, 0x74,
- 0xde, 0x7a, 0x4b, 0x5a, 0x58, 0xcb, 0x5c, 0x5c,
- 0xf3, 0x5b, 0xce, 0xe6, 0xfb, 0x94, 0x6e, 0x5b,
- 0xd6, 0x94, 0xfa, 0x59, 0x3a, 0x8b, 0xeb, 0x3f,
- 0x9d, 0x65, 0x92, 0xec, 0xed, 0xaa, 0x66, 0xca,
- 0x82, 0xa2, 0x9d, 0x0c, 0x51, 0xbc, 0xf9, 0x33,
- 0x62, 0x30, 0xe5, 0xd7, 0x84, 0xe4, 0xc0, 0xa4,
- 0x3f, 0x8d, 0x79, 0xa3, 0x0a, 0x16, 0x5c, 0xba,
- 0xbe, 0x45, 0x2b, 0x77, 0x4b, 0x9c, 0x71, 0x09,
- 0xa9, 0x7d, 0x13, 0x8f, 0x12, 0x92, 0x28, 0x96,
- 0x6f, 0x6c, 0x0a, 0xdc, 0x10, 0x6a, 0xad, 0x5a,
- 0x9f, 0xdd, 0x30, 0x82, 0x57, 0x69, 0xb2, 0xc6,
- 0x71, 0xaf, 0x67, 0x59, 0xdf, 0x28, 0xeb, 0x39,
- 0x3d, 0x54, 0xd6
-};
-
-static const u_char sha256_long2_msg_digest[] = {
- 0x97, 0xdb, 0xca, 0x7d, 0xf4, 0x6d, 0x62, 0xc8,
- 0xa4, 0x22, 0xc9, 0x41, 0xdd, 0x7e, 0x83, 0x5b,
- 0x8a, 0xd3, 0x36, 0x17, 0x63, 0xf7, 0xe9, 0xb2,
- 0xd9, 0x5f, 0x4f, 0x0d, 0xa6, 0xe1, 0xcc, 0xbc
-};
-
-static const hash_testvector_t sha256_hash_testvectors[] = {
- { sizeof(sha256_short2_msg), sha256_short2_msg, sha256_short2_msg_digest },
- { sizeof(sha256_short4_msg), sha256_short4_msg, sha256_short4_msg_digest },
- { sizeof(sha256_long2_msg), sha256_long2_msg, sha256_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-384 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha384_short2_msg[] = {
- 0xb9
-};
-
-static const u_char sha384_short2_msg_digest[] = {
- 0xbc, 0x80, 0x89, 0xa1, 0x90, 0x07, 0xc0, 0xb1,
- 0x41, 0x95, 0xf4, 0xec, 0xc7, 0x40, 0x94, 0xfe,
- 0xc6, 0x4f, 0x01, 0xf9, 0x09, 0x29, 0x28, 0x2c,
- 0x2f, 0xb3, 0x92, 0x88, 0x15, 0x78, 0x20, 0x8a,
- 0xd4, 0x66, 0x82, 0x8b, 0x1c, 0x6c, 0x28, 0x3d,
- 0x27, 0x22, 0xcf, 0x0a, 0xd1, 0xab, 0x69, 0x38
-};
-
-static const u_char sha384_short4_msg[] = {
- 0xa4, 0x1c, 0x49, 0x77, 0x79, 0xc0, 0x37, 0x5f,
- 0xf1, 0x0a, 0x7f, 0x4e, 0x08, 0x59, 0x17, 0x39
-};
-
-static const u_char sha384_short4_msg_digest[] = {
- 0xc9, 0xa6, 0x84, 0x43, 0xa0, 0x05, 0x81, 0x22,
- 0x56, 0xb8, 0xec, 0x76, 0xb0, 0x05, 0x16, 0xf0,
- 0xdb, 0xb7, 0x4f, 0xab, 0x26, 0xd6, 0x65, 0x91,
- 0x3f, 0x19, 0x4b, 0x6f, 0xfb, 0x0e, 0x91, 0xea,
- 0x99, 0x67, 0x56, 0x6b, 0x58, 0x10, 0x9c, 0xbc,
- 0x67, 0x5c, 0xc2, 0x08, 0xe4, 0xc8, 0x23, 0xf7
-};
-
-static const u_char sha384_long2_msg[] = {
- 0x39, 0x96, 0x69, 0xe2, 0x8f, 0x6b, 0x9c, 0x6d,
- 0xbc, 0xbb, 0x69, 0x12, 0xec, 0x10, 0xff, 0xcf,
- 0x74, 0x79, 0x03, 0x49, 0xb7, 0xdc, 0x8f, 0xbe,
- 0x4a, 0x8e, 0x7b, 0x3b, 0x56, 0x21, 0xdb, 0x0f,
- 0x3e, 0x7d, 0xc8, 0x7f, 0x82, 0x32, 0x64, 0xbb,
- 0xe4, 0x0d, 0x18, 0x11, 0xc9, 0xea, 0x20, 0x61,
- 0xe1, 0xc8, 0x4a, 0xd1, 0x0a, 0x23, 0xfa, 0xc1,
- 0x72, 0x7e, 0x72, 0x02, 0xfc, 0x3f, 0x50, 0x42,
- 0xe6, 0xbf, 0x58, 0xcb, 0xa8, 0xa2, 0x74, 0x6e,
- 0x1f, 0x64, 0xf9, 0xb9, 0xea, 0x35, 0x2c, 0x71,
- 0x15, 0x07, 0x05, 0x3c, 0xf4, 0xe5, 0x33, 0x9d,
- 0x52, 0x86, 0x5f, 0x25, 0xcc, 0x22, 0xb5, 0xe8,
- 0x77, 0x84, 0xa1, 0x2f, 0xc9, 0x61, 0xd6, 0x6c,
- 0xb6, 0xe8, 0x95, 0x73, 0x19, 0x9a, 0x2c, 0xe6,
- 0x56, 0x5c, 0xbd, 0xf1, 0x3d, 0xca, 0x40, 0x38,
- 0x32, 0xcf, 0xcb, 0x0e, 0x8b, 0x72, 0x11, 0xe8,
- 0x3a, 0xf3, 0x2a, 0x11, 0xac, 0x17, 0x92, 0x9f,
- 0xf1, 0xc0, 0x73, 0xa5, 0x1c, 0xc0, 0x27, 0xaa,
- 0xed, 0xef, 0xf8, 0x5a, 0xad, 0x7c, 0x2b, 0x7c,
- 0x5a, 0x80, 0x3e, 0x24, 0x04, 0xd9, 0x6d, 0x2a,
- 0x77, 0x35, 0x7b, 0xda, 0x1a, 0x6d, 0xae, 0xed,
- 0x17, 0x15, 0x1c, 0xb9, 0xbc, 0x51, 0x25, 0xa4,
- 0x22, 0xe9, 0x41, 0xde, 0x0c, 0xa0, 0xfc, 0x50,
- 0x11, 0xc2, 0x3e, 0xcf, 0xfe, 0xfd, 0xd0, 0x96,
- 0x76, 0x71, 0x1c, 0xf3, 0xdb, 0x0a, 0x34, 0x40,
- 0x72, 0x0e ,0x16, 0x15, 0xc1, 0xf2, 0x2f, 0xbc,
- 0x3c, 0x72, 0x1d, 0xe5, 0x21, 0xe1, 0xb9, 0x9b,
- 0xa1, 0xbd, 0x55, 0x77, 0x40, 0x86, 0x42, 0x14,
- 0x7e, 0xd0, 0x96
-};
-
-static const u_char sha384_long2_msg_digest[] = {
- 0x4f, 0x44, 0x0d, 0xb1, 0xe6, 0xed, 0xd2, 0x89,
- 0x9f, 0xa3, 0x35, 0xf0, 0x95, 0x15, 0xaa, 0x02,
- 0x5e, 0xe1, 0x77, 0xa7, 0x9f, 0x4b, 0x4a, 0xaf,
- 0x38, 0xe4, 0x2b, 0x5c, 0x4d, 0xe6, 0x60, 0xf5,
- 0xde, 0x8f, 0xb2, 0xa5, 0xb2, 0xfb, 0xd2, 0xa3,
- 0xcb, 0xff, 0xd2, 0x0c, 0xff, 0x12, 0x88, 0xc0
-};
-
-static const hash_testvector_t sha384_hash_testvectors[] = {
- { sizeof(sha384_short2_msg), sha384_short2_msg, sha384_short2_msg_digest },
- { sizeof(sha384_short4_msg), sha384_short4_msg, sha384_short4_msg_digest },
- { sizeof(sha384_long2_msg), sha384_long2_msg, sha384_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-512 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha512_short2_msg[] = {
- 0xd0
-};
-
-static const u_char sha512_short2_msg_digest[] = {
- 0x99, 0x92, 0x20, 0x29, 0x38, 0xe8, 0x82, 0xe7,
- 0x3e, 0x20, 0xf6, 0xb6, 0x9e, 0x68, 0xa0, 0xa7,
- 0x14, 0x90, 0x90, 0x42, 0x3d, 0x93, 0xc8, 0x1b,
- 0xab, 0x3f, 0x21, 0x67, 0x8d, 0x4a, 0xce, 0xee,
- 0xe5, 0x0e, 0x4e, 0x8c, 0xaf, 0xad, 0xa4, 0xc8,
- 0x5a, 0x54, 0xea, 0x83, 0x06, 0x82, 0x6c, 0x4a,
- 0xd6, 0xe7, 0x4c, 0xec, 0xe9, 0x63, 0x1b, 0xfa,
- 0x8a, 0x54, 0x9b, 0x4a, 0xb3, 0xfb, 0xba, 0x15
-};
-
-static const u_char sha512_short4_msg[] = {
- 0x8d, 0x4e, 0x3c, 0x0e, 0x38, 0x89, 0x19, 0x14,
- 0x91, 0x81, 0x6e, 0x9d, 0x98, 0xbf, 0xf0, 0xa0
-};
-
-static const u_char sha512_short4_msg_digest[] = {
- 0xcb, 0x0b, 0x67, 0xa4, 0xb8, 0x71, 0x2c, 0xd7,
- 0x3c, 0x9a, 0xab, 0xc0, 0xb1, 0x99, 0xe9, 0x26,
- 0x9b, 0x20, 0x84, 0x4a, 0xfb, 0x75, 0xac, 0xbd,
- 0xd1, 0xc1, 0x53, 0xc9, 0x82, 0x89, 0x24, 0xc3,
- 0xdd, 0xed, 0xaa, 0xfe, 0x66, 0x9c, 0x5f, 0xdd,
- 0x0b, 0xc6, 0x6f, 0x63, 0x0f, 0x67, 0x73, 0x98,
- 0x82, 0x13, 0xeb, 0x1b, 0x16, 0xf5, 0x17, 0xad,
- 0x0d, 0xe4, 0xb2, 0xf0, 0xc9, 0x5c, 0x90, 0xf8
-};
-
-static const u_char sha512_long2_msg[] = {
- 0xa5, 0x5f, 0x20, 0xc4, 0x11, 0xaa, 0xd1, 0x32,
- 0x80, 0x7a, 0x50, 0x2d, 0x65, 0x82, 0x4e, 0x31,
- 0xa2, 0x30, 0x54, 0x32, 0xaa, 0x3d, 0x06, 0xd3,
- 0xe2, 0x82, 0xa8, 0xd8, 0x4e, 0x0d, 0xe1, 0xde,
- 0x69, 0x74, 0xbf, 0x49, 0x54, 0x69, 0xfc, 0x7f,
- 0x33, 0x8f, 0x80, 0x54, 0xd5, 0x8c, 0x26, 0xc4,
- 0x93, 0x60, 0xc3, 0xe8, 0x7a, 0xf5, 0x65, 0x23,
- 0xac, 0xf6, 0xd8, 0x9d, 0x03, 0xe5, 0x6f, 0xf2,
- 0xf8, 0x68, 0x00, 0x2b, 0xc3, 0xe4, 0x31, 0xed,
- 0xc4, 0x4d, 0xf2, 0xf0, 0x22, 0x3d, 0x4b, 0xb3,
- 0xb2, 0x43, 0x58, 0x6e, 0x1a, 0x7d, 0x92, 0x49,
- 0x36, 0x69, 0x4f, 0xcb, 0xba, 0xf8, 0x8d, 0x95,
- 0x19, 0xe4, 0xeb, 0x50, 0xa6, 0x44, 0xf8, 0xe4,
- 0xf9, 0x5e, 0xb0, 0xea, 0x95, 0xbc, 0x44, 0x65,
- 0xc8, 0x82, 0x1a, 0xac, 0xd2, 0xfe, 0x15, 0xab,
- 0x49, 0x81, 0x16, 0x4b, 0xbb, 0x6d, 0xc3, 0x2f,
- 0x96, 0x90, 0x87, 0xa1, 0x45, 0xb0, 0xd9, 0xcc,
- 0x9c, 0x67, 0xc2, 0x2b, 0x76, 0x32, 0x99, 0x41,
- 0x9c, 0xc4, 0x12, 0x8b, 0xe9, 0xa0, 0x77, 0xb3,
- 0xac, 0xe6, 0x34, 0x06, 0x4e, 0x6d, 0x99, 0x28,
- 0x35, 0x13, 0xdc, 0x06, 0xe7, 0x51, 0x5d, 0x0d,
- 0x73, 0x13, 0x2e, 0x9a, 0x0d, 0xc6, 0xd3, 0xb1,
- 0xf8, 0xb2, 0x46, 0xf1, 0xa9, 0x8a, 0x3f, 0xc7,
- 0x29, 0x41, 0xb1, 0xe3, 0xbb, 0x20, 0x98, 0xe8,
- 0xbf, 0x16, 0xf2, 0x68, 0xd6, 0x4f, 0x0b, 0x0f,
- 0x47, 0x07, 0xfe, 0x1e, 0xa1, 0xa1, 0x79, 0x1b,
- 0xa2, 0xf3, 0xc0, 0xc7, 0x58, 0xe5, 0xf5, 0x51,
- 0x86, 0x3a, 0x96, 0xc9, 0x49, 0xad, 0x47, 0xd7,
- 0xfb, 0x40, 0xd2
-};
-
-static const u_char sha512_long2_msg_digest[] = {
- 0xc6, 0x65, 0xbe, 0xfb, 0x36, 0xda, 0x18, 0x9d,
- 0x78, 0x82, 0x2d, 0x10, 0x52, 0x8c, 0xbf, 0x3b,
- 0x12, 0xb3, 0xee, 0xf7, 0x26, 0x03, 0x99, 0x09,
- 0xc1, 0xa1, 0x6a, 0x27, 0x0d, 0x48, 0x71, 0x93,
- 0x77, 0x96, 0x6b, 0x95, 0x7a, 0x87, 0x8e, 0x72,
- 0x05, 0x84, 0x77, 0x9a, 0x62, 0x82, 0x5c, 0x18,
- 0xda, 0x26, 0x41, 0x5e, 0x49, 0xa7, 0x17, 0x6a,
- 0x89, 0x4e, 0x75, 0x10, 0xfd, 0x14, 0x51, 0xf5
-};
-
-static const hash_testvector_t sha512_hash_testvectors[] = {
- { sizeof(sha512_short2_msg), sha512_short2_msg, sha512_short2_msg_digest },
- { sizeof(sha512_short4_msg), sha512_short4_msg, sha512_short4_msg_digest },
- { sizeof(sha512_long2_msg), sha512_long2_msg, sha512_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-256, SHA-384, and SHA-512 hmac test vectors
- * from RFC 4231 "Identifiers and Test Vectors for HMAC-SHA-224,
- * HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512"
- * December 2005, M. Nystrom, RSA Security
- */
-
-static const u_char sha2_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b
-};
-
-static const u_char sha2_hmac1_msg[] = {
- 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-};
-
-static const u_char sha2_hmac1_256[] = {
- 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
- 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
- 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
- 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7
-};
-
-static const u_char sha2_hmac1_384[] = {
- 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
- 0x6b, 0x08, 0x25, 0xf4, 0xab ,0x46, 0x90, 0x7f,
- 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
- 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
- 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
- 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6
-};
-
-static const u_char sha2_hmac1_512[] = {
- 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
- 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
- 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
- 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
- 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
- 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
- 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
- 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54
-};
-
-static const u_char sha2_hmac2_key[] = {
- 0x4a, 0x65, 0x66, 0x65
-};
-
-static const u_char sha2_hmac2_msg[] = {
- 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
- 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
- 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
- 0x69, 0x6e, 0x67, 0x3f
-};
-
-static const u_char sha2_hmac2_256[] = {
- 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
- 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
- 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
- 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43
-};
-
-static const u_char sha2_hmac2_384[] = {
- 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
- 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
- 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
- 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
- 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
- 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49
-};
-
-static const u_char sha2_hmac2_512[] = {
- 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
- 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
- 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
- 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
- 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
- 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
- 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
- 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37
-};
-
-static const u_char sha2_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa
-};
-
-static const u_char sha2_hmac3_msg[] = {
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd
-};
-
-static const u_char sha2_hmac3_256[] = {
- 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
- 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
- 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
- 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe
-};
-
-static const u_char sha2_hmac3_384[] = {
- 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
- 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
- 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
- 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
- 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
- 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27
-};
-
-static const u_char sha2_hmac3_512[] = {
- 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
- 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
- 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
- 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
- 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
- 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
- 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
- 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb
-};
-
-static const u_char sha2_hmac4_key[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19
-};
-
-static const u_char sha2_hmac4_msg[] = {
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd
-};
-
-static const u_char sha2_hmac4_256[] = {
- 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
- 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
- 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
- 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b
-};
-
-static const u_char sha2_hmac4_384[] = {
- 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
- 0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
- 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
- 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
- 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
- 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb
-};
-
-static const u_char sha2_hmac4_512[] = {
- 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
- 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
- 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
- 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
- 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
- 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
- 0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
- 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd
-};
-
-static const u_char sha2_hmac6_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa
-};
-
-static const u_char sha2_hmac6_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
- 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
- 0x20, 0x46, 0x69, 0x72, 0x73, 0x74
-};
-
-static const u_char sha2_hmac6_256[] = {
- 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
- 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
- 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
- 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54
-};
-
-static const u_char sha2_hmac6_384[] = {
- 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
- 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
- 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
- 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
- 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
- 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52
-};
-
-static const u_char sha2_hmac6_512[] = {
- 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
- 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
- 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
- 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
- 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
- 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
- 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
- 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98
-};
-
-static const u_char sha2_hmac7_msg[] = {
- 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
- 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75,
- 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
- 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68,
- 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
- 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65,
- 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
- 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74,
- 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
- 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64,
- 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
- 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65,
- 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
- 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20,
- 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
- 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65,
- 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c,
- 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e
-};
-
-static const u_char sha2_hmac7_256[] = {
- 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
- 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
- 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
- 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2
-};
-
-static const u_char sha2_hmac7_384[] = {
- 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
- 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
- 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
- 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
- 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
- 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e
-};
-
-static const u_char sha2_hmac7_512[] = {
- 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
- 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
- 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
- 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
- 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
- 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
- 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
- 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58
-};
-
-static const hmac_testvector_t sha256_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_256 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_256 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_256 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_256 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_256 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_256 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static const hmac_testvector_t sha384_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_384 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_384 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_384 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_384 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_384 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_384 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static const hmac_testvector_t sha512_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_512 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_512 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_512 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_512 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_512 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_512 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-struct hash_desc hash_desc_sha2_256 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_256,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha256_context),
- hash_block_size: SHA2_256_BLOCK_SIZE,
- hash_digest_size: SHA2_256_DIGEST_SIZE,
- hash_testvectors: sha256_hash_testvectors,
- hmac_testvectors: sha256_hmac_testvectors,
- hash_init: (void (*)(void *))sha256_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha256_write,
- hash_final:(void (*)(u_char *, void *))sha256_hash_final
-};
-
-struct hash_desc hash_desc_sha2_384 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_384,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha512_context),
- hash_block_size: SHA2_384_BLOCK_SIZE,
- hash_digest_size: SHA2_384_DIGEST_SIZE,
- hash_testvectors: sha384_hash_testvectors,
- hmac_testvectors: sha384_hmac_testvectors,
- hash_init: (void (*)(void *))sha384_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha512_write,
- hash_final:(void (*)(u_char *, void *))sha384_hash_final
-};
-
-struct hash_desc hash_desc_sha2_512 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_512,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha512_context),
- hash_block_size: SHA2_512_BLOCK_SIZE,
- hash_digest_size: SHA2_512_DIGEST_SIZE,
- hash_testvectors: sha512_hash_testvectors,
- hmac_testvectors: sha512_hmac_testvectors,
- hash_init: (void (*)(void *))sha512_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha512_write,
- hash_final:(void (*)(u_char *, void *))sha512_hash_final
-};
-
-int ike_alg_sha2_init(void);
-
-int
-ike_alg_sha2_init(void)
-{
- int ret
-;
- ret = ike_alg_register_hash(&hash_desc_sha2_256);
- if (ret)
- goto out;
- ret = ike_alg_register_hash(&hash_desc_sha2_384);
- if (ret)
- goto out;
- ret = ike_alg_register_hash(&hash_desc_sha2_512);
-
-out:
- return ret;
-}
-
-/*
-IKE_ALG_INIT_NAME: ike_alg_sha2_init
-*/
diff --git a/programs/pluto/alg/ike_alg_twofish.c b/programs/pluto/alg/ike_alg_twofish.c
deleted file mode 100644
index 1788bc394..000000000
--- a/programs/pluto/alg/ike_alg_twofish.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libtwofish/twofish_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define TWOFISH_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define TWOFISH_KEY_MIN_LEN 128
-#define TWOFISH_KEY_DEF_LEN 128
-#define TWOFISH_KEY_MAX_LEN 256
-
-static void
-do_twofish(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- twofish_context twofish_ctx;
- char iv_bak[TWOFISH_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
- twofish_set_key(&twofish_ctx, key, key_size);
- /*
- * my TWOFISH cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak,
- (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE,
- TWOFISH_CBC_BLOCK_SIZE);
-
- twofish_cbc_encrypt(&twofish_ctx, buf, buf, buf_size, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, TWOFISH_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc encrypt_desc_twofish =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_TWOFISH_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(twofish_context),
- enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
- keydeflen: TWOFISH_KEY_MIN_LEN,
- keyminlen: TWOFISH_KEY_DEF_LEN,
- keymaxlen: TWOFISH_KEY_MAX_LEN,
- do_crypt: do_twofish,
-};
-
-struct encrypt_desc encrypt_desc_twofish_ssh =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_TWOFISH_CBC_SSH,
- algo_next: NULL,
- enc_ctxsize: sizeof(twofish_context),
- enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
- keydeflen: TWOFISH_KEY_MIN_LEN,
- keyminlen: TWOFISH_KEY_DEF_LEN,
- keymaxlen: TWOFISH_KEY_MAX_LEN,
- do_crypt: do_twofish,
-};
-
-int ike_alg_twofish_init(void);
-
-int
-ike_alg_twofish_init(void)
-{
- int ret = ike_alg_register_enc(&encrypt_desc_twofish);
-
- if (ike_alg_register_enc(&encrypt_desc_twofish_ssh) < 0)
- plog("ike_alg_twofish_init(): Experimental OAKLEY_TWOFISH_CBC_SSH activation failed");
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_twofish_init
-*/
diff --git a/programs/pluto/alg_info.c b/programs/pluto/alg_info.c
deleted file mode 100644
index af2753312..000000000
--- a/programs/pluto/alg_info.c
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*
- * Algorithm info parsing and creation functions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * $Id: alg_info.c,v 1.6 2006/08/03 10:18:21 as Exp $
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-#include <pfkeyv2.h>
-
-#include "alg_info.h"
-#include "constants.h"
-#ifndef NO_PLUTO
-#include "defs.h"
-#include "log.h"
-#include "whack.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h"
-#include "kernel_alg.h"
-#include "ike_alg.h"
-#else
-/*
- * macros/functions for compilation without pluto (eg: spi for manual conns)
- */
-#include <assert.h>
-#define passert(x) assert(x)
-extern int debug; /* eg: spi.c */
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define RC_LOG_SERIOUS
-#define loglog(x, args...) fprintf(stderr, ##args);
-#define alloc_thing(thing, name) alloc_bytes(sizeof (thing), name)
-void * alloc_bytes(size_t size, const char *name) {
- void *p=malloc(size);
- if (p == NULL)
- fprintf(stderr, "unable to malloc %lu bytes for %s",
- (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-#define pfreeany(ptr) free(ptr)
-#endif /* NO_PLUTO */
-
-/*
- * sadb/ESP aa attrib converters
- */
-int
-alg_info_esp_aa2sadb(int auth)
-{
- int sadb_aalg = 0;
-
- switch(auth) {
- case AUTH_ALGORITHM_HMAC_MD5:
- case AUTH_ALGORITHM_HMAC_SHA1:
- sadb_aalg = auth + 1;
- break;
- case AUTH_ALGORITHM_HMAC_SHA2_256:
- case AUTH_ALGORITHM_HMAC_SHA2_384:
- case AUTH_ALGORITHM_HMAC_SHA2_512:
- case AUTH_ALGORITHM_HMAC_RIPEMD:
- sadb_aalg = auth;
- break;
- default:
- /* loose ... */
- sadb_aalg = auth;
- }
- return sadb_aalg;
-}
-
-int /* __attribute__ ((unused)) */
-alg_info_esp_sadb2aa(int sadb_aalg)
-{
- int auth = 0;
-
- switch(sadb_aalg) {
- case SADB_AALG_MD5_HMAC:
- case SADB_AALG_SHA1_HMAC:
- auth = sadb_aalg - 1;
- break;
- /* since they are the same ... :) */
- case AUTH_ALGORITHM_HMAC_SHA2_256:
- case AUTH_ALGORITHM_HMAC_SHA2_384:
- case AUTH_ALGORITHM_HMAC_SHA2_512:
- case AUTH_ALGORITHM_HMAC_RIPEMD:
- auth = sadb_aalg;
- break;
- default:
- /* loose ... */
- auth = sadb_aalg;
- }
- return auth;
-}
-
-/*
- * Search enum_name array with in prefixed uppercase
- */
-static int
-enum_search_prefix (enum_names *ed, const char *prefix, const char *str, int strlen)
-{
- char buf[64];
- char *ptr;
- int ret;
- int len = sizeof(buf) - 1; /* reserve space for final \0 */
-
- for (ptr = buf; *prefix; *ptr++ = *prefix++, len--);
- while (strlen-- && len-- && *str) *ptr++ = toupper(*str++);
- *ptr = 0;
-
- DBG(DBG_CRYPT,
- DBG_log("enum_search_prefix () calling enum_search(%p, \"%s\")"
- , ed, buf)
- )
- ret = enum_search(ed, buf);
- return ret;
-}
-
-/*
- * Search enum_name array with in prefixed and postfixed uppercase
- */
-static int
-enum_search_ppfix (enum_names *ed, const char *prefix, const char *postfix, const char *str, int strlen)
-{
- char buf[64];
- char *ptr;
- int ret;
- int len = sizeof(buf) - 1; /* reserve space for final \0 */
-
- for (ptr = buf; *prefix; *ptr++ = *prefix++, len--);
- while (strlen-- && len-- && *str) *ptr++ = toupper(*str++);
- while (len-- && *postfix) *ptr++ = *postfix++;
- *ptr = 0;
-
- DBG(DBG_CRYPT,
- DBG_log("enum_search_ppfixi () calling enum_search(%p, \"%s\")"
- , ed, buf)
- )
- ret = enum_search(ed, buf);
- return ret;
-}
-
-/*
- * Search esp_transformid_names for a match, eg:
- * "3des" <=> "ESP_3DES"
- */
-#define ESP_MAGIC_ID 0x00ffff01
-
-static int
-ealg_getbyname_esp(const char *const str, int len)
-{
- if (!str || !*str)
- return -1;
-
- /* leave special case for eg: "id248" string */
- if (strcmp("id", str) == 0)
- return ESP_MAGIC_ID;
-
- return enum_search_prefix(&esp_transformid_names, "ESP_", str, len);
-}
-
-/*
- * Search auth_alg_names for a match, eg:
- * "md5" <=> "AUTH_ALGORITHM_HMAC_MD5"
- */
-static int
-aalg_getbyname_esp(const char *const str, int len)
-{
- int ret;
- unsigned num;
-
- if (!str || !*str)
- return -1;
-
- /* interpret 'SHA' as 'SHA1' */
- if (strncasecmp("SHA", str, len) == 0)
- return enum_search(&auth_alg_names, "AUTH_ALGORITHM_HMAC_SHA1");
-
- ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_", str ,len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_", str, len);
- if (ret >= 0)
- return ret;
-
- sscanf(str, "id%d%n", &ret, &num);
- return (ret >= 0 && num != strlen(str))? -1 : ret;
-}
-
-static int
-modp_getbyname_esp(const char *const str, int len)
-{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);
- return ret;
-}
-
-void
-alg_info_free(struct alg_info *alg_info)
-{
- pfreeany(alg_info);
-}
-
-/*
- * Raw add routine: only checks for no duplicates
- */
-static void
-__alg_info_esp_add (struct alg_info_esp *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits)
-{
- struct esp_info *esp_info=alg_info->esp;
- unsigned cnt = alg_info->alg_info_cnt, i;
-
- /* check for overflows */
- passert(cnt < elemsof(alg_info->esp));
-
- /* dont add duplicates */
- for (i = 0; i < cnt; i++)
- {
- if (esp_info[i].esp_ealg_id == ealg_id
- && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits)
- && esp_info[i].esp_aalg_id == aalg_id
- && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits))
- return;
- }
-
- esp_info[cnt].esp_ealg_id = ealg_id;
- esp_info[cnt].esp_ealg_keylen = ek_bits;
- esp_info[cnt].esp_aalg_id = aalg_id;
- esp_info[cnt].esp_aalg_keylen = ak_bits;
-
- /* sadb values */
- esp_info[cnt].encryptalg = ealg_id;
- esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id);
- alg_info->alg_info_cnt++;
-
- DBG(DBG_CRYPT,
- DBG_log("__alg_info_esp_add() ealg=%d aalg=%d cnt=%d"
- , ealg_id, aalg_id, alg_info->alg_info_cnt)
- )
-}
-
-/*
- * Add ESP alg info _with_ logic (policy):
- */
-static void
-alg_info_esp_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits)
-{
- /* Policy: default to 3DES */
- if (ealg_id == 0)
- ealg_id = ESP_3DES;
-
- if (ealg_id > 0)
- {
-#ifndef NO_PLUTO
- if (aalg_id > 0)
-#else
- /* Allow no auth for manual conns (from spi.c) */
- if (aalg_id >= 0)
-#endif
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- aalg_id, ak_bits);
- else
- {
- /* Policy: default to MD5 and SHA1 */
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- AUTH_ALGORITHM_HMAC_MD5, ak_bits);
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- AUTH_ALGORITHM_HMAC_SHA1, ak_bits);
- }
- }
-}
-
-#ifndef NO_PLUTO
-/**************************************
- *
- * IKE alg
- *
- *************************************/
-/*
- * Search oakley_enc_names for a match, eg:
- * "3des_cbc" <=> "OAKLEY_3DES_CBC"
- */
-static int
-ealg_getbyname_ike(const char *const str, int len)
-{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_enc_names,"OAKLEY_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_enc_names, "OAKLEY_", "_CBC", str, len);
- return ret;
-}
-
-/*
- * Search oakley_hash_names for a match, eg:
- * "md5" <=> "OAKLEY_MD5"
- */
-static int
-aalg_getbyname_ike(const char *const str, int len)
-{
- int ret;
- unsigned num;
-
- if (!str || !*str)
- return -1;
-
- /* interpret 'SHA1' as 'SHA' */
- if (strncasecmp("SHA1", str, len) == 0)
- return enum_search(&oakley_hash_names, "OAKLEY_SHA");
-
- ret = enum_search_prefix(&oakley_hash_names,"OAKLEY_", str, len);
- if (ret >= 0)
- return ret;
-
- sscanf(str, "id%d%n", &ret, &num);
- return (ret >=0 && num != strlen(str))? -1 : ret;
-}
-
-/*
- * Search oakley_group_names for a match, eg:
- * "modp1024" <=> "OAKLEY_GROUP_MODP1024"
- */
-static int
-modp_getbyname_ike(const char *const str, int len)
-{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);
- return ret;
-}
-
-static void
-__alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits, int modp_id)
-{
- struct ike_info *ike_info = alg_info->ike;
- unsigned cnt = alg_info->alg_info_cnt;
- unsigned i;
-
- /* check for overflows */
- passert(cnt < elemsof(alg_info->ike));
-
- /* dont add duplicates */
- for (i = 0;i < cnt; i++)
- {
- if (ike_info[i].ike_ealg == ealg_id
- && (!ek_bits || ike_info[i].ike_eklen == ek_bits)
- && ike_info[i].ike_halg == aalg_id
- && (!ak_bits || ike_info[i].ike_hklen == ak_bits)
- && ike_info[i].ike_modp==modp_id)
- return;
- }
-
- ike_info[cnt].ike_ealg = ealg_id;
- ike_info[cnt].ike_eklen = ek_bits;
- ike_info[cnt].ike_halg = aalg_id;
- ike_info[cnt].ike_hklen = ak_bits;
- ike_info[cnt].ike_modp = modp_id;
- alg_info->alg_info_cnt++;
-
- DBG(DBG_CRYPT,
- DBG_log("__alg_info_ike_add() ealg=%d aalg=%d modp_id=%d, cnt=%d"
- , ealg_id, aalg_id, modp_id
- , alg_info->alg_info_cnt)
- )
-}
-
-/*
- * Proposals will be built by looping over default_ike_groups array and
- * merging alg_info (ike_info) contents
- */
-
-static int default_ike_groups[] = {
- OAKLEY_GROUP_MODP1536,
- OAKLEY_GROUP_MODP1024
-};
-
-/*
- * Add IKE alg info _with_ logic (policy):
- */
-static void
-alg_info_ike_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits, int modp_id)
-{
- int i = 0;
- int n_groups = elemsof(default_ike_groups);
-
- /* if specified modp_id avoid loop over default_ike_groups */
- if (modp_id)
- {
- n_groups=0;
- goto in_loop;
- }
-
- for (; n_groups--; i++)
- {
- modp_id = default_ike_groups[i];
-in_loop:
- /* Policy: default to 3DES */
- if (ealg_id == 0)
- ealg_id = OAKLEY_3DES_CBC;
-
- if (ealg_id > 0)
- {
- if (aalg_id > 0)
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- aalg_id, ak_bits,
- modp_id);
- else
- {
- /* Policy: default to MD5 and SHA */
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- OAKLEY_MD5, ak_bits,
- modp_id);
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- OAKLEY_SHA, ak_bits,
- modp_id);
- }
- }
- }
-}
-#endif /* NO_PLUTO */
-
-/*
- * Creates a new alg_info by parsing passed string
- */
-enum parser_state_esp {
- ST_INI,
- ST_EA, /* encrypt algo */
- ST_EA_END,
- ST_EK, /* enc. key length */
- ST_EK_END,
- ST_AA, /* auth algo */
- ST_AA_END,
- ST_AK, /* auth. key length */
- ST_AK_END,
- ST_MODP, /* modp spec */
- ST_FLAG_STRICT,
- ST_END,
- ST_EOF,
- ST_ERR
-};
-
-static const char *parser_state_esp_names[] = {
- "ST_INI",
- "ST_EA",
- "ST_EA_END",
- "ST_EK",
- "ST_EK_END",
- "ST_AA",
- "ST_AA_END",
- "ST_AK",
- "ST_AK_END",
- "ST_MOPD",
- "ST_FLAG_STRICT",
- "ST_END",
- "ST_EOF",
- "ST_ERR"
-};
-
-static const char*
-parser_state_name_esp(enum parser_state_esp state)
-{
- return parser_state_esp_names[state];
-}
-
-/* XXX:jjo to implement different parser for ESP and IKE */
-struct parser_context {
- unsigned state, old_state;
- unsigned protoid;
- char ealg_buf[16];
- char aalg_buf[16];
- char modp_buf[16];
- int (*ealg_getbyname)(const char *const str, int len);
- int (*aalg_getbyname)(const char *const str, int len);
- int (*modp_getbyname)(const char *const str, int len);
- char *ealg_str;
- char *aalg_str;
- char *modp_str;
- int eklen;
- int aklen;
- int ch;
- const char *err;
-};
-
-static inline void
-parser_set_state(struct parser_context *p_ctx, enum parser_state_esp state)
-{
- if (state != p_ctx->state)
- {
- p_ctx->old_state = p_ctx->state;
- p_ctx->state = state;
- }
-}
-
-static int
-parser_machine(struct parser_context *p_ctx)
-{
- int ch = p_ctx->ch;
-
- /* special 'absolute' cases */
- p_ctx->err = "No error.";
-
- /* chars that end algo strings */
- switch (ch){
- case 0: /* end-of-string */
- case '!': /* flag as strict algo list */
- case ',': /* algo string separator */
- switch (p_ctx->state) {
- case ST_EA:
- case ST_EK:
- case ST_AA:
- case ST_AK:
- case ST_MODP:
- case ST_FLAG_STRICT:
- {
- enum parser_state_esp next_state = 0;
-
- switch (ch) {
- case 0:
- next_state = ST_EOF;
- break;
- case ',':
- next_state = ST_END;
- break;
- case '!':
- next_state = ST_FLAG_STRICT;
- break;
- }
- /* ch? parser_set_state(p_ctx, ST_END) : parser_set_state(p_ctx, ST_EOF) ; */
- parser_set_state(p_ctx, next_state);
- goto out;
- }
- default:
- p_ctx->err = "String ended with invalid char";
- goto err;
- }
- }
-re_eval:
- switch (p_ctx->state) {
- case ST_INI:
- if (isspace(ch))
- break;
- if (isalnum(ch))
- {
- *(p_ctx->ealg_str++) = ch;
- parser_set_state(p_ctx, ST_EA);
- break;
- }
- p_ctx->err = "No alphanum. char initially found";
- goto err;
- case ST_EA:
- if (isalpha(ch) || ch == '_')
- {
- *(p_ctx->ealg_str++) = ch;
- break;
- }
- if (isdigit(ch))
- {
- /* bravely switch to enc keylen */
- *(p_ctx->ealg_str) = 0;
- parser_set_state(p_ctx, ST_EK);
- goto re_eval;
- }
- if (ch == '-')
- {
- *(p_ctx->ealg_str) = 0;
- parser_set_state(p_ctx, ST_EA_END);
- break;
- }
- p_ctx->err = "No valid char found after enc alg string";
- goto err;
- case ST_EA_END:
- if (isdigit(ch))
- {
- /* bravely switch to enc keylen */
- parser_set_state(p_ctx, ST_EK);
- goto re_eval;
- }
- if (isalpha(ch))
- {
- parser_set_state(p_ctx, ST_AA);
- goto re_eval;
- }
- p_ctx->err = "No alphanum char found after enc alg separator";
- goto err;
- case ST_EK:
- if (ch == '-')
- {
- parser_set_state(p_ctx, ST_EK_END);
- break;
- }
- if (isdigit(ch))
- {
- p_ctx->eklen = p_ctx->eklen*10 + ch - '0';
- break;
- }
- p_ctx->err = "Non digit or valid separator found while reading enc keylen";
- goto err;
- case ST_EK_END:
- if (isalpha(ch))
- {
- parser_set_state(p_ctx, ST_AA);
- goto re_eval;
- }
- p_ctx->err = "Non alpha char found after enc keylen end separator";
- goto err;
- case ST_AA:
- if (ch == '-')
- {
- *(p_ctx->aalg_str++) = 0;
- parser_set_state(p_ctx, ST_AA_END);
- break;
- }
- if (isalnum(ch) || ch == '_')
- {
- *(p_ctx->aalg_str++) = ch;
- break;
- }
- p_ctx->err = "Non alphanum or valid separator found in auth string";
- goto err;
- case ST_AA_END:
- if (isdigit(ch))
- {
- parser_set_state(p_ctx, ST_AK);
- goto re_eval;
- }
- /* Only allow modpXXXX string if we have a modp_getbyname method */
- if ((p_ctx->modp_getbyname) && isalpha(ch))
- {
- parser_set_state(p_ctx, ST_MODP);
- goto re_eval;
- }
- p_ctx->err = "Non initial digit found for auth keylen";
- goto err;
- case ST_AK:
- if (ch=='-')
- {
- parser_set_state(p_ctx, ST_AK_END);
- break;
- }
- if (isdigit(ch))
- {
- p_ctx->aklen = p_ctx->aklen*10 + ch - '0';
- break;
- }
- p_ctx->err = "Non digit found for auth keylen";
- goto err;
- case ST_AK_END:
- /* Only allow modpXXXX string if we have a modp_getbyname method */
- if ((p_ctx->modp_getbyname) && isalpha(ch))
- {
- parser_set_state(p_ctx, ST_MODP);
- goto re_eval;
- }
- p_ctx->err = "Non alpha char found after auth keylen";
- goto err;
- case ST_MODP:
- if (isalnum(ch))
- {
- *(p_ctx->modp_str++) = ch;
- break;
- }
- p_ctx->err = "Non alphanum char found after in modp string";
- goto err;
- case ST_FLAG_STRICT:
- if (ch == 0)
- parser_set_state(p_ctx, ST_END);
- p_ctx->err = "Flags character(s) must be at end of whole string";
- goto err;
-
- /* XXX */
- case ST_END:
- case ST_EOF:
- case ST_ERR:
- break;
- /* XXX */
- }
-out:
- return p_ctx->state;
-err:
- parser_set_state(p_ctx, ST_ERR);
- return ST_ERR;
-}
-
-/*
- * Must be called for each "new" char, with new
- * character in ctx.ch
- */
-static void
-parser_init(struct parser_context *p_ctx, unsigned protoid)
-{
- memset(p_ctx, 0, sizeof (*p_ctx));
- p_ctx->protoid = protoid; /* XXX: jjo */
- p_ctx->protoid = PROTO_IPSEC_ESP;
- p_ctx->ealg_str = p_ctx->ealg_buf;
- p_ctx->aalg_str = p_ctx->aalg_buf;
- p_ctx->modp_str = p_ctx->modp_buf;
- p_ctx->state = ST_INI;
-
- switch (protoid) {
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- p_ctx->ealg_getbyname = ealg_getbyname_ike;
- p_ctx->aalg_getbyname = aalg_getbyname_ike;
- p_ctx->modp_getbyname = modp_getbyname_ike;
- break;
-#endif
- case PROTO_IPSEC_ESP:
- p_ctx->ealg_getbyname = ealg_getbyname_esp;
- p_ctx->aalg_getbyname = aalg_getbyname_esp;
- break;
- }
-}
-
-static int
-parser_alg_info_add(struct parser_context *p_ctx, struct alg_info *alg_info)
-{
- int ealg_id = 0;
- int aalg_id = 0;
- int modp_id = 0;
-#ifndef NO_PLUTO
- const struct oakley_group_desc *gd;
-#endif
-
- if (*p_ctx->ealg_buf)
- {
- ealg_id = p_ctx->ealg_getbyname(p_ctx->ealg_buf, strlen(p_ctx->ealg_buf));
- if (ealg_id == ESP_MAGIC_ID)
- {
- ealg_id = p_ctx->eklen;
- p_ctx->eklen = 0;
- }
- if (ealg_id < 0)
- {
- p_ctx->err = "enc_alg not found";
- return -1;
- }
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() ealg_getbyname(\"%s\")=%d"
- , p_ctx->ealg_buf
- , ealg_id)
- )
- }
- if (*p_ctx->aalg_buf)
- {
- aalg_id = p_ctx->aalg_getbyname(p_ctx->aalg_buf, strlen(p_ctx->aalg_buf));
- if (aalg_id < 0)
- {
- p_ctx->err = "hash_alg not found";
- return -1;
- }
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() aalg_getbyname(\"%s\")=%d"
- , p_ctx->aalg_buf
- , aalg_id)
- )
- }
- if (p_ctx->modp_getbyname && *p_ctx->modp_buf)
- {
- modp_id = p_ctx->modp_getbyname(p_ctx->modp_buf, strlen(p_ctx->modp_buf));
- if (modp_id < 0)
- {
- p_ctx->err = "modp group not found";
- return -1;
- }
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() modp_getbyname(\"%s\")=%d"
- , p_ctx->modp_buf
- , modp_id)
- )
- }
- switch (alg_info->alg_info_protoid) {
- case PROTO_IPSEC_ESP:
- alg_info_esp_add(alg_info,
- ealg_id, p_ctx->eklen,
- aalg_id, p_ctx->aklen);
- break;
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- if (modp_id && !(gd = lookup_group(modp_id)))
- {
- p_ctx->err = "found modp group id, but not supported";
- return -1;
- }
- alg_info_ike_add(alg_info,
- ealg_id, p_ctx->eklen,
- aalg_id, p_ctx->aklen,
- modp_id);
- break;
-#endif
- default:
- return -1;
- }
- return 0;
-}
-
-static int
-alg_info_parse_str (struct alg_info *alg_info, const char *alg_str, const char **err_p)
-{
- struct parser_context ctx;
- int ret;
- const char *ptr;
- static char err_buf[256];
-
- *err_buf = 0;
- parser_init(&ctx, alg_info->alg_info_protoid);
- if (err_p)
- *err_p = NULL;
-
- /* use default if nul esp string */
- if (!*alg_str)
- {
- switch (alg_info->alg_info_protoid) {
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- alg_info_ike_add(alg_info, 0, 0, 0, 0, 0);
- return 0;
-#endif
- case PROTO_IPSEC_ESP:
- alg_info_esp_add(alg_info, 0, 0, 0, 0);
- return 0;
- default:
- /* IMPOSSIBLE */
- passert(alg_info->alg_info_protoid);
- }
- }
-
- for (ret = 0, ptr = alg_str; ret < ST_EOF;)
- {
- ctx.ch = *ptr++;
- ret = parser_machine(&ctx);
-
- switch (ret) {
- case ST_FLAG_STRICT:
- alg_info->alg_info_flags |= ALG_INFO_F_STRICT;
- break;
- case ST_END:
- case ST_EOF:
- DBG(DBG_CRYPT,
- DBG_log("alg_info_parse_str() ealg_buf=%s aalg_buf=%s"
- "eklen=%d aklen=%d",
- ctx.ealg_buf, ctx.aalg_buf,
- ctx.eklen, ctx.aklen)
- )
- if (parser_alg_info_add(&ctx, alg_info) < 0)
- {
- snprintf(err_buf, sizeof(err_buf),
- "%s, enc_alg=\"%s\", auth_alg=\"%s\", modp=\"%s\"",
- ctx.err,
- ctx.ealg_buf,
- ctx.aalg_buf,
- ctx.modp_buf);
- goto err;
- }
- /* zero out for next run (ST_END) */
- parser_init(&ctx, alg_info->alg_info_protoid);
- break;
- case ST_ERR:
- snprintf(err_buf, sizeof(err_buf),
- "%s, just after \"%.*s\" (old_state=%s)",
- ctx.err,
- (int)(ptr-alg_str-1), alg_str ,
- parser_state_name_esp(ctx.old_state));
- goto err;
- default:
- if (!ctx.ch)
- break;
- }
- }
- return 0;
-err:
- if (err_p)
- *err_p=err_buf;
- return -1;
-}
-
-struct alg_info_esp *
-alg_info_esp_create_from_str (const char *alg_str, const char **err_p)
-{
- struct alg_info_esp *alg_info_esp;
- char esp_buf[256];
- static char err_buf[256];
- char *pfs_name;
- int ret = 0;
- /*
- * alg_info storage should be sized dynamically
- * but this may require 2passes to know
- * transform count in advance.
- */
- alg_info_esp = alloc_thing (struct alg_info_esp, "alg_info_esp");
- if (!alg_info_esp)
- goto out;
-
- pfs_name=index (alg_str, ';');
- if (pfs_name)
- {
- memcpy(esp_buf, alg_str, pfs_name-alg_str);
- esp_buf[pfs_name-alg_str] = 0;
- alg_str = esp_buf;
- pfs_name++;
-
- /* if pfs strings AND first char is not '0' */
- if (*pfs_name && pfs_name[0] != '0')
- {
- ret = modp_getbyname_esp(pfs_name, strlen(pfs_name));
- if (ret < 0)
- {
- /* Bomb if pfsgroup not found */
- DBG(DBG_CRYPT,
- DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found"
- , pfs_name)
- )
- if (*err_p)
- {
- snprintf(err_buf, sizeof(err_buf),
- "pfsgroup \"%s\" not found",
- pfs_name);
-
- *err_p = err_buf;
- }
- goto out;
- }
- alg_info_esp->esp_pfsgroup = ret;
- }
- }
- else
- alg_info_esp->esp_pfsgroup = 0;
-
- alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP;
- ret = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str, err_p) ;
-out:
- if (ret < 0)
- {
- pfreeany(alg_info_esp);
- alg_info_esp = NULL;
- }
- return alg_info_esp;
-}
-
-#ifndef NO_PLUTO
-struct alg_info_ike *
-alg_info_ike_create_from_str (const char *alg_str, const char **err_p)
-{
- struct alg_info_ike *alg_info_ike;
- /*
- * alg_info storage should be sized dynamically
- * but this may require 2passes to know
- * transform count in advance.
- */
- alg_info_ike = alloc_thing (struct alg_info_ike, "alg_info_ike");
- alg_info_ike->alg_info_protoid = PROTO_ISAKMP;
-
- if (alg_info_parse_str((struct alg_info *)alg_info_ike,
- alg_str, err_p) < 0)
- {
- pfreeany(alg_info_ike);
- return NULL;
- }
- return alg_info_ike;
-}
-#endif
-
-/*
- * alg_info struct can be shared by
- * several connections instances,
- * handle free() with ref_cnts
- */
-void
-alg_info_addref(struct alg_info *alg_info)
-{
- if (alg_info != NULL)
- {
- alg_info->ref_cnt++;
- DBG(DBG_CRYPT,
- DBG_log("alg_info_addref() alg_info->ref_cnt=%d"
- , alg_info->ref_cnt)
- )
- }
-}
-
-void
-alg_info_delref(struct alg_info **alg_info_p)
-{
- struct alg_info *alg_info = *alg_info_p;
-
- if (alg_info != NULL)
- {
- passert(alg_info->ref_cnt != 0);
- alg_info->ref_cnt--;
- DBG(DBG_CRYPT,
- DBG_log("alg_info_delref() alg_info->ref_cnt=%d"
- , alg_info->ref_cnt)
- )
- if (alg_info->ref_cnt == 0)
- {
- DBG(DBG_CRYPT,
- DBG_log("alg_info_delref() freeing alg_info")
- )
- alg_info_free(alg_info);
- }
- *alg_info_p = NULL;
- }
-}
-
-/* snprint already parsed transform list (alg_info) */
-int
-alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info)
-{
- char *ptr = buf;
- int np = 0;
- struct esp_info *esp_info;
-#ifndef NO_PLUTO
- struct ike_info *ike_info;
-#endif
- int cnt;
-
- switch (alg_info->alg_info_protoid) {
- case PROTO_IPSEC_ESP:
- {
- struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info;
-
- ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt)
- {
- np = snprintf(ptr, buflen, "%d_%03d-%d, "
- , esp_info->esp_ealg_id
- , (int)esp_info->esp_ealg_keylen
- , esp_info->esp_aalg_id);
- ptr += np;
- buflen -= np;
- if (buflen < 0)
- goto out;
- }
- if (alg_info_esp->esp_pfsgroup)
- {
- np = snprintf(ptr, buflen, "; pfsgroup=%d; "
- , alg_info_esp->esp_pfsgroup);
- ptr += np;
- buflen -= np;
- if (buflen < 0)
- goto out;
- }
- break;
- }
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt)
- {
- np = snprintf(ptr, buflen, "%d_%03d-%d-%d, "
- , ike_info->ike_ealg
- , (int)ike_info->ike_eklen
- , ike_info->ike_halg
- , ike_info->ike_modp);
- ptr += np;
- buflen -= np;
- if (buflen < 0)
- goto out;
- }
- break;
-#endif
- default:
- np = snprintf(buf, buflen, "INVALID protoid=%d\n"
- , alg_info->alg_info_protoid);
- ptr += np;
- buflen -= np;
- goto out;
- }
-
- np = snprintf(ptr, buflen, "%s"
- , alg_info->alg_info_flags & ALG_INFO_F_STRICT?
- "strict":"");
- ptr += np;
- buflen -= np;
-out:
- if (buflen < 0)
- {
- loglog(RC_LOG_SERIOUS
- , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d"
- , buflen);
- }
-
- return ptr - buf;
-}
-
-#ifndef NO_PLUTO
-int
-alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info)
-{
- char *ptr = buf;
-
- int cnt = alg_info->alg_info_cnt;
- struct esp_info *esp_info = alg_info->esp;
-
- while (cnt--)
- {
- if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL)
- && kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL))
- {
- u_int eklen = (esp_info->esp_ealg_keylen)
- ? esp_info->esp_ealg_keylen
- : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id)
- * BITS_PER_BYTE;
-
- u_int aklen = esp_info->esp_aalg_keylen
- ? esp_info->esp_aalg_keylen
- : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id)
- * BITS_PER_BYTE;
-
- int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ",
- esp_info->esp_ealg_id, eklen,
- esp_info->esp_aalg_id, aklen);
- ptr += ret;
- buflen -= ret;
- if (buflen < 0)
- break;
- }
- esp_info++;
- }
- return ptr - buf;
-}
-
-int
-alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info)
-{
- char *ptr = buf;
-
- int cnt = alg_info->alg_info_cnt;
- struct ike_info *ike_info = alg_info->ike;
-
- while (cnt--)
- {
- struct encrypt_desc *enc_desc = ike_alg_get_encrypter(ike_info->ike_ealg);
- struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg);
-
- if (enc_desc != NULL && hash_desc != NULL
- && lookup_group(ike_info->ike_modp))
- {
-
- u_int eklen = (ike_info->ike_eklen)
- ? ike_info->ike_eklen
- : enc_desc->keydeflen;
-
- u_int aklen = (ike_info->ike_hklen)
- ? ike_info->ike_hklen
- : hash_desc->hash_digest_size * BITS_PER_BYTE;
-
- int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ",
- ike_info->ike_ealg, eklen,
- ike_info->ike_halg, aklen,
- ike_info->ike_modp);
- ptr += ret;
- buflen -= ret;
- if (buflen < 0)
- break;
- }
- ike_info++;
- }
- return ptr - buf;
-}
-#endif /* NO_PLUTO */
diff --git a/programs/pluto/alg_info.h b/programs/pluto/alg_info.h
deleted file mode 100644
index cd2011dcc..000000000
--- a/programs/pluto/alg_info.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Algorithm info parsing and creation functions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: alg_info.h,v 1.4 2004/09/29 22:39:44 as Exp $
- */
-
-#ifndef ALG_INFO_H
-#define ALG_INFO_H
-
-struct esp_info {
- u_int8_t transid; /* ESP transform */
- u_int16_t auth; /* AUTH */
- size_t enckeylen; /* keylength for ESP transform */
- size_t authkeylen; /* keylength for AUTH */
- u_int8_t encryptalg; /* normally encryptalg=transid */
- u_int8_t authalg; /* normally authalg=auth+1 */
-};
-
-struct ike_info {
- u_int16_t ike_ealg; /* high 16 bit nums for reserved */
- u_int8_t ike_halg;
- size_t ike_eklen;
- size_t ike_hklen;
- u_int16_t ike_modp;
-};
-
-#define ALG_INFO_COMMON \
- int alg_info_cnt; \
- int ref_cnt; \
- unsigned alg_info_flags; \
- unsigned alg_info_protoid
-
-struct alg_info {
- ALG_INFO_COMMON;
-};
-
-struct alg_info_esp {
- ALG_INFO_COMMON;
- struct esp_info esp[64];
- int esp_pfsgroup;
-};
-
-struct alg_info_ike {
- ALG_INFO_COMMON;
- struct ike_info ike[64];
-};
-#define esp_ealg_id transid
-#define esp_aalg_id auth
-#define esp_ealg_keylen enckeylen /* bits */
-#define esp_aalg_keylen authkeylen /* bits */
-
-/* alg_info_flags bits */
-#define ALG_INFO_F_STRICT 0x01
-
-extern int alg_info_esp_aa2sadb(int auth);
-extern int alg_info_esp_sadb2aa(int sadb_aalg);
-extern void alg_info_free(struct alg_info *alg_info);
-extern void alg_info_addref(struct alg_info *alg_info);
-extern void alg_info_delref(struct alg_info **alg_info);
-extern struct alg_info_esp* alg_info_esp_create_from_str(const char *alg_str
- , const char **err_p);
-extern struct alg_info_ike* alg_info_ike_create_from_str(const char *alg_str
- , const char **err_p);
-extern int alg_info_parse(const char *str);
-extern int alg_info_snprint(char *buf, int buflen
- , struct alg_info *alg_info);
-extern int alg_info_snprint_esp(char *buf, int buflen
- , struct alg_info_esp *alg_info);
-extern int alg_info_snprint_ike(char *buf, int buflen
- , struct alg_info_ike *alg_info);
-#define ALG_INFO_ESP_FOREACH(ai, ai_esp, i) \
- for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++)
-#define ALG_INFO_IKE_FOREACH(ai, ai_ike, i) \
- for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++)
-#endif /* ALG_INFO_H */
diff --git a/programs/pluto/asn1.c b/programs/pluto/asn1.c
deleted file mode 100644
index 0663bc490..000000000
--- a/programs/pluto/asn1.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: asn1.c,v 1.16 2006/01/04 21:00:43 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "asn1.h"
-#include "oid.h"
-#include "log.h"
-
-/* some common prefabricated ASN.1 constants */
-
-static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
-static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
-static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
-
-const chunk_t ASN1_INTEGER_0 = strchunk(ASN1_INTEGER_0_str);
-const chunk_t ASN1_INTEGER_1 = strchunk(ASN1_INTEGER_1_str);
-const chunk_t ASN1_INTEGER_2 = strchunk(ASN1_INTEGER_2_str);
-
-/* some popular algorithmIdentifiers */
-
-static u_char ASN1_md5_id_str[] = {
- 0x30, 0x0C,
- 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
- 0x05, 0x00
-};
-
-static u_char ASN1_sha1_id_str[] = {
- 0x30, 0x09,
- 0x06, 0x05, 0x2B, 0x0E,0x03, 0x02, 0x1A,
- 0x05, 0x00
-};
-
-static u_char ASN1_md5WithRSA_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04,
- 0x05, 0x00
-};
-
-static u_char ASN1_sha1WithRSA_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05,
- 0x05, 0x00
-};
-
-static u_char ASN1_rsaEncryption_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
- 0x05, 0x00
-};
-
-const chunk_t ASN1_md5_id = strchunk(ASN1_md5_id_str);
-const chunk_t ASN1_sha1_id = strchunk(ASN1_sha1_id_str);
-const chunk_t ASN1_rsaEncryption_id = strchunk(ASN1_rsaEncryption_id_str);
-const chunk_t ASN1_md5WithRSA_id = strchunk(ASN1_md5WithRSA_id_str);
-const chunk_t ASN1_sha1WithRSA_id = strchunk(ASN1_sha1WithRSA_id_str);
-
-/* ASN.1 definiton of an algorithmIdentifier */
-
-static const asn1Object_t algorithmIdentifierObjects[] = {
- { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "parameters", ASN1_EOC, ASN1_RAW } /* 2 */
-};
-
-#define ALGORITHM_ID_ALG 1
-#define ALGORITHM_ID_PARAMETERS 2
-#define ALGORITHM_ID_ROOF 3
-
-/*
- * return the ASN.1 encoded algorithm identifier
- */
-chunk_t
-asn1_algorithmIdentifier(int oid)
-{
- switch (oid)
- {
- case OID_RSA_ENCRYPTION:
- return ASN1_rsaEncryption_id;
- case OID_MD5_WITH_RSA:
- return ASN1_md5WithRSA_id;
- case OID_SHA1_WITH_RSA:
- return ASN1_sha1WithRSA_id;
- case OID_MD5:
- return ASN1_md5_id;
- case OID_SHA1:
- return ASN1_sha1_id;
- default:
- return empty_chunk;
- }
-}
-
-/* If the oid is listed in the oid_names table then the corresponding
- * position in the oid_names table is returned otherwise -1 is returned
- */
-int
-known_oid(chunk_t object)
-{
- int oid = 0;
-
- while (object.len)
- {
- if (oid_names[oid].octet == *object.ptr)
- {
- if (--object.len == 0 || oid_names[oid].down == 0)
- {
- return oid; /* found terminal symbol */
- }
- else
- {
- object.ptr++; oid++; /* advance to next hex octet */
- }
- }
- else
- {
- if (oid_names[oid].next)
- oid = oid_names[oid].next;
- else
- return OID_UNKNOWN;
- }
- }
- return -1;
-}
-
-/*
- * Decodes the length in bytes of an ASN.1 object
- */
-u_int
-asn1_length(chunk_t *blob)
-{
- u_char n;
- size_t len;
-
- /* advance from tag field on to length field */
- blob->ptr++;
- blob->len--;
-
- /* read first octet of length field */
- n = *blob->ptr++;
- blob->len--;
-
- if ((n & 0x80) == 0) /* single length octet */
- return n;
-
- /* composite length, determine number of length octets */
- n &= 0x7f;
-
- if (n > blob->len)
- {
- DBG(DBG_PARSING,
- DBG_log("number of length octets is larger than ASN.1 object")
- )
- return ASN1_INVALID_LENGTH;
- }
-
- if (n > sizeof(len))
- {
- DBG(DBG_PARSING,
- DBG_log("number of length octets is larger than limit of %d octets"
- , (int)sizeof(len))
- )
- return ASN1_INVALID_LENGTH;
- }
-
- len = 0;
-
- while (n-- > 0)
- {
- len = 256*len + *blob->ptr++;
- blob->len--;
- }
- return len;
-}
-
-/*
- * codes ASN.1 lengths up to a size of 16'777'215 bytes
- */
-void
-code_asn1_length(size_t length, chunk_t *code)
-{
- if (length < 128)
- {
- code->ptr[0] = length;
- code->len = 1;
- }
- else if (length < 256)
- {
- code->ptr[0] = 0x81;
- code->ptr[1] = (u_char) length;
- code->len = 2;
- }
- else if (length < 65536)
- {
- code->ptr[0] = 0x82;
- code->ptr[1] = length >> 8;
- code->ptr[2] = length & 0x00ff;
- code->len = 3;
- }
- else
- {
- code->ptr[0] = 0x83;
- code->ptr[1] = length >> 16;
- code->ptr[2] = (length >> 8) & 0x00ff;
- code->ptr[3] = length & 0x0000ff;
- code->len = 4;
- }
-}
-
-/*
- * build an empty asn.1 object with tag and length fields already filled in
- */
-u_char*
-build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
-{
- u_char length_buf[4];
- chunk_t length = { length_buf, 0 };
- u_char *pos;
-
- /* code the asn.1 length field */
- code_asn1_length(datalen, &length);
-
- /* allocate memory for the asn.1 TLV object */
- object->len = 1 + length.len + datalen;
- object->ptr = alloc_bytes(object->len, "asn1 object");
-
- /* set position pointer at the start of the object */
- pos = object->ptr;
-
- /* copy the asn.1 tag field and advance the pointer */
- *pos++ = type;
-
- /* copy the asn.1 length field and advance the pointer */
- chunkcpy(pos, length);
-
- return pos;
-}
-
-/*
- * build a simple ASN.1 object
- */
-chunk_t
-asn1_simple_object(asn1_t tag, chunk_t content)
-{
- chunk_t object;
-
- u_char *pos = build_asn1_object(&object, tag, content.len);
- chunkcpy(pos, content);
-
- return object;
-}
-
-/* Build an ASN.1 object from a variable number of individual chunks.
- * Depending on the mode, chunks either are moved ('m') or copied ('c').
- */
-chunk_t
-asn1_wrap(asn1_t type, const char *mode, ...)
-{
- chunk_t construct;
- va_list chunks;
- u_char *pos;
- int i;
- int count = strlen(mode);
-
- /* sum up lengths of individual chunks */
- va_start(chunks, mode);
- construct.len = 0;
- for (i = 0; i < count; i++)
- {
- chunk_t ch = va_arg(chunks, chunk_t);
- construct.len += ch.len;
- }
- va_end(chunks);
-
- /* allocate needed memory for construct */
- pos = build_asn1_object(&construct, type, construct.len);
-
- /* copy or move the chunks */
- va_start(chunks, mode);
- for (i = 0; i < count; i++)
- {
- chunk_t ch = va_arg(chunks, chunk_t);
-
- switch (*mode++)
- {
- case 'm':
- mv_chunk(&pos, ch);
- break;
- case 'c':
- default:
- chunkcpy(pos, ch);
- }
- }
- va_end(chunks);
-
- return construct;
-}
-
-/*
- * convert a MP integer into a DER coded ASN.1 object
- */
-chunk_t
-asn1_integer_from_mpz(const mpz_t value)
-{
- size_t bits = mpz_sizeinbase(value, 2); /* size in bits */
- size_t size = 1 + bits / BITS_PER_BYTE; /* size in bytes */
- chunk_t n = mpz_to_n(value, size);
-
- return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
-/*
- * determines if a character string is of type ASN.1 printableString
- */
-bool
-is_printablestring(chunk_t str)
-{
- const char printablestring_charset[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
- u_int i;
-
- for (i = 0; i < str.len; i++)
- {
- if (strchr(printablestring_charset, str.ptr[i]) == NULL)
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
- */
-time_t
-asn1totime(const chunk_t *utctime, asn1_t type)
-{
- struct tm t;
- time_t tz_offset;
- u_char *eot = NULL;
-
- if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
- {
- tz_offset = 0; /* Zulu time with a zero time zone offset */
- }
- else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL)
- {
- int tz_hour, tz_min;
-
- sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
- tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */
- }
- else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
- {
- int tz_hour, tz_min;
-
- sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min);
- tz_offset = -3600*tz_hour - 60*tz_min; /* negative time zone offset */
- }
- else
- {
- return 0; /* error in time format */
- }
-
- {
- const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
- "%4d%2d%2d%2d%2d";
-
- sscanf(utctime->ptr, format, &t.tm_year, &t.tm_mon, &t.tm_mday,
- &t.tm_hour, &t.tm_min);
- }
-
- /* is there a seconds field? */
- if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
- {
- sscanf(eot-2, "%2d", &t.tm_sec);
- }
- else
- {
- t.tm_sec = 0;
- }
-
- /* representation of year */
- if (t.tm_year >= 1900)
- {
- t.tm_year -= 1900;
- }
- else if (t.tm_year >= 100)
- {
- return 0;
- }
- else if (t.tm_year < 50)
- {
- t.tm_year += 100;
- }
-
- /* representation of month 0..11*/
- t.tm_mon--;
-
- /* set daylight saving time to off */
- t.tm_isdst = 0;
-
- /* compensate timezone */
-
- return mktime(&t) - timezone - tz_offset;
-}
-
-/*
- * convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
- */
-chunk_t
-timetoasn1(const time_t *time, asn1_t type)
-{
- int offset;
- const char *format;
- char buf[TIMETOA_BUF];
- chunk_t formatted_time;
- struct tm *t = gmtime(time);
-
- if (type == ASN1_GENERALIZEDTIME)
- {
- format = "%04d%02d%02d%02d%02d%02dZ";
- offset = 1900;
- }
- else /* ASN1_UTCTIME */
- {
- format = "%02d%02d%02d%02d%02d%02dZ";
- offset = (t->tm_year < 100)? 0 : -100;
- }
- sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday
- , t->tm_hour, t->tm_min, t->tm_sec);
- formatted_time.ptr = buf;
- formatted_time.len = strlen(buf);
- return asn1_simple_object(type, formatted_time);
-}
-
-
-/*
- * Initializes the internal context of the ASN.1 parser
- */
-void
-asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0,
- bool implicit, u_int cond)
-{
- ctx->blobs[0] = blob;
- ctx->level0 = level0;
- ctx->implicit = implicit;
- ctx->cond = cond;
- memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
-}
-
-/*
- * print the value of an ASN.1 simple object
- */
-static void
-debug_asn1_simple_object(chunk_t object, asn1_t type, u_int cond)
-{
- int oid;
-
- switch (type)
- {
- case ASN1_OID:
- oid = known_oid(object);
- if (oid != OID_UNKNOWN)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%s'",oid_names[oid].name);
- )
- return;
- }
- break;
- case ASN1_UTF8STRING:
- case ASN1_IA5STRING:
- case ASN1_PRINTABLESTRING:
- case ASN1_T61STRING:
- case ASN1_VISIBLESTRING:
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", (int)object.len, object.ptr);
- )
- return;
- case ASN1_UTCTIME:
- case ASN1_GENERALIZEDTIME:
- DBG(DBG_PARSING,
- time_t time = asn1totime(&object, type);
- DBG_log(" '%s'", timetoa(&time, TRUE));
- )
- return;
- default:
- break;
- }
- DBG(cond,
- DBG_dump_chunk("", object);
- )
-}
-
-/*
- * Parses and extracts the next ASN.1 object
- */
-bool
-extract_object(asn1Object_t const *objects,
- u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
-{
- asn1Object_t obj = objects[*objectID];
- chunk_t *blob;
- chunk_t *blob1;
- u_char *start_ptr;
-
- *object = empty_chunk;
-
- if (obj.flags & ASN1_END) /* end of loop or option found */
- {
- if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
- {
- *objectID = ctx->loopAddr[obj.level]; /* another iteration */
- obj = objects[*objectID];
- }
- else
- {
- ctx->loopAddr[obj.level] = 0; /* exit loop or option*/
- return TRUE;
- }
- }
-
- *level = ctx->level0 + obj.level;
- blob = ctx->blobs + obj.level;
- blob1 = blob + 1;
- start_ptr = blob->ptr;
-
- /* handle ASN.1 defaults values */
-
- if ((obj.flags & ASN1_DEF)
- && (blob->len == 0 || *start_ptr != obj.type) )
- {
- /* field is missing */
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", *level, obj.name);
- )
- if (obj.type & ASN1_CONSTRUCTED)
- {
- (*objectID)++ ; /* skip context-specific tag */
- }
- return TRUE;
- }
-
- /* handle ASN.1 options */
-
- if ((obj.flags & ASN1_OPT)
- && (blob->len == 0 || *start_ptr != obj.type))
- {
- /* advance to end of missing option field */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
-
- /* an ASN.1 object must possess at least a tag and length field */
-
- if (blob->len < 2)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
- *level, obj.name);
- )
- return FALSE;
- }
-
- blob1->len = asn1_length(blob);
-
- if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
- *level, obj.name);
- )
- return FALSE;
- }
-
- blob1->ptr = blob->ptr;
- blob->ptr += blob1->len;
- blob->len -= blob1->len;
-
- /* return raw ASN.1 object without prior type checking */
-
- if (obj.flags & ASN1_RAW)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", *level, obj.name);
- )
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- return TRUE;
- }
-
- if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
- *level, obj.name, obj.type, *start_ptr);
- DBG_dump("", start_ptr, (u_int)(blob->ptr - start_ptr));
- )
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", ctx->level0+obj.level, obj.name);
- )
-
- /* In case of "SEQUENCE OF" or "SET OF" start a loop */
-
- if (obj.flags & ASN1_LOOP)
- {
- if (blob1->len > 0)
- {
- /* at least one item, start the loop */
- ctx->loopAddr[obj.level] = *objectID + 1;
- }
- else
- {
- /* no items, advance directly to end of loop */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
- }
-
- if (obj.flags & ASN1_OBJ)
- {
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- DBG(ctx->cond,
- DBG_dump_chunk("", *object);
- )
- }
- else if (obj.flags & ASN1_BODY)
- {
- *object = *blob1;
- debug_asn1_simple_object(*object, obj.type, ctx->cond);
- }
- return TRUE;
-}
-
-/*
- * parse an ASN.1 simple type
- */
-bool
-parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
-, const char* name)
-{
- size_t len;
-
- /* an ASN.1 object must possess at least a tag and length field */
- if (object->len < 2)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
- level, name);
- )
- return FALSE;
- }
-
- if (*object->ptr != type)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
- level, name, type, *object->ptr);
- )
- return FALSE;
- }
-
- len = asn1_length(object);
-
- if (len == ASN1_INVALID_LENGTH || object->len < len)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
- level, name);
- )
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", level, name);
- )
- debug_asn1_simple_object(*object, type, DBG_RAW);
- return TRUE;
-}
-
-/*
- * extracts an algorithmIdentifier
- */
-int
-parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int alg = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < ALGORITHM_ID_ROOF)
- {
- if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
- return OID_UNKNOWN;
-
- switch (objectID)
- {
- case ALGORITHM_ID_ALG:
- alg = known_oid(object);
- break;
- case ALGORITHM_ID_PARAMETERS:
- if (parameters != NULL)
- *parameters = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- return alg;
- }
-
-/*
- * tests if a blob contains a valid ASN.1 set or sequence
- */
-bool
-is_asn1(chunk_t blob)
-{
- u_int len;
- u_char tag = *blob.ptr;
-
- if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
- {
- DBG(DBG_PARSING,
- DBG_log(" file content is not binary ASN.1");
- )
- return FALSE;
- }
- len = asn1_length(&blob);
- if (len != blob.len)
- {
- DBG(DBG_PARSING,
- DBG_log(" file size does not match ASN.1 coded length");
- )
- return FALSE;
- }
- return TRUE;
-}
diff --git a/programs/pluto/asn1.h b/programs/pluto/asn1.h
deleted file mode 100644
index 2a3fb3e9e..000000000
--- a/programs/pluto/asn1.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: asn1.h,v 1.14 2005/12/06 22:50:10 as Exp $
- */
-
-#ifndef _ASN1_H
-#define _ASN1_H
-
-#include <stdarg.h>
-#include <gmp.h>
-
-#include "defs.h"
-
-/* Defines some primitive ASN1 types */
-
-typedef enum {
- ASN1_EOC = 0x00,
- ASN1_BOOLEAN = 0x01,
- ASN1_INTEGER = 0x02,
- ASN1_BIT_STRING = 0x03,
- ASN1_OCTET_STRING = 0x04,
- ASN1_NULL = 0x05,
- ASN1_OID = 0x06,
- ASN1_ENUMERATED = 0x0A,
- ASN1_UTF8STRING = 0x0C,
- ASN1_NUMERICSTRING = 0x12,
- ASN1_PRINTABLESTRING = 0x13,
- ASN1_T61STRING = 0x14,
- ASN1_VIDEOTEXSTRING = 0x15,
- ASN1_IA5STRING = 0x16,
- ASN1_UTCTIME = 0x17,
- ASN1_GENERALIZEDTIME = 0x18,
- ASN1_GRAPHICSTRING = 0x19,
- ASN1_VISIBLESTRING = 0x1A,
- ASN1_GENERALSTRING = 0x1B,
- ASN1_UNIVERSALSTRING = 0x1C,
- ASN1_BMPSTRING = 0x1E,
-
- ASN1_CONSTRUCTED = 0x20,
-
- ASN1_SEQUENCE = 0x30,
-
- ASN1_SET = 0x31,
-
- ASN1_CONTEXT_S_0 = 0x80,
- ASN1_CONTEXT_S_1 = 0x81,
- ASN1_CONTEXT_S_2 = 0x82,
- ASN1_CONTEXT_S_3 = 0x83,
- ASN1_CONTEXT_S_4 = 0x84,
- ASN1_CONTEXT_S_5 = 0x85,
- ASN1_CONTEXT_S_6 = 0x86,
- ASN1_CONTEXT_S_7 = 0x87,
- ASN1_CONTEXT_S_8 = 0x88,
-
- ASN1_CONTEXT_C_0 = 0xA0,
- ASN1_CONTEXT_C_1 = 0xA1,
- ASN1_CONTEXT_C_2 = 0xA2,
- ASN1_CONTEXT_C_3 = 0xA3,
- ASN1_CONTEXT_C_4 = 0xA4,
- ASN1_CONTEXT_C_5 = 0xA5
-} asn1_t;
-
-/* Definition of ASN1 flags */
-
-#define ASN1_NONE 0x00
-#define ASN1_DEF 0x01
-#define ASN1_OPT 0x02
-#define ASN1_LOOP 0x04
-#define ASN1_END 0x08
-#define ASN1_OBJ 0x10
-#define ASN1_BODY 0x20
-#define ASN1_RAW 0x40
-
-#define ASN1_INVALID_LENGTH 0xffffffff
-
-/* definition of an ASN.1 object */
-
-typedef struct {
- u_int level;
- const u_char *name;
- asn1_t type;
- u_char flags;
-} asn1Object_t;
-
-#define ASN1_MAX_LEVEL 10
-
-typedef struct {
- bool implicit;
- u_int cond;
- u_int level0;
- u_int loopAddr[ASN1_MAX_LEVEL+1];
- chunk_t blobs[ASN1_MAX_LEVEL+2];
-} asn1_ctx_t;
-
-/* some common prefabricated ASN.1 constants */
-
-extern const chunk_t ASN1_INTEGER_0;
-extern const chunk_t ASN1_INTEGER_1;
-extern const chunk_t ASN1_INTEGER_2;
-
-/* some popular algorithmIdentifiers */
-extern const chunk_t ASN1_md5_id;
-extern const chunk_t ASN1_sha1_id;
-extern const chunk_t ASN1_rsaEncryption_id;
-extern const chunk_t ASN1_md5WithRSA_id;
-extern const chunk_t ASN1_sha1WithRSA_id;
-
-extern chunk_t asn1_algorithmIdentifier(int oid);
-extern int known_oid(chunk_t object);
-extern u_int asn1_length(chunk_t *blob);
-extern void code_asn1_length(size_t length, chunk_t *code);
-extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
-extern chunk_t asn1_integer_from_mpz(const mpz_t value);
-extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
-extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
-extern bool is_printablestring(chunk_t str);
-extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
-extern chunk_t timetoasn1(const time_t *time, asn1_t type);
-extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob
- , u_int level0, bool implicit, u_int cond);
-extern bool extract_object(asn1Object_t const *objects
- , u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
-extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
- , const char* name);
-extern int parse_algorithmIdentifier(chunk_t blob, int level0
- , chunk_t *parameters);
-extern bool is_asn1(chunk_t blob);
-
-#endif /* _ASN1_H */
-
diff --git a/programs/pluto/ca.c b/programs/pluto/ca.c
deleted file mode 100644
index c1e0261d8..000000000
--- a/programs/pluto/ca.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/* Certification Authority (CA) support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ca.c,v 1.10 2005/12/25 12:29:55 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "ca.h"
-#include "certs.h"
-#include "whack.h"
-#include "fetch.h"
-
-/* chained list of X.509 authority certificates (ca, aa, and ocsp) */
-
-static x509cert_t *x509authcerts = NULL;
-
-const ca_info_t empty_ca_info = {
- NULL , /* next */
- NULL , /* name */
- UNDEFINED_TIME,
- { NULL, 0 } , /* authName */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKey SerialNumber */
- NULL , /* ldaphost */
- NULL , /* ldapbase */
- NULL , /* ocspori */
- NULL , /* crluri */
- FALSE /* strictcrlpolicy */
-};
-
-/* chained list of X.509 certification authority information records */
-
-static ca_info_t *ca_infos = NULL;
-
-/*
- * Checks if CA a is trusted by CA b
- */
-bool
-trusted_ca(chunk_t a, chunk_t b, int *pathlen)
-{
- bool match = FALSE;
-
- /* no CA b specified -> any CA a is accepted */
- if (b.ptr == NULL)
- {
- *pathlen = (a.ptr == NULL)? 0 : MAX_CA_PATH_LEN;
- return TRUE;
- }
-
- /* no CA a specified -> trust cannot be established */
- if (a.ptr == NULL)
- {
- *pathlen = MAX_CA_PATH_LEN;
- return FALSE;
- }
-
- *pathlen = 0;
-
- /* CA a equals CA b -> we have a match */
- if (same_dn(a, b))
- return TRUE;
-
- /* CA a might be a subordinate CA of b */
- lock_authcert_list("trusted_ca");
-
- while ((*pathlen)++ < MAX_CA_PATH_LEN)
- {
- x509cert_t *cacert = get_authcert(a, empty_chunk, empty_chunk, AUTH_CA);
-
- /* cacert not found or self-signed root cacert-> exit */
- if (cacert == NULL || same_dn(cacert->issuer, a))
- break;
-
- /* does the issuer of CA a match CA b? */
- match = same_dn(cacert->issuer, b);
-
- /* we have a match and exit the loop */
- if (match)
- break;
-
- /* go one level up in the CA chain */
- a = cacert->issuer;
- }
-
- unlock_authcert_list("trusted_ca");
- return match;
-}
-
-/*
- * does our CA match one of the requested CAs?
- */
-bool
-match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen)
-{
- /* if no ca is requested than any ca will match */
- if (requested_ca == NULL)
- {
- *our_pathlen = 0;
- return TRUE;
- }
-
- *our_pathlen = MAX_CA_PATH_LEN + 1;
-
- while (requested_ca != NULL)
- {
- int pathlen;
-
- if (trusted_ca(our_ca, requested_ca->name, &pathlen)
- && pathlen < *our_pathlen)
- *our_pathlen = pathlen;
- requested_ca = requested_ca->next;
- }
-
- return *our_pathlen <= MAX_CA_PATH_LEN;
-}
-
-/*
- * free the first authority certificate in the chain
- */
-static void
-free_first_authcert(void)
-{
- x509cert_t *first = x509authcerts;
- x509authcerts = first->next;
- free_x509cert(first);
-}
-
-/*
- * free all CA certificates
- */
-void
-free_authcerts(void)
-{
- lock_authcert_list("free_authcerts");
-
- while (x509authcerts != NULL)
- free_first_authcert();
-
- unlock_authcert_list("free_authcerts");
-}
-
-/*
- * get a X.509 authority certificate with a given subject or keyid
- */
-x509cert_t*
-get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags)
-{
- x509cert_t *cert = x509authcerts;
- x509cert_t *prev_cert = NULL;
-
- while (cert != NULL)
- {
- if (cert->authority_flags & auth_flags
- && ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
- : (same_dn(subject, cert->subject)
- && same_serial(serial, cert->serialNumber))))
- {
- if (cert != x509authcerts)
- {
- /* bring the certificate up front */
- prev_cert->next = cert->next;
- cert->next = x509authcerts;
- x509authcerts = cert;
- }
- return cert;
- }
- prev_cert = cert;
- cert = cert->next;
- }
- return NULL;
-}
-
-/*
- * add an authority certificate to the chained list
- */
-bool
-add_authcert(x509cert_t *cert, u_char auth_flags)
-{
- x509cert_t *old_cert;
-
- /* set authority flags */
- cert->authority_flags |= auth_flags;
-
- lock_authcert_list("add_authcert");
-
- old_cert = get_authcert(cert->subject, cert->serialNumber
- , cert->subjectKeyID, auth_flags);
-
- if (old_cert != NULL)
- {
- if (same_x509cert(cert, old_cert))
- {
- /* cert is already present, just add additional authority flags */
- old_cert->authority_flags |= cert->authority_flags;
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" authcert is already present and identical")
- )
- unlock_authcert_list("add_authcert");
-
- free_x509cert(cert);
- return FALSE;
- }
- else
- {
- /* cert is already present but will be replaced by new cert */
- free_first_authcert();
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" existing authcert deleted")
- )
- }
- }
-
- /* add new authcert to chained list */
- cert->next = x509authcerts;
- x509authcerts = cert;
- share_x509cert(cert); /* set count to one */
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" authcert inserted")
- )
- unlock_authcert_list("add_authcert");
- return TRUE;
-}
-
-/*
- * Loads authority certificates
- */
-void
-load_authcerts(const char *type, const char *path, u_char auth_flags)
-{
- struct dirent **filelist;
- u_char buf[BUF_LEN];
- u_char *save_dir;
- int n;
-
- /* change directory to specified path */
- save_dir = getcwd(buf, BUF_LEN);
-
- if (chdir(path))
- {
- plog("Could not change to directory '%s'", path);
- }
- else
- {
- plog("Changing to directory '%s'", path);
- n = scandir(path, &filelist, file_select, alphasort);
-
- if (n < 0)
- plog(" scandir() error");
- else
- {
- while (n--)
- {
- cert_t cert;
-
- if (load_cert(filelist[n]->d_name, type, &cert))
- add_authcert(cert.u.x509, auth_flags);
-
- free(filelist[n]);
- }
- free(filelist);
- }
- }
- /* restore directory path */
- chdir(save_dir);
-}
-
-/*
- * list all X.509 authcerts with given auth flags in a chained list
- */
-void
-list_authcerts(const char *caption, u_char auth_flags, bool utc)
-{
- lock_authcert_list("list_authcerts");
- list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
- unlock_authcert_list("list_authcerts");
-}
-
-/*
- * get a cacert with a given subject or keyid from an alternative list
- */
-static const x509cert_t*
-get_alt_cacert(chunk_t subject, chunk_t serial, chunk_t keyid
- , const x509cert_t *cert)
-{
- while (cert != NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
- : (same_dn(subject, cert->subject)
- && same_serial(serial, cert->serialNumber)))
- {
- return cert;
- }
- cert = cert->next;
- }
- return NULL;
-}
-
-/* establish trust into a candidate authcert by going up the trust chain.
- * validity and revocation status are not checked.
- */
-bool
-trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
-{
- int pathlen;
-
- lock_authcert_list("trust_authcert_candidate");
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- const x509cert_t *authcert = NULL;
- u_char buf[BUF_LEN];
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
-
- /* search in alternative chain first */
- authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, alt_chain);
-
- if (authcert != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found in alternative chain")
- )
- }
- else
- {
- /* search in trusted chain */
- authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
-
- if (authcert != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
- )
- }
- else
- {
- plog("issuer cacert not found");
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
- }
- }
-
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, authcert))
- {
- plog("certificate signature is invalid");
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
- )
-
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
- {
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- unlock_authcert_list("trust_authcert_candidate");
- return TRUE;
- }
-
- /* go up one step in the trust chain */
- cert = authcert;
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
-}
-
-/*
- * get a CA info record with a given authName or authKeyID
- */
-ca_info_t*
-get_ca_info(chunk_t authname, chunk_t serial, chunk_t keyid)
-{
- ca_info_t *ca= ca_infos;
-
- while (ca!= NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID)
- : (same_dn(authname, ca->authName)
- && same_serial(serial, ca->authKeySerialNumber)))
- {
- return ca;
- }
- ca = ca->next;
- }
- return NULL;
-}
-
-
-/*
- * free the dynamic memory used by a ca_info record
- */
-static void
-free_ca_info(ca_info_t* ca_info)
-{
- if (ca_info == NULL)
- return;
-
- pfreeany(ca_info->name);
- pfreeany(ca_info->ldaphost);
- pfreeany(ca_info->ldapbase);
- pfreeany(ca_info->ocspuri);
-
- freeanychunk(ca_info->authName);
- freeanychunk(ca_info->authKeyID);
- freeanychunk(ca_info->authKeySerialNumber);
-
- free_generalNames(ca_info->crluri, TRUE);
-
- pfree(ca_info);
-}
-
-/*
- * free all CA certificates
- */
-void
-free_ca_infos(void)
-{
- while (ca_infos != NULL)
- {
- ca_info_t *ca = ca_infos;
-
- ca_infos = ca_infos->next;
- free_ca_info(ca);
- }
-}
-
-/*
- * find a CA information record by name and optionally delete it
- */
-bool
-find_ca_info_by_name(const char *name, bool delete)
-{
- ca_info_t **ca_p = &ca_infos;
- ca_info_t *ca = *ca_p;
-
- while (ca != NULL)
- {
- /* is there already an entry? */
- if (streq(name, ca->name))
- {
- if (delete)
- {
- lock_ca_info_list("find_ca_info_by_name");
- *ca_p = ca->next;
- free_ca_info(ca);
- plog("deleting ca description \"%s\"", name);
- unlock_ca_info_list("find_ca_info_by_name");
- }
- return TRUE;
- }
- ca_p = &ca->next;
- ca = *ca_p;
- }
- return FALSE;
-}
-
-
- /*
- * adds a CA description to a chained list
- */
-void
-add_ca_info(const whack_message_t *msg)
-{
- smartcard_t *sc = NULL;
- cert_t cert;
- bool valid_cert = FALSE;
- bool cached_cert = FALSE;
-
- if (find_ca_info_by_name(msg->name, FALSE))
- {
- loglog(RC_DUPNAME, "attempt to redefine ca record \"%s\"", msg->name);
- return;
- }
-
- if (scx_on_smartcard(msg->cacert))
- {
- /* load CA cert from smartcard */
- valid_cert = scx_load_cert(msg->cacert, &sc, &cert, &cached_cert);
- }
- else
- {
- /* load CA cert from file */
- valid_cert = load_ca_cert(msg->cacert, &cert);
- }
-
- if (valid_cert)
- {
- char buf[BUF_LEN];
- x509cert_t *cacert = cert.u.x509;
- ca_info_t *ca = NULL;
-
- /* does the authname already exist? */
- ca = get_ca_info(cacert->subject, cacert->serialNumber
- , cacert->subjectKeyID);
-
- if (ca != NULL)
- {
- /* ca_info is already present */
- loglog(RC_DUPNAME, " duplicate ca information in record \"%s\" found,"
- "ignoring \"%s\"", ca->name, msg->name);
- free_x509cert(cacert);
- return;
- }
-
- plog("added ca description \"%s\"", msg->name);
-
- /* create and initialize new ca_info record */
- ca = alloc_thing(ca_info_t, "ca info");
- *ca = empty_ca_info;
-
- /* name */
- ca->name = clone_str(msg->name, "ca name");
-
- /* authName */
- clonetochunk(ca->authName, cacert->subject.ptr
- , cacert->subject.len, "authName");
- dntoa(buf, BUF_LEN, ca->authName);
- DBG(DBG_CONTROL,
- DBG_log("authname: '%s'", buf)
- )
-
- /* authSerialNumber */
- clonetochunk(ca->authKeySerialNumber, cacert->serialNumber.ptr
- , cacert->serialNumber.len, "authKeySerialNumber");
-
- /* authKeyID */
- if (cacert->subjectKeyID.ptr != NULL)
- {
- clonetochunk(ca->authKeyID, cacert->subjectKeyID.ptr
- , cacert->subjectKeyID.len, "authKeyID");
- datatot(cacert->subjectKeyID.ptr, cacert->subjectKeyID.len, ':'
- , buf, BUF_LEN);
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log("authkey: %s", buf)
- )
- }
-
- /* ldaphost */
- ca->ldaphost = clone_str(msg->ldaphost, "ldaphost");
-
- /* ldapbase */
- ca->ldapbase = clone_str(msg->ldapbase, "ldapbase");
-
- /* ocspuri */
- if (msg->ocspuri != NULL)
- {
- if (strncasecmp(msg->ocspuri, "http", 4) == 0)
- ca->ocspuri = clone_str(msg->ocspuri, "ocspuri");
- else
- plog(" ignoring ocspuri with unkown protocol");
- }
-
- /* crluri2*/
- if (msg->crluri2 != NULL)
- {
- generalName_t gn =
- { NULL, GN_URI, {msg->crluri2, strlen(msg->crluri2)} };
-
- add_distribution_points(&gn, &ca->crluri);
- }
-
- /* crluri */
- if (msg->crluri != NULL)
- {
- generalName_t gn =
- { NULL, GN_URI, {msg->crluri, strlen(msg->crluri)} };
-
- add_distribution_points(&gn, &ca->crluri);
- }
-
- /* strictrlpolicy */
- ca->strictcrlpolicy = msg->whack_strict;
-
- /* insert ca_info record into the chained list */
- lock_ca_info_list("add_ca_info");
-
- ca->next = ca_infos;
- ca_infos = ca;
- ca->installed = time(NULL);
-
- unlock_ca_info_list("add_ca_info");
-
- /* add cacert to list of authcerts */
- if (!cached_cert)
- {
- if (add_authcert(cacert, AUTH_CA) && sc != NULL)
- {
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
- sc->last_cert.u.x509->count--;
- sc->last_cert = cert;
- share_cert(sc->last_cert);
- }
- }
- if (sc != NULL)
- time(&sc->last_load);
- }
-}
-
-/*
- * list all ca_info records in the chained list
- */
-void
-list_ca_infos(bool utc)
-{
- ca_info_t *ca = ca_infos;
-
- if (ca != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 CA Information Records:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (ca != NULL)
- {
- u_char buf[BUF_LEN];
-
- /* strictpolicy per CA not supported yet
- *
- whack_log(RC_COMMENT, "%s, \"%s\", strictcrlpolicy: %s"
- , timetoa(&ca->installed, utc), ca->name
- , ca->strictcrlpolicy? "yes":"no");
- */
- whack_log(RC_COMMENT, "%s, \"%s\"", timetoa(&ca->installed, utc), ca->name);
- dntoa(buf, BUF_LEN, ca->authName);
- whack_log(RC_COMMENT, " authname: '%s'", buf);
- if (ca->ldaphost != NULL)
- whack_log(RC_COMMENT, " ldaphost: '%s'", ca->ldaphost);
- if (ca->ldapbase != NULL)
- whack_log(RC_COMMENT, " ldapbase: '%s'", ca->ldapbase);
- if (ca->ocspuri != NULL)
- whack_log(RC_COMMENT, " ocspuri: '%s'", ca->ocspuri);
-
- list_distribution_points(ca->crluri);
-
- if (ca->authKeyID.ptr != NULL)
- {
- datatot(ca->authKeyID.ptr, ca->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (ca->authKeySerialNumber.ptr != NULL)
- {
- datatot(ca->authKeySerialNumber.ptr, ca->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
- ca = ca->next;
- }
-}
-
-
diff --git a/programs/pluto/ca.h b/programs/pluto/ca.h
deleted file mode 100644
index 8d4602dc6..000000000
--- a/programs/pluto/ca.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Certification Authority (CA) support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ca.h,v 1.5 2005/12/25 12:28:40 as Exp $
- */
-
-#ifndef _CA_H
-#define _CA_H
-
-#include "x509.h"
-#include "whack.h"
-
-#define MAX_CA_PATH_LEN 7
-
-/* authority flags */
-
-#define AUTH_NONE 0x00 /* no authorities */
-#define AUTH_CA 0x01 /* certification authority */
-#define AUTH_AA 0x02 /* authorization authority */
-#define AUTH_OCSP 0x04 /* ocsp signing authority */
-
-/* CA info structures */
-
-typedef struct ca_info ca_info_t;
-
-struct ca_info {
- ca_info_t *next;
- char *name;
- time_t installed;
- chunk_t authName;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- char *ldaphost;
- char *ldapbase;
- char *ocspuri;
- generalName_t *crluri;
- bool strictcrlpolicy;
-};
-
-extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
-extern bool match_requested_ca(generalName_t *requested_ca
- , chunk_t our_ca, int *our_pathlen);
-extern x509cert_t* get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid
- , u_char auth_flags);
-extern void load_authcerts(const char *type, const char *path
- , u_char auth_flags);
-extern bool add_authcert(x509cert_t *cert, u_char auth_flags);
-extern void free_authcerts(void);
-extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
-extern bool trust_authcert_candidate(const x509cert_t *cert
- , const x509cert_t *alt_chain);
-extern ca_info_t* get_ca_info(chunk_t name, chunk_t serial, chunk_t keyid);
-extern bool find_ca_info_by_name(const char *name, bool delete);
-extern void add_ca_info(const whack_message_t *msg);
-extern void delete_ca_info(const char *name);
-extern void free_ca_infos(void);
-extern void list_ca_infos(bool utc);
-
-#endif /* _CA_H */
-
diff --git a/programs/pluto/certs.c b/programs/pluto/certs.c
deleted file mode 100644
index 92b40605f..000000000
--- a/programs/pluto/certs.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* Certificate support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: certs.c,v 1.8 2005/11/06 22:55:41 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "asn1.h"
-#include "id.h"
-#include "x509.h"
-#include "pgp.h"
-#include "pem.h"
-#include "certs.h"
-#include "pkcs1.h"
-
-/*
- * used for initializatin of certs
- */
-const cert_t empty_cert = {CERT_NONE, {NULL}};
-
-/*
- * extracts the certificate to be sent to the peer
- */
-chunk_t
-get_mycert(cert_t cert)
-{
- switch (cert.type)
- {
- case CERT_PGP:
- return cert.u.pgp->certificate;
- case CERT_X509_SIGNATURE:
- return cert.u.x509->certificate;
- default:
- return empty_chunk;
- }
-}
-
-/* load a coded key or certificate file with autodetection
- * of binary DER or base64 PEM ASN.1 formats and armored PGP format
- */
-bool
-load_coded_file(const char *filename, prompt_pass_t *pass, const char *type
-, chunk_t *blob, bool *pgp)
-{
- err_t ugh = NULL;
-
- FILE *fd = fopen(filename, "r");
-
- if (fd)
- {
- int bytes;
- fseek(fd, 0, SEEK_END );
- blob->len = ftell(fd);
- rewind(fd);
- blob->ptr = alloc_bytes(blob->len, type);
- bytes = fread(blob->ptr, 1, blob->len, fd);
- fclose(fd);
- plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
-
- *pgp = FALSE;
-
- /* try DER format */
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in DER format");
- )
- return TRUE;
- }
-
- /* try PEM format */
- ugh = pemtobin(blob, pass, filename, pgp);
-
- if (ugh == NULL)
- {
- if (*pgp)
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in armored PGP format");
- )
- return TRUE;
- }
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in PEM format");
- )
- return TRUE;
- }
- ugh = "file coded in unknown format, discarded";
- }
-
- /* a conversion error has occured */
- plog(" %s", ugh);
- pfree(blob->ptr);
- *blob = empty_chunk;
- }
- else
- {
- plog(" could not open %s file '%s'", type, filename);
- }
- return FALSE;
-}
-
-/*
- * Loads a PKCS#1 or PGP private RSA key file
- */
-err_t
-load_rsa_private_key(const char* filename, prompt_pass_t *pass
-, RSA_private_key_t *key)
-{
- err_t ugh = NULL;
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
-
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
-
- if (load_coded_file(path, pass, "private key", &blob, &pgp))
- {
- if (pgp)
- {
- if (!parse_pgp(blob, NULL, key))
- ugh = "syntax error in PGP private key file";
- }
- else
- {
- if (!pkcs1_parse_private_key(blob, key))
- ugh = "syntax error in PKCS#1 private key file";
- }
- pfree(blob.ptr);
- }
- else
- ugh = "error loading RSA private key file";
-
- return ugh;
-}
-/*
- * Loads a X.509 or OpenPGP certificate
- */
-bool
-load_cert(const char *filename, const char *label, cert_t *cert)
-{
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
-
- /* initialize cert struct */
- cert->type = CERT_NONE;
- cert->u.x509 = NULL;
-
- if (load_coded_file(filename, NULL, label, &blob, &pgp))
- {
- if (pgp)
- {
- pgpcert_t *pgpcert = alloc_thing(pgpcert_t, "pgpcert");
- *pgpcert = empty_pgpcert;
- if (parse_pgp(blob, pgpcert, NULL))
- {
- cert->type = CERT_PGP;
- cert->u.pgp = pgpcert;
- return TRUE;
- }
- else
- {
- plog(" error in OpenPGP certificate");
- free_pgpcert(pgpcert);
- return FALSE;
- }
- }
- else
- {
- x509cert_t *x509cert = alloc_thing(x509cert_t, "x509cert");
- *x509cert = empty_x509cert;
- if (parse_x509cert(blob, 0, x509cert))
- {
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return TRUE;
- }
- else
- {
- plog(" error in X.509 certificate");
- free_x509cert(x509cert);
- return FALSE;
- }
- }
- }
- return FALSE;
-}
-
-/*
- * Loads a host certificate
- */
-bool
-load_host_cert(const char *filename, cert_t *cert)
-{
- const char *path = concatenate_paths(HOST_CERT_PATH, filename);
-
- return load_cert(path, "host cert", cert);
-}
-
-/*
- * Loads a CA certificate
- */
-bool
-load_ca_cert(const char *filename, cert_t *cert)
-{
- const char *path = concatenate_paths(CA_CERT_PATH, filename);
-
- return load_cert(path, "CA cert", cert);
-}
-
-/*
- * establish equality of two certificates
- */
-bool
-same_cert(const cert_t *a, const cert_t *b)
-{
- return a->type == b->type && a->u.x509 == b->u.x509;
-}
-
-/* for each link pointing to the certif icate
- " increase the count by one
- */
-void
-share_cert(cert_t cert)
-{
- switch (cert.type)
- {
- case CERT_PGP:
- share_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- share_x509cert(cert.u.x509);
- break;
- default:
- break;
- }
-}
-
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
- */
-void
-release_cert(cert_t cert)
-{
- switch (cert.type)
- {
- case CERT_PGP:
- release_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- release_x509cert(cert.u.x509);
- break;
- default:
- break;
- }
-}
-
-/*
- * list all X.509 and OpenPGP end certificates
- */
-void
-list_certs(bool utc)
-{
- list_x509_end_certs(utc);
- list_pgp_end_certs(utc);
-}
-
diff --git a/programs/pluto/certs.h b/programs/pluto/certs.h
deleted file mode 100644
index cca128965..000000000
--- a/programs/pluto/certs.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Certificate support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: certs.h,v 1.7 2005/11/06 22:55:41 as Exp $
- */
-
-#ifndef _CERTS_H
-#define _CERTS_H
-
-#include "pkcs1.h"
-#include "x509.h"
-#include "pgp.h"
-
-/* path definitions for private keys, end certs,
- * cacerts, attribute certs and crls
- */
-#define PRIVATE_KEY_PATH "/etc/ipsec.d/private"
-#define HOST_CERT_PATH "/etc/ipsec.d/certs"
-#define CA_CERT_PATH "/etc/ipsec.d/cacerts"
-#define A_CERT_PATH "/etc/ipsec.d/acerts"
-#define AA_CERT_PATH "/etc/ipsec.d/aacerts"
-#define OCSP_CERT_PATH "/etc/ipsec.d/ocspcerts"
-#define CRL_PATH "/etc/ipsec.d/crls"
-#define REQ_PATH "/etc/ipsec.d/reqs"
-
-/* advance warning of imminent expiry of
- * cacerts, public keys, and crls
- */
-#define CA_CERT_WARNING_INTERVAL 30 /* days */
-#define OCSP_CERT_WARNING_INTERVAL 30 /* days */
-#define PUBKEY_WARNING_INTERVAL 7 /* days */
-#define CRL_WARNING_INTERVAL 7 /* days */
-#define ACERT_WARNING_INTERVAL 1 /* day */
-
-/* certificate access structure
- * currently X.509 and OpenPGP certificates are supported
- */
-typedef struct {
- u_char type;
- union {
- x509cert_t *x509;
- pgpcert_t *pgp;
- } u;
-} cert_t;
-
-/* used for initialization */
-extern const cert_t empty_cert;
-
-/* do not send certificate requests
- * flag set in plutomain.c and used in ipsec_doi.c
- */
-extern bool no_cr_send;
-
-extern err_t load_rsa_private_key(const char* filename, prompt_pass_t *pass
- , RSA_private_key_t *key);
-extern chunk_t get_mycert(cert_t cert);
-extern bool load_coded_file(const char *filename, prompt_pass_t *pass
- , const char *type, chunk_t *blob, bool *pgp);
-extern bool load_cert(const char *filename, const char *label
- , cert_t *cert);
-extern bool load_host_cert(const char *filename, cert_t *cert);
-extern bool load_ca_cert(const char *filename, cert_t *cert);
-extern bool same_cert(const cert_t *a, const cert_t *b);
-extern void share_cert(cert_t cert);
-extern void release_cert(cert_t cert);
-extern void list_certs(bool utc);
-
-#endif /* _CERTS_H */
-
-
diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
deleted file mode 100644
index 93b3bd2b6..000000000
--- a/programs/pluto/connections.c
+++ /dev/null
@@ -1,4457 +0,0 @@
-/* information about connections between hosts and clients
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: connections.c,v 1.47 2007/01/10 00:36:19 as Exp $
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-#include "kameipsec.h"
-
-#include "constants.h"
-#include "defs.h"
-#include "id.h"
-#include "x509.h"
-#include "ca.h"
-#include "crl.h"
-#include "pgp.h"
-#include "certs.h"
-#include "ac.h"
-#include "smartcard.h"
-#include "fetch.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "demux.h"
-#include "state.h"
-#include "timer.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "server.h"
-#include "kernel.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "whack.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "kernel_alg.h"
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-#ifdef VIRTUAL_IP
-#include "virtual.h"
-#endif
-
-static void flush_pending_by_connection(struct connection *c); /* forward */
-
-static struct connection *connections = NULL;
-
-/* struct host_pair: a nexus of information about a pair of hosts.
- * A host is an IP address, UDP port pair. This is a debatable choice:
- * - should port be considered (no choice of port in standard)?
- * - should ID be considered (hard because not always known)?
- * - should IP address matter on our end (we don't know our end)?
- * Only oriented connections are registered.
- * Unoriented connections are kept on the unoriented_connections
- * linked list (using hp_next). For them, host_pair is NULL.
- */
-
-struct host_pair {
- struct {
- ip_address addr;
- u_int16_t port; /* host order */
- } me, him;
- bool initial_connection_sent;
- struct connection *connections; /* connections with this pair */
- struct pending *pending; /* awaiting Keying Channel */
- struct host_pair *next;
-};
-
-static struct host_pair *host_pairs = NULL;
-
-static struct connection *unoriented_connections = NULL;
-
-/* check to see that Ids of peers match */
-bool
-same_peer_ids(const struct connection *c, const struct connection *d
-, const struct id *his_id)
-{
- return same_id(&c->spd.this.id, &d->spd.this.id)
- && same_id(his_id == NULL? &c->spd.that.id : his_id, &d->spd.that.id);
-}
-
-static struct host_pair *
-find_host_pair(const ip_address *myaddr, u_int16_t myport
-, const ip_address *hisaddr, u_int16_t hisport)
-{
- struct host_pair *p, *prev;
-
- /* default hisaddr to an appropriate any */
- if (hisaddr == NULL)
- hisaddr = aftoinfo(addrtypeof(myaddr))->any;
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- {
- /**
- * port is not relevant in host_pair. with nat_traversal we
- * always use pluto_port (500)
- */
- myport = pluto_port;
- hisport = pluto_port;
- }
-#endif
-
- for (prev = NULL, p = host_pairs; p != NULL; prev = p, p = p->next)
- {
- if (sameaddr(&p->me.addr, myaddr) && p->me.port == myport
- && sameaddr(&p->him.addr, hisaddr) && p->him.port == hisport)
- {
- if (prev != NULL)
- {
- prev->next = p->next; /* remove p from list */
- p->next = host_pairs; /* and stick it on front */
- host_pairs = p;
- }
- break;
- }
- }
- return p;
-}
-
-/* find head of list of connections with this pair of hosts */
-static struct connection *
-find_host_pair_connections(const ip_address *myaddr, u_int16_t myport
-, const ip_address *hisaddr, u_int16_t hisport)
-{
- struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport);
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled && hp && hisaddr)
- {
- struct connection *c;
- for (c = hp->connections; c != NULL; c = c->hp_next)
- {
- if ((c->spd.this.host_port==myport) && (c->spd.that.host_port==hisport))
- return c;
- }
- return NULL;
- }
-#endif
-
- return hp == NULL? NULL : hp->connections;
-}
-
-static void
-connect_to_host_pair(struct connection *c)
-{
- if (oriented(*c))
- {
- struct host_pair *hp = find_host_pair(&c->spd.this.host_addr, c->spd.this.host_port
- , &c->spd.that.host_addr, c->spd.that.host_port);
-
- if (hp == NULL)
- {
- /* no suitable host_pair -- build one */
- hp = alloc_thing(struct host_pair, "host_pair");
- hp->me.addr = c->spd.this.host_addr;
- hp->him.addr = c->spd.that.host_addr;
-#ifdef NAT_TRAVERSAL
- hp->me.port = nat_traversal_enabled ? pluto_port : c->spd.this.host_port;
- hp->him.port = nat_traversal_enabled ? pluto_port : c->spd.that.host_port;
-#else
- hp->me.port = c->spd.this.host_port;
- hp->him.port = c->spd.that.host_port;
-#endif
- hp->initial_connection_sent = FALSE;
- hp->connections = NULL;
- hp->pending = NULL;
- hp->next = host_pairs;
- host_pairs = hp;
- }
- c->host_pair = hp;
- c->hp_next = hp->connections;
- hp->connections = c;
- }
- else
- {
- /* since this connection isn't oriented, we place it
- * in the unoriented_connections list instead.
- */
- c->host_pair = NULL;
- c->hp_next = unoriented_connections;
- unoriented_connections = c;
- }
-}
-
-/* find a connection by name.
- * If strict, don't accept a CK_INSTANCE.
- * Move the winner (if any) to the front.
- * If none is found, and strict, a diagnostic is logged to whack.
- */
-struct connection *
-con_by_name(const char *nm, bool strict)
-{
- struct connection *p, *prev;
-
- for (prev = NULL, p = connections; ; prev = p, p = p->ac_next)
- {
- if (p == NULL)
- {
- if (strict)
- whack_log(RC_UNKNOWN_NAME
- , "no connection named \"%s\"", nm);
- break;
- }
- if (streq(p->name, nm)
- && (!strict || p->kind != CK_INSTANCE))
- {
- if (prev != NULL)
- {
- prev->ac_next = p->ac_next; /* remove p from list */
- p->ac_next = connections; /* and stick it on front */
- connections = p;
- }
- break;
- }
- }
- return p;
-}
-
-void
-release_connection(struct connection *c, bool relations)
-{
- if (c->kind == CK_INSTANCE)
- {
- /* This does everything we need.
- * Note that we will be called recursively by delete_connection,
- * but kind will be CK_GOING_AWAY.
- */
- delete_connection(c, relations);
- }
- else
- {
- flush_pending_by_connection(c);
- delete_states_by_connection(c, relations);
- unroute_connection(c);
- }
-}
-
-/* Delete a connection */
-
-#define list_rm(etype, enext, e, ehead) { \
- etype **ep; \
- for (ep = &(ehead); *ep != (e); ep = &(*ep)->enext) \
- passert(*ep != NULL); /* we must not come up empty-handed */ \
- *ep = (e)->enext; \
- }
-
-
-void
-delete_connection(struct connection *c, bool relations)
-{
- struct connection *old_cur_connection
- = cur_connection == c? NULL : cur_connection;
-#ifdef DEBUG
- lset_t old_cur_debugging = cur_debugging;
-#endif
-
- set_cur_connection(c);
-
- /* Must be careful to avoid circularity:
- * we mark c as going away so it won't get deleted recursively.
- */
- passert(c->kind != CK_GOING_AWAY);
- if (c->kind == CK_INSTANCE)
- {
- plog("deleting connection \"%s\" instance with peer %s {isakmp=#%lu/ipsec=#%lu}"
- , c->name
- , ip_str(&c->spd.that.host_addr)
- , c->newest_isakmp_sa, c->newest_ipsec_sa);
- c->kind = CK_GOING_AWAY;
- }
- else
- {
- plog("deleting connection");
- }
- release_connection(c, relations); /* won't delete c */
-
- if (c->kind == CK_GROUP)
- delete_group(c);
-
- /* free up any logging resources */
- perpeer_logfree(c);
-
- /* find and delete c from connections list */
- list_rm(struct connection, ac_next, c, connections);
- cur_connection = old_cur_connection;
-
- /* find and delete c from the host pair list */
- if (c->host_pair == NULL)
- {
- list_rm(struct connection, hp_next, c, unoriented_connections);
- }
- else
- {
- struct host_pair *hp = c->host_pair;
-
- list_rm(struct connection, hp_next, c, hp->connections);
- c->host_pair = NULL; /* redundant, but safe */
-
- /* if there are no more connections with this host_pair
- * and we haven't even made an initial contact, let's delete
- * this guy in case we were created by an attempted DOS attack.
- */
- if (hp->connections == NULL
- && !hp->initial_connection_sent)
- {
- passert(hp->pending == NULL); /* ??? must deal with this! */
- list_rm(struct host_pair, next, hp, host_pairs);
- pfree(hp);
- }
- }
-
-#ifdef VIRTUAL_IP
- if (c->kind != CK_GOING_AWAY) pfreeany(c->spd.that.virt);
-#endif
-
-#ifdef DEBUG
- cur_debugging = old_cur_debugging;
-#endif
- pfreeany(c->name);
- free_id_content(&c->spd.this.id);
- pfreeany(c->spd.this.updown);
- freeanychunk(c->spd.this.ca);
- free_ietfAttrList(c->spd.this.groups);
- free_id_content(&c->spd.that.id);
- pfreeany(c->spd.that.updown);
- freeanychunk(c->spd.that.ca);
- free_ietfAttrList(c->spd.that.groups);
- free_generalNames(c->requested_ca, TRUE);
- gw_delref(&c->gw_info);
-
- lock_certs_and_keys("delete_connection");
- release_cert(c->spd.this.cert);
- scx_release(c->spd.this.sc);
- release_cert(c->spd.that.cert);
- scx_release(c->spd.that.sc);
- unlock_certs_and_keys("delete_connection");
-
- alg_info_delref((struct alg_info **)&c->alg_info_esp);
- alg_info_delref((struct alg_info **)&c->alg_info_ike);
-
- pfree(c);
-}
-
-/* Delete connections with the specified name */
-void
-delete_connections_by_name(const char *name, bool strict)
-{
- struct connection *c = con_by_name(name, strict);
-
- for (; c != NULL; c = con_by_name(name, FALSE))
- delete_connection(c, FALSE);
-}
-
-void
-delete_every_connection(void)
-{
- while (connections != NULL)
- delete_connection(connections, TRUE);
-}
-
-void
-release_dead_interfaces(void)
-{
- struct host_pair *hp;
-
- for (hp = host_pairs; hp != NULL; hp = hp->next)
- {
- struct connection **pp
- , *p;
-
- for (pp = &hp->connections; (p = *pp) != NULL; )
- {
- if (p->interface->change == IFN_DELETE)
- {
- /* this connection's interface is going away */
- enum connection_kind k = p->kind;
-
- release_connection(p, TRUE);
-
- if (k <= CK_PERMANENT)
- {
- /* The connection should have survived release:
- * move it to the unoriented_connections list.
- */
- passert(p == *pp);
-
- p->interface = NULL;
-
- *pp = p->hp_next; /* advance *pp */
- p->host_pair = NULL;
- p->hp_next = unoriented_connections;
- unoriented_connections = p;
- }
- else
- {
- /* The connection should have vanished,
- * but the previous connection remains.
- */
- passert(p != *pp);
- }
- }
- else
- {
- pp = &p->hp_next; /* advance pp */
- }
- }
- }
-}
-
-/* adjust orientations of connections to reflect newly added interfaces */
-void
-check_orientations(void)
-{
- /* try to orient all the unoriented connections */
- {
- struct connection *c = unoriented_connections;
-
- unoriented_connections = NULL;
-
- while (c != NULL)
- {
- struct connection *nxt = c->hp_next;
-
- (void)orient(c);
- connect_to_host_pair(c);
- c = nxt;
- }
- }
-
- /* Check that no oriented connection has become double-oriented.
- * In other words, the far side must not match one of our new interfaces.
- */
- {
- struct iface *i;
-
- for (i = interfaces; i != NULL; i = i->next)
- {
- if (i->change == IFN_ADD)
- {
- struct host_pair *hp;
-
- for (hp = host_pairs; hp != NULL; hp = hp->next)
- {
- if (sameaddr(&hp->him.addr, &i->addr)
- && (!no_klips || hp->him.port == pluto_port))
- {
- /* bad news: the whole chain of connections
- * hanging off this host pair has both sides
- * matching an interface.
- * We'll get rid of them, using orient and
- * connect_to_host_pair. But we'll be lazy
- * and not ditch the host_pair itself (the
- * cost of leaving it is slight and cannot
- * be induced by a foe).
- */
- struct connection *c = hp->connections;
-
- hp->connections = NULL;
- while (c != NULL)
- {
- struct connection *nxt = c->hp_next;
-
- c->interface = NULL;
- (void)orient(c);
- connect_to_host_pair(c);
- c = nxt;
- }
- }
- }
- }
- }
- }
-}
-
-static err_t
-default_end(struct end *e, ip_address *dflt_nexthop)
-{
- err_t ugh = NULL;
- const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr));
-
- if (afi == NULL)
- return "unknown address family in default_end";
-
- /* default ID to IP (but only if not NO_IP -- WildCard) */
- if (e->id.kind == ID_NONE && !isanyaddr(&e->host_addr))
- {
- e->id.kind = afi->id_addr;
- e->id.ip_addr = e->host_addr;
- e->has_id_wildcards = FALSE;
- }
-
- /* default nexthop to other side */
- if (isanyaddr(&e->host_nexthop))
- e->host_nexthop = *dflt_nexthop;
-
- /* default client to subnet containing only self
- * XXX This may mean that the client's address family doesn't match
- * tunnel_addr_family.
- */
- if (!e->has_client)
- ugh = addrtosubnet(&e->host_addr, &e->client);
-
- return ugh;
-}
-
-/* Format the topology of a connection end, leaving out defaults.
- * Largest left end looks like: client === host : port [ host_id ] --- hop
- * Note: if that==NULL, skip nexthop
- * Returns strlen of formated result (length excludes NUL at end).
- */
-size_t
-format_end(char *buf
-, size_t buf_len
-, const struct end *this
-, const struct end *that
-, bool is_left
-, lset_t policy)
-{
- char client[SUBNETTOT_BUF];
- const char *client_sep = "";
- char protoport[sizeof(":255/65535")];
- const char *host = NULL;
- char host_space[ADDRTOT_BUF];
- char host_port[sizeof(":65535")];
- char host_id[BUF_LEN + 2];
- char hop[ADDRTOT_BUF];
- const char *hop_sep = "";
- const char *open_brackets = "";
- const char *close_brackets = "";
-
- if (isanyaddr(&this->host_addr))
- {
- switch (policy & (POLICY_GROUP | POLICY_OPPO))
- {
- case POLICY_GROUP:
- host = "%group";
- break;
- case POLICY_OPPO:
- host = "%opportunistic";
- break;
- case POLICY_GROUP | POLICY_OPPO:
- host = "%opportunisticgroup";
- break;
- default:
- host = "%any";
- break;
- }
- }
-
- client[0] = '\0';
-
-#ifdef VIRTUAL_IP
- if (is_virtual_end(this) && isanyaddr(&this->host_addr))
- {
- host = "%virtual";
- }
-#endif
-
- /* [client===] */
- if (this->has_client)
- {
- ip_address client_net, client_mask;
-
- networkof(&this->client, &client_net);
- maskof(&this->client, &client_mask);
- client_sep = "===";
-
- /* {client_subnet_wildcard} */
- if (this->has_client_wildcard)
- {
- open_brackets = "{";
- close_brackets = "}";
- }
-
- if (isanyaddr(&client_net) && isanyaddr(&client_mask)
- && (policy & (POLICY_GROUP | POLICY_OPPO)))
- client_sep = ""; /* boring case */
- else if (subnetisnone(&this->client))
- strcpy(client, "?");
- else
- subnettot(&this->client, 0, client, sizeof(client));
- }
- else if (this->modecfg && isanyaddr(&this->host_srcip))
- {
- /* we are mode config client */
- client_sep = "===";
- strcpy(client, "%modecfg");
- }
-
- /* host */
- if (host == NULL)
- {
- addrtot(&this->host_addr, 0, host_space, sizeof(host_space));
- host = host_space;
- }
-
- host_port[0] = '\0';
- if (this->host_port != IKE_UDP_PORT)
- snprintf(host_port, sizeof(host_port), ":%u"
- , this->host_port);
-
- /* payload portocol and port */
- protoport[0] = '\0';
- if (this->has_port_wildcard)
- snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol);
- else if (this->port || this->protocol)
- snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol
- , this->port);
-
- /* id, if different from host */
- host_id[0] = '\0';
- if (this->id.kind == ID_MYID)
- {
- strcpy(host_id, "[%myid]");
- }
- else if (!(this->id.kind == ID_NONE
- || (id_is_ipaddr(&this->id) && sameaddr(&this->id.ip_addr, &this->host_addr))))
- {
- int len = idtoa(&this->id, host_id+1, sizeof(host_id)-2);
-
- host_id[0] = '[';
- strcpy(&host_id[len < 0? (ptrdiff_t)sizeof(host_id)-2 : 1 + len], "]");
- }
-
- /* [---hop] */
- hop[0] = '\0';
- hop_sep = "";
- if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr))
- {
- addrtot(&this->host_nexthop, 0, hop, sizeof(hop));
- hop_sep = "---";
- }
-
- if (is_left)
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s"
- , open_brackets, client, close_brackets
- , client_sep, host, host_port, host_id
- , protoport, hop_sep, hop);
- else
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s"
- , hop, hop_sep, host, host_port, host_id
- , protoport, client_sep
- , open_brackets, client, close_brackets);
- return strlen(buf);
-}
-
-/* format topology of a connection.
- * Two symmetric ends separated by ...
- */
-#define CONNECTION_BUF (2 * (END_BUF - 1) + 4)
-
-static size_t
-format_connection(char *buf, size_t buf_len
- , const struct connection *c
- , struct spd_route *sr)
-{
- size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY);
-
- w += snprintf(buf + w, buf_len - w, "...");
- return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);
-}
-
-static void
-unshare_connection_strings(struct connection *c)
-{
- c->name = clone_str(c->name, "connection name");
-
- unshare_id_content(&c->spd.this.id);
- c->spd.this.updown = clone_str(c->spd.this.updown, "updown");
- scx_share(c->spd.this.sc);
- share_cert(c->spd.this.cert);
- if (c->spd.this.ca.ptr != NULL)
- clonetochunk(c->spd.this.ca, c->spd.this.ca.ptr, c->spd.this.ca.len, "ca string");
-
- unshare_id_content(&c->spd.that.id);
- c->spd.that.updown = clone_str(c->spd.that.updown, "updown");
- scx_share(c->spd.that.sc);
- share_cert(c->spd.that.cert);
- if (c->spd.that.ca.ptr != NULL)
- clonetochunk(c->spd.that.ca, c->spd.that.ca.ptr, c->spd.that.ca.len, "ca string");
-
- /* increment references to algo's */
- alg_info_addref((struct alg_info *)c->alg_info_esp);
- alg_info_addref((struct alg_info *)c->alg_info_ike);
-}
-
-static void
-load_end_certificate(const char *filename, struct end *dst)
-{
- time_t valid_until;
- cert_t cert;
- bool valid_cert = FALSE;
- bool cached_cert = FALSE;
-
- /* initialize end certificate */
- dst->cert.type = CERT_NONE;
- dst->cert.u.x509 = NULL;
-
- /* initialize smartcard info record */
- dst->sc = NULL;
-
- if (filename != NULL)
- {
- if (scx_on_smartcard(filename))
- {
- /* load cert from smartcard */
- valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert);
- }
- else
- {
- /* load cert from file */
- valid_cert = load_host_cert(filename, &cert);
- }
- }
-
- if (valid_cert)
- {
- err_t ugh = NULL;
-
- switch (cert.type)
- {
- case CERT_PGP:
- select_pgpcert_id(cert.u.pgp, &dst->id);
-
- if (cached_cert)
- dst->cert = cert;
- else
- {
- valid_until = cert.u.pgp->until;
- add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.pgp = add_pgpcert(cert.u.pgp);
- }
- break;
- case CERT_X509_SIGNATURE:
- select_x509cert_id(cert.u.x509, &dst->id);
-
- if (cached_cert)
- dst->cert = cert;
- else
- {
- /* check validity of cert */
- valid_until = cert.u.x509->notAfter;
- ugh = check_validity(cert.u.x509, &valid_until);
- if (ugh != NULL)
- {
- plog(" %s", ugh);
- free_x509cert(cert.u.x509);
- break;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
- add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.x509 = add_x509cert(cert.u.x509);
- }
- /* if no CA is defined, use issuer as default */
- if (dst->ca.ptr == NULL)
- dst->ca = dst->cert.u.x509->issuer;
- break;
- default:
- break;
- }
-
- /* cache the certificate that was last retrieved from the smartcard */
- if (dst->sc != NULL)
- {
- if (!same_cert(&dst->sc->last_cert, &dst->cert))
- {
- lock_certs_and_keys("load_end_certificates");
- release_cert(dst->sc->last_cert);
- dst->sc->last_cert = dst->cert;
- share_cert(dst->cert);
- unlock_certs_and_keys("load_end_certificates");
- }
- time(&dst->sc->last_load);
- }
- }
-}
-
-static bool
-extract_end(struct end *dst, const whack_end_t *src, const char *which)
-{
- bool same_ca = FALSE;
-
- /* decode id, if any */
- if (src->id == NULL)
- {
- dst->id.kind = ID_NONE;
- }
- else
- {
- err_t ugh = atoid(src->id, &dst->id, TRUE);
-
- if (ugh != NULL)
- {
- loglog(RC_BADID, "bad %s --id: %s (ignored)", which, ugh);
- dst->id = empty_id; /* ignore bad one */
- }
- }
-
- dst->ca = empty_chunk;
-
- /* decode CA distinguished name, if any */
- if (src->ca != NULL)
- {
- if streq(src->ca, "%same")
- same_ca = TRUE;
- else if (!streq(src->ca, "%any"))
- {
- err_t ugh;
-
- dst->ca.ptr = temporary_cyclic_buffer();
- ugh = atodn(src->ca, &dst->ca);
- if (ugh != NULL)
- {
- plog("bad CA string '%s': %s (ignored)", src->ca, ugh);
- dst->ca = empty_chunk;
- }
- }
- }
-
- /* load local end certificate and extract ID, if any */
- load_end_certificate(src->cert, dst);
-
- /* does id has wildcards? */
- dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0;
-
- /* decode group attributes, if any */
- decode_groups(src->groups, &dst->groups);
-
- /* the rest is simple copying of corresponding fields */
- dst->host_addr = src->host_addr;
- dst->host_nexthop = src->host_nexthop;
- dst->host_srcip = src->host_srcip;
- dst->has_natip = src->has_natip;
- dst->client = src->client;
- dst->protocol = src->protocol;
- dst->port = src->port;
- dst->has_port_wildcard = src->has_port_wildcard;
- dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand;
- dst->has_client = src->has_client;
- dst->has_client_wildcard = src->has_client_wildcard;
- dst->modecfg = src->modecfg;
- dst->hostaccess = src->hostaccess;
- dst->sendcert = src->sendcert;
- dst->updown = src->updown;
- dst->host_port = src->host_port;
-
- /* if host sourceip is defined but no client is present
- * behind the host then set client to sourceip/32
- */
- if (addrbytesptr(&dst->host_srcip, NULL)
- && !isanyaddr(&dst->host_srcip)
- && !dst->has_natip
- && !dst->has_client)
- {
- err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client);
-
- if (ugh != NULL)
- plog("could not assign host sourceip to client subnet");
- else
- dst->has_client = TRUE;
- }
- return same_ca;
-}
-
-static bool
-check_connection_end(const whack_end_t *this, const whack_end_t *that
-, const whack_message_t *wm)
-{
- if (wm->addr_family != addrtypeof(&this->host_addr)
- || wm->addr_family != addrtypeof(&this->host_nexthop)
- || (this->has_client? wm->tunnel_addr_family : wm->addr_family)
- != subnettypeof(&this->client)
- || subnettypeof(&this->client) != subnettypeof(&that->client))
- {
- /* this should have been diagnosed by whack, so we need not be clear
- * !!! overloaded use of RC_CLASH
- */
- loglog(RC_CLASH, "address family inconsistency in connection");
- return FALSE;
- }
-
- if (isanyaddr(&that->host_addr))
- {
- /* other side is wildcard: we must check if other conditions met */
- if (isanyaddr(&this->host_addr))
- {
- loglog(RC_ORIENT, "connection must specify host IP address for our side");
- return FALSE;
- }
- }
-#ifdef VIRTUAL_IP
- if (this->virt && (!isanyaddr(&this->host_addr) || this->has_client))
- {
- loglog(RC_CLASH,
- "virtual IP must only be used with %%any and without client");
- return FALSE;
- }
-#endif
- return TRUE; /* happy */
-}
-
-struct connection *
-find_connection_by_reqid(uint32_t reqid)
-{
- struct connection *c;
-
- reqid &= ~3;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->spd.reqid == reqid)
- return c;
- }
-
- return NULL;
-}
-
-static uint32_t
-gen_reqid(void)
-{
- uint32_t start;
- static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;
-
- start = reqid;
- do {
- reqid += 4;
- if (reqid == 0)
- reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4;
- if (!find_connection_by_reqid(reqid))
- return reqid;
- } while (reqid != start);
-
- exit_log("unable to allocate reqid");
-}
-
-void
-add_connection(const whack_message_t *wm)
-{
- if (con_by_name(wm->name, FALSE) != NULL)
- {
- loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name);
- }
- else if (wm->right.protocol != wm->left.protocol)
- {
- /* this should haven been diagnosed by whack
- * !!! overloaded use of RC_CLASH
- */
- loglog(RC_CLASH, "the protocol must be the same for leftport and rightport");
- }
- else if (check_connection_end(&wm->right, &wm->left, wm)
- && check_connection_end(&wm->left, &wm->right, wm))
- {
- bool same_rightca, same_leftca;
- struct connection *c = alloc_thing(struct connection, "struct connection");
-
- c->name = wm->name;
-
- c->policy = wm->policy;
-
- if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp)
- loglog(RC_COMMENT
- , "ignoring --compress in \"%s\" because KLIPS is not configured to do IPCOMP"
- , c->name);
-
- if (wm->esp)
- {
- const char *ugh;
-
- DBG(DBG_CONTROL,
- DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL")
- )
- c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : "", &ugh);
-
- DBG(DBG_CRYPT|DBG_CONTROL,
- static char buf[256]="<NULL>";
-
- if (c->alg_info_esp)
- alg_info_snprint(buf, sizeof(buf)
- ,(struct alg_info *)c->alg_info_esp);
- DBG_log("esp string values: %s", buf);
- )
- if (c->alg_info_esp)
- {
- if (c->alg_info_esp->alg_info_cnt==0)
- loglog(RC_LOG_SERIOUS
- , "got 0 transforms for esp=\"%s\"", wm->esp);
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "esp string error: %s", ugh? ugh : "Unknown");
- }
- }
-
- if (wm->ike)
- {
- const char *ugh;
-
- DBG(DBG_CONTROL,
- DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL")
- )
- c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "", &ugh);
-
- DBG(DBG_CRYPT|DBG_CONTROL,
- static char buf[256]="<NULL>";
-
- if (c->alg_info_ike)
- alg_info_snprint(buf, sizeof(buf)
- , (struct alg_info *)c->alg_info_ike);
- DBG_log("ike string values: %s", buf);
- )
- if (c->alg_info_ike)
- {
- if (c->alg_info_ike->alg_info_cnt==0)
- loglog(RC_LOG_SERIOUS
- , "got 0 transforms for ike=\"%s\"", wm->ike);
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "ike string error: %s", ugh? ugh : "Unknown");
- }
- }
-
- c->sa_ike_life_seconds = wm->sa_ike_life_seconds;
- c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds;
- c->sa_rekey_margin = wm->sa_rekey_margin;
- c->sa_rekey_fuzz = wm->sa_rekey_fuzz;
- c->sa_keying_tries = wm->sa_keying_tries;
-
- /* RFC 3706 DPD */
- c->dpd_delay = wm->dpd_delay;
- c->dpd_timeout = wm->dpd_timeout;
- c->dpd_action = wm->dpd_action;
-
- c->addr_family = wm->addr_family;
- c->tunnel_addr_family = wm->tunnel_addr_family;
-
- c->requested_ca = NULL;
-
- same_leftca = extract_end(&c->spd.this, &wm->left, "left");
- same_rightca = extract_end(&c->spd.that, &wm->right, "right");
-
- if (same_rightca)
- c->spd.that.ca = c->spd.this.ca;
- else if (same_leftca)
- c->spd.this.ca = c->spd.that.ca;
-
- default_end(&c->spd.this, &c->spd.that.host_addr);
- default_end(&c->spd.that, &c->spd.this.host_addr);
-
- /* force any wildcard host IP address, any wildcard subnet
- * or any wildcard ID to that end
- */
- if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard
- || c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards)
- {
- struct end t = c->spd.this;
-
- c->spd.this = c->spd.that;
- c->spd.that = t;
- }
-
- c->spd.next = NULL;
- c->spd.reqid = gen_reqid();
-
- /* set internal fields */
- c->instance_serial = 0;
- c->ac_next = connections;
- connections = c;
- c->interface = NULL;
- c->spd.routing = RT_UNROUTED;
- c->newest_isakmp_sa = SOS_NOBODY;
- c->newest_ipsec_sa = SOS_NOBODY;
- c->spd.eroute_owner = SOS_NOBODY;
-
- if (c->policy & POLICY_GROUP)
- {
- c->kind = CK_GROUP;
- add_group(c);
- }
- else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy))
- || c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard
- || c->spd.that.has_id_wildcards)
- {
- /* Opportunistic or Road Warrior or wildcard client subnet
- * or wildcard ID */
- c->kind = CK_TEMPLATE;
- }
- else
- {
- c->kind = CK_PERMANENT;
- }
- set_policy_prio(c); /* must be after kind is set */
-
-#ifdef DEBUG
- c->extra_debugging = wm->debugging;
-#endif
-
- c->gw_info = NULL;
-
-#ifdef VIRTUAL_IP
- passert(!(wm->left.virt && wm->right.virt));
- if (wm->left.virt || wm->right.virt)
- {
- passert(isanyaddr(&c->spd.that.host_addr));
- c->spd.that.virt = create_virtual(c,
- wm->left.virt ? wm->left.virt : wm->right.virt);
- if (c->spd.that.virt)
- c->spd.that.has_client = TRUE;
- }
-#endif
-
- unshare_connection_strings(c);
- (void)orient(c);
- connect_to_host_pair(c);
-
- /* log all about this connection */
- plog("added connection description \"%s\"", c->name);
- DBG(DBG_CONTROL,
- char topo[CONNECTION_BUF];
-
- (void) format_connection(topo, sizeof(topo), c, &c->spd);
-
- DBG_log("%s", topo);
-
- /* Make sure that address families can be correctly inferred
- * from printed ends.
- */
- passert(c->addr_family == addrtypeof(&c->spd.this.host_addr)
- && c->addr_family == addrtypeof(&c->spd.this.host_nexthop)
- && (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family)
- == subnettypeof(&c->spd.this.client)
-
- && c->addr_family == addrtypeof(&c->spd.that.host_addr)
- && c->addr_family == addrtypeof(&c->spd.that.host_nexthop)
- && (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family)
- == subnettypeof(&c->spd.that.client));
-
- DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;"
- " rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s"
- , (unsigned long) c->sa_ike_life_seconds
- , (unsigned long) c->sa_ipsec_life_seconds
- , (unsigned long) c->sa_rekey_margin
- , (unsigned long) c->sa_rekey_fuzz
- , (unsigned long) c->sa_keying_tries
- , prettypolicy(c->policy));
- );
- }
-}
-
-/* Derive a template connection from a group connection and target.
- * Similar to instantiate(). Happens at whack --listen.
- * Returns name of new connection. May be NULL.
- * Caller is responsible for pfreeing.
- */
-char *
-add_group_instance(struct connection *group, const ip_subnet *target)
-{
- char namebuf[100]
- , targetbuf[SUBNETTOT_BUF];
- struct connection *t;
- char *name = NULL;
-
- passert(group->kind == CK_GROUP);
- passert(oriented(*group));
-
- /* manufacture a unique name for this template */
- subnettot(target, 0, targetbuf, sizeof(targetbuf));
- snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf);
-
- if (con_by_name(namebuf, FALSE) != NULL)
- {
- loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\""
- , namebuf);
- }
- else
- {
- t = clone_thing(*group, "group instance");
- t->name = namebuf;
- unshare_connection_strings(t);
- name = clone_str(t->name, "group instance name");
- t->spd.that.client = *target;
- t->policy &= ~(POLICY_GROUP | POLICY_GROUTED);
- t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy)
- ? CK_TEMPLATE : CK_INSTANCE;
-
- /* reset log file info */
- t->log_file_name = NULL;
- t->log_file = NULL;
- t->log_file_err = FALSE;
-
- t->spd.reqid = gen_reqid();
-
-#ifdef VIRTUAL_IP
- if (t->spd.that.virt)
- {
- DBG_log("virtual_ip not supported in group instance");
- t->spd.that.virt = NULL;
- }
-#endif
-
- /* add to connections list */
- t->ac_next = connections;
- connections = t;
-
- /* same host_pair as parent: stick after parent on list */
- group->hp_next = t;
-
- /* route if group is routed */
- if (group->policy & POLICY_GROUTED)
- {
- if (!trap_connection(t))
- whack_log(RC_ROUTE, "could not route");
- }
- }
- return name;
-}
-
-/* an old target has disappeared for a group: delete instance */
-void
-remove_group_instance(const struct connection *group USED_BY_DEBUG
-, const char *name)
-{
- passert(group->kind == CK_GROUP);
- passert(oriented(*group));
-
- delete_connections_by_name(name, FALSE);
-}
-
-/* Common part of instantiating a Road Warrior or Opportunistic connection.
- * his_id can be used to carry over an ID discovered in Phase 1.
- * It must not disagree with the one in c, but if that is unspecified,
- * the new connection will use his_id.
- * If his_id is NULL, and c.that.id is uninstantiated (ID_NONE), the
- * new connection will continue to have an uninstantiated that.id.
- * Note: instantiation does not affect port numbers.
- *
- * Note that instantiate can only deal with a single SPD/eroute.
- */
-static struct connection *
-instantiate(struct connection *c, const ip_address *him
-#ifdef NAT_TRAVERSAL
-, u_int16_t his_port
-#endif
-, const struct id *his_id)
-{
- struct connection *d;
- int wildcards;
-
- passert(c->kind == CK_TEMPLATE);
- passert(c->spd.next == NULL);
-
- c->instance_serial++;
- d = clone_thing(*c, "temporary connection");
- if (his_id != NULL)
- {
- passert(match_id(his_id, &d->spd.that.id, &wildcards));
- d->spd.that.id = *his_id;
- d->spd.that.has_id_wildcards = FALSE;
- }
- unshare_connection_strings(d);
- unshare_ietfAttrList(&d->spd.this.groups);
- unshare_ietfAttrList(&d->spd.that.groups);
- d->kind = CK_INSTANCE;
-
- passert(oriented(*d));
- d->spd.that.host_addr = *him;
- setportof(htons(c->spd.that.port), &d->spd.that.host_addr);
-#ifdef NAT_TRAVERSAL
- if (his_port) d->spd.that.host_port = his_port;
-#endif
- default_end(&d->spd.that, &d->spd.this.host_addr);
-
- /* We cannot guess what our next_hop should be, but if it was
- * explicitly specified as 0.0.0.0, we set it to be him.
- * (whack will not allow nexthop to be elided in RW case.)
- */
- default_end(&d->spd.this, &d->spd.that.host_addr);
- d->spd.next = NULL;
- d->spd.reqid = gen_reqid();
-
- /* set internal fields */
- d->ac_next = connections;
- connections = d;
- d->spd.routing = RT_UNROUTED;
- d->newest_isakmp_sa = SOS_NOBODY;
- d->newest_ipsec_sa = SOS_NOBODY;
- d->spd.eroute_owner = SOS_NOBODY;
-
- /* reset log file info */
- d->log_file_name = NULL;
- d->log_file = NULL;
- d->log_file_err = FALSE;
-
- connect_to_host_pair(d);
-
- return d;
-}
-
-struct connection *
-rw_instantiate(struct connection *c
-, const ip_address *him
-#ifdef NAT_TRAVERSAL
-, u_int16_t his_port
-#endif
-#ifdef VIRTUAL_IP
-, const ip_subnet *his_net
-#endif
-, const struct id *his_id)
-{
-#ifdef NAT_TRAVERSAL
- struct connection *d = instantiate(c, him, his_port, his_id);
-#else
- struct connection *d = instantiate(c, him, his_id);
-#endif
-
-#ifdef VIRTUAL_IP
- if (d && his_net && is_virtual_connection(c))
- {
- d->spd.that.client = *his_net;
- d->spd.that.virt = NULL;
- if (subnetishost(his_net) && addrinsubnet(him, his_net))
- d->spd.that.has_client = FALSE;
- }
-#endif
-
- if (d->policy & POLICY_OPPO)
- {
- /* This must be before we know the client addresses.
- * Fill in one that is impossible. This prevents anyone else from
- * trying to use this connection to get to a particular client
- */
- d->spd.that.client = *aftoinfo(subnettypeof(&d->spd.that.client))->none;
- }
- DBG(DBG_CONTROL
- , DBG_log("instantiated \"%s\" for %s" , d->name, ip_str(him)));
- return d;
-}
-
-struct connection *
-oppo_instantiate(struct connection *c
-, const ip_address *him
-, const struct id *his_id
-, struct gw_info *gw
-, const ip_address *our_client USED_BY_DEBUG
-, const ip_address *peer_client)
-{
-#ifdef NAT_TRAVERSAL
- struct connection *d = instantiate(c, him, 0, his_id);
-#else
- struct connection *d = instantiate(c, him, his_id);
-#endif
-
- passert(d->spd.next == NULL);
-
- /* fill in our client side */
- if (d->spd.this.has_client)
- {
- /* there was a client in the abstract connection
- * so we demand that the required client is within that subnet.
- */
- passert(addrinsubnet(our_client, &d->spd.this.client));
- happy(addrtosubnet(our_client, &d->spd.this.client));
- /* opportunistic connections do not use port selectors */
- setportof(0, &d->spd.this.client.addr);
- }
- else
- {
- /* there was no client in the abstract connection
- * so we demand that the required client be the host
- */
- passert(sameaddr(our_client, &d->spd.this.host_addr));
- }
-
- /* fill in peer's client side.
- * If the client is the peer, excise the client from the connection.
- */
- passert((d->policy & POLICY_OPPO)
- && addrinsubnet(peer_client, &d->spd.that.client));
- happy(addrtosubnet(peer_client, &d->spd.that.client));
- /* opportunistic connections do not use port selectors */
- setportof(0, &d->spd.that.client.addr);
-
- if (sameaddr(peer_client, &d->spd.that.host_addr))
- d->spd.that.has_client = FALSE;
-
- passert(d->gw_info == NULL);
- gw_addref(gw);
- d->gw_info = gw;
-
- /* Adjust routing if something is eclipsing c.
- * It must be a %hold for us (hard to passert this).
- * If there was another instance eclipsing, we'd be using it.
- */
- if (c->spd.routing == RT_ROUTED_ECLIPSED)
- d->spd.routing = RT_ROUTED_PROSPECTIVE;
-
- /* Remember if the template is routed:
- * if so, this instance applies for initiation
- * even if it is created for responding.
- */
- if (routed(c->spd.routing))
- d->instance_initiation_ok = TRUE;
-
- DBG(DBG_CONTROL,
- char topo[CONNECTION_BUF];
-
- (void) format_connection(topo, sizeof(topo), d, &d->spd);
- DBG_log("instantiated \"%s\": %s", d->name, topo);
- );
- return d;
-}
-
-/* priority formatting */
-void
-fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
-{
- if (pp == BOTTOM_PRIO)
- snprintf(buf, POLICY_PRIO_BUF, "0");
- else
- snprintf(buf, POLICY_PRIO_BUF, "%lu,%lu"
- , pp>>16, (pp & ~(~(policy_prio_t)0 << 16)) >> 8);
-}
-
-/* Format any information needed to identify an instance of a connection.
- * Fills any needed information into buf which MUST be big enough.
- * Road Warrior: peer's IP address
- * Opportunistic: [" " myclient "==="] " ..." peer ["===" hisclient] '\0'
- */
-static size_t
-fmt_client(const ip_subnet *client, const ip_address *gw, const char *prefix, char buf[ADDRTOT_BUF])
-{
- if (subnetisaddr(client, gw))
- {
- buf[0] = '\0'; /* compact denotation for "self" */
- }
- else
- {
- char *ap;
-
- strcpy(buf, prefix);
- ap = buf + strlen(prefix);
- if (subnetisnone(client))
- strcpy(ap, "?"); /* unknown */
- else
- subnettot(client, 0, ap, SUBNETTOT_BUF);
- }
- return strlen(buf);
-}
-
-void
-fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
-{
- char *p = buf;
-
- *p = '\0';
-
- if (c->kind == CK_INSTANCE)
- {
- if (c->instance_serial != 0)
- {
- snprintf(p, CONN_INST_BUF, "[%lu]", c->instance_serial);
- p += strlen(p);
- }
-
- if (c->policy & POLICY_OPPO)
- {
- size_t w = fmt_client(&c->spd.this.client, &c->spd.this.host_addr, " ", p);
-
- p += w;
-
- strcpy(p, w == 0? " ..." : "=== ...");
- p += strlen(p);
-
- addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
- p += strlen(p);
-
- (void) fmt_client(&c->spd.that.client, &c->spd.that.host_addr, "===", p);
- }
- else
- {
- *p++ = ' ';
- addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
-#ifdef NAT_TRAVERSAL
- if (c->spd.that.host_port != pluto_port)
- {
- p += strlen(p);
- sprintf(p, ":%d", c->spd.that.host_port);
- }
-#endif
- }
- }
-}
-
-/* Find an existing connection for a trapped outbound packet.
- * This is attempted before we bother with gateway discovery.
- * + this connection is routed or instance_of_routed_template
- * (i.e. approved for on-demand)
- * + this subnet contains our_client (or we are our_client)
- * + that subnet contains peer_client (or peer is peer_client)
- * + don't care about Phase 1 IDs (we don't know)
- * Note: result may still need to be instantiated.
- * The winner has the highest policy priority.
- *
- * If there are several with that priority, we give preference to
- * the first one that is an instance.
- *
- * See also build_outgoing_opportunistic_connection.
- */
-struct connection *
-find_connection_for_clients(struct spd_route **srp,
- const ip_address *our_client,
- const ip_address *peer_client,
- int transport_proto)
-{
- struct connection *c = connections, *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- struct spd_route *sr;
- struct spd_route *best_sr = NULL;
- int our_port = ntohs(portof(our_client));
- int peer_port = ntohs(portof(peer_client));
-
- passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
-#ifdef DEBUG
- if (DBGP(DBG_CONTROL))
- {
- char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
- addrtot(our_client, 0, ocb, sizeof(ocb));
- addrtot(peer_client, 0, pcb, sizeof(pcb));
- DBG_log("find_connection: "
- "looking for policy for connection: %s:%d/%d -> %s:%d/%d"
- , ocb, transport_proto, our_port, pcb, transport_proto, peer_port);
- }
-#endif /* DEBUG */
-
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->kind == CK_GROUP)
- continue;
-
- for (sr = &c->spd; best!=c && sr; sr = sr->next)
- {
- if ((routed(sr->routing) || c->instance_initiation_ok)
- && addrinsubnet(our_client, &sr->this.client)
- && addrinsubnet(peer_client, &sr->that.client)
- && addrinsubnet(peer_client, &sr->that.client)
- && (!sr->this.protocol || transport_proto == sr->this.protocol)
- && (!sr->this.port || our_port == sr->this.port)
- && (!sr->that.port || peer_port == sr->that.port))
- {
- char cib[CONN_INST_BUF];
- char cib2[CONN_INST_BUF];
-
- policy_prio_t prio = 8 * (c->prio + (c->kind == CK_INSTANCE))
- + 2 * (sr->this.port == our_port)
- + 2 * (sr->that.port == peer_port)
- + (sr->this.protocol == transport_proto);
-
-#ifdef DEBUG
- if (DBGP(DBG_CONTROL|DBG_CONTROLMORE))
- {
- char c_ocb[SUBNETTOT_BUF], c_pcb[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, c_ocb, sizeof(c_ocb));
- subnettot(&c->spd.that.client, 0, c_pcb, sizeof(c_pcb));
- DBG_log("find_connection: conn \"%s\"%s has compatible peers: %s->%s [pri: %ld]"
- , c->name
- , (fmt_conn_instance(c, cib), cib)
- , c_ocb, c_pcb, prio);
- }
-#endif /* DEBUG */
-
- if (best == NULL)
- {
- best = c;
- best_sr = sr;
- best_prio = prio;
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log("find_connection: "
- "comparing best \"%s\"%s [pri:%ld]{%p} (child %s) to \"%s\"%s [pri:%ld]{%p} (child %s)"
- , best->name
- , (fmt_conn_instance(best, cib), cib)
- , best_prio
- , best
- , (best->policy_next ? best->policy_next->name : "none")
- , c->name
- , (fmt_conn_instance(c, cib2), cib2)
- , prio
- , c
- , (c->policy_next ? c->policy_next->name : "none")));
-
- if (prio > best_prio)
- {
- best = c;
- best_sr = sr;
- best_prio = prio;
- }
- }
- }
- }
-
- if (best!= NULL && NEVER_NEGOTIATE(best->policy))
- best = NULL;
-
- if (srp != NULL && best != NULL)
- *srp = best_sr;
-
-#ifdef DEBUG
- if (DBGP(DBG_CONTROL))
- {
- if (best)
- {
- char cib[CONN_INST_BUF];
- DBG_log("find_connection: concluding with \"%s\"%s [pri:%ld]{%p} kind=%s"
- , best->name
- , (fmt_conn_instance(best, cib), cib)
- , best_prio
- , best
- , enum_name(&connection_kind_names, best->kind));
- } else {
- DBG_log("find_connection: concluding with empty");
- }
- }
-#endif /* DEBUG */
-
- return best;
-}
-
-/* Find and instantiate a connection for an outgoing Opportunistic connection.
- * We've already discovered its gateway.
- * We look for a the connection such that:
- * + this is one of our interfaces
- * + this subnet contains our_client (or we are our_client)
- * (we will specialize the client). We prefer the smallest such subnet.
- * + that subnet contains peer_clent (we will specialize the client).
- * We prefer the smallest such subnet.
- * + is opportunistic
- * + that peer is NO_IP
- * + don't care about Phase 1 IDs (probably should be default)
- * We could look for a connection that already had the desired peer
- * (rather than NO_IP) specified, but it doesn't seem worth the
- * bother.
- *
- * We look for the routed policy applying to the narrowest subnets.
- * We only succeed if we find such a policy AND it is satisfactory.
- *
- * The body of the inner loop is a lot like that in
- * find_connection_for_clients. In this case, we know the gateways
- * that we need to instantiate an opportunistic connection.
- */
-struct connection *
-build_outgoing_opportunistic_connection(struct gw_info *gw
- ,const ip_address *our_client
- ,const ip_address *peer_client)
-{
- struct iface *p;
- struct connection *best = NULL;
- struct spd_route *sr, *bestsr;
- char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
- addrtot(our_client, 0, ocb, sizeof(ocb));
- addrtot(peer_client, 0, pcb, sizeof(pcb));
-
- passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
-
- /* We don't know his ID yet, so gw id must be an ipaddr */
- passert(gw->key != NULL);
- passert(id_is_ipaddr(&gw->gw_id));
-
- /* for each of our addresses... */
- for (p = interfaces; p != NULL; p = p->next)
- {
- /* go through those connections with our address and NO_IP as hosts
- * We cannot know what port the peer would use, so we assume
- * that it is pluto_port (makes debugging easier).
- */
- struct connection *c = find_host_pair_connections(&p->addr
- , pluto_port, (ip_address *)NULL, pluto_port);
-
- for (; c != NULL; c = c->hp_next)
- {
- DBG(DBG_OPPO,
- DBG_log("checking %s", c->name));
- if (c->kind == CK_GROUP)
- {
- continue;
- }
-
- for (sr = &c->spd; best!=c && sr; sr = sr->next)
- {
- if (routed(sr->routing)
- && addrinsubnet(our_client, &sr->this.client)
- && addrinsubnet(peer_client, &sr->that.client))
- {
- if (best == NULL)
- {
- best = c;
- break;
- }
-
- DBG(DBG_OPPO,
- DBG_log("comparing best %s to %s"
- , best->name, c->name));
-
- for (bestsr = &best->spd; best!=c && bestsr; bestsr=bestsr->next)
- {
- if (!subnetinsubnet(&bestsr->this.client, &sr->this.client)
- || (samesubnet(&bestsr->this.client, &sr->this.client)
- && !subnetinsubnet(&bestsr->that.client
- , &sr->that.client)))
- {
- best = c;
- }
- }
- }
- }
- }
- }
-
- if (best == NULL
- || NEVER_NEGOTIATE(best->policy)
- || (best->policy & POLICY_OPPO) == LEMPTY
- || best->kind != CK_TEMPLATE)
- return NULL;
- else
- return oppo_instantiate(best, &gw->gw_id.ip_addr, NULL, gw
- , our_client, peer_client);
-}
-
-bool
-orient(struct connection *c)
-{
- struct spd_route *sr;
-
- if (!oriented(*c))
- {
- struct iface *p;
-
- for (sr = &c->spd; sr; sr = sr->next)
- {
- /* Note: this loop does not stop when it finds a match:
- * it continues checking to catch any ambiguity.
- */
- for (p = interfaces; p != NULL; p = p->next)
- {
-#ifdef NAT_TRAVERSAL
- if (p->ike_float) continue;
-#endif
- for (;;)
- {
- /* check if this interface matches this end */
- if (sameaddr(&sr->this.host_addr, &p->addr)
- && (!no_klips || sr->this.host_port == pluto_port))
- {
- if (oriented(*c))
- {
- if (c->interface == p)
- loglog(RC_LOG_SERIOUS
- , "both sides of \"%s\" are our interface %s!"
- , c->name, p->rname);
- else
- loglog(RC_LOG_SERIOUS, "two interfaces match \"%s\" (%s, %s)"
- , c->name, c->interface->rname, p->rname);
- c->interface = NULL; /* withdraw orientation */
- return FALSE;
- }
- c->interface = p;
- }
-
- /* done with this interface if it doesn't match that end */
- if (!(sameaddr(&sr->that.host_addr, &p->addr)
- && (!no_klips || sr->that.host_port == pluto_port)))
- break;
-
- /* swap ends and try again.
- * It is a little tricky to see that this loop will stop.
- * Only continue if the far side matches.
- * If both sides match, there is an error-out.
- */
- {
- struct end t = sr->this;
-
- sr->this = sr->that;
- sr->that = t;
- }
- }
- }
- }
- }
- return oriented(*c);
-}
-
-void
-initiate_connection(const char *name, int whackfd)
-{
- struct connection *c = con_by_name(name, TRUE);
-
- if (c != NULL)
- {
- set_cur_connection(c);
- if (!oriented(*c))
- {
- loglog(RC_ORIENT, "we have no ipsecN interface for either end of this connection");
- }
- else if (NEVER_NEGOTIATE(c->policy))
- {
- loglog(RC_INITSHUNT
- , "cannot initiate an authby=never connection");
- }
- else if (c->kind != CK_PERMANENT)
- {
- if (isanyaddr(&c->spd.that.host_addr))
- loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address");
- else
- loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards");
- }
- else
- {
- /* We will only request an IPsec SA if policy isn't empty
- * (ignoring Main Mode items).
- * This is a fudge, but not yet important.
- * If we are to proceed asynchronously, whackfd will be NULL_FD.
- */
- c->policy |= POLICY_UP;
- /* do we have to prompt for a PIN code? */
- if (c->spd.this.sc != NULL && !c->spd.this.sc->valid && whackfd != NULL_FD)
- scx_get_pin(c->spd.this.sc, whackfd);
-
- if (c->spd.this.sc != NULL && !c->spd.this.sc->valid)
- {
- loglog(RC_NOVALIDPIN, "cannot initiate connection without valid PIN");
- }
- else
- {
- ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY);
- whackfd = NULL_FD; /* protect from close */
- }
- }
- reset_cur_connection();
- }
- close_any(whackfd);
-}
-
-/* (Possibly) Opportunistic Initiation:
- * Knowing clients (single IP addresses), try to build an tunnel.
- * This may involve discovering a gateway and instantiating an
- * Opportunistic connection. Called when a packet is caught by
- * a %trap, or when whack --oppohere --oppothere is used.
- * It may turn out that an existing or non-opporunistic connnection
- * can handle the traffic.
- *
- * Most of the code will be restarted if an ADNS request is made
- * to discover the gateway. The only difference between the first
- * and second entry is whether gateways_from_dns is NULL or not.
- * initiate_opportunistic: initial entrypoint
- * continue_oppo: where we pickup when ADNS result arrives
- * initiate_opportunistic_body: main body shared by above routines
- * cannot_oppo: a helper function to log a diagnostic
- * This structure repeats a lot of code when the ADNS result arrives.
- * This seems like a waste, but anything learned the first time through
- * may no longer be true!
- *
- * After the first IKE message is sent, the regular state machinery
- * carries negotiation forward.
- */
-
-enum find_oppo_step {
- fos_start,
- fos_myid_ip_txt,
- fos_myid_hostname_txt,
- fos_myid_ip_key,
- fos_myid_hostname_key,
- fos_our_client,
- fos_our_txt,
-#ifdef USE_KEYRR
- fos_our_key,
-#endif /* USE_KEYRR */
- fos_his_client,
- fos_done
-};
-
-#ifdef DEBUG
-static const char *const oppo_step_name[] = {
- "fos_start",
- "fos_myid_ip_txt",
- "fos_myid_hostname_txt",
- "fos_myid_ip_key",
- "fos_myid_hostname_key",
- "fos_our_client",
- "fos_our_txt",
-#ifdef USE_KEYRR
- "fos_our_key",
-#endif /* USE_KEYRR */
- "fos_his_client",
- "fos_done"
-};
-#endif /* DEBUG */
-
-struct find_oppo_bundle {
- enum find_oppo_step step;
- err_t want;
- bool failure_ok; /* if true, continue_oppo should not die on DNS failure */
- ip_address our_client; /* not pointer! */
- ip_address peer_client;
- int transport_proto;
- bool held;
- policy_prio_t policy_prio;
- ipsec_spi_t failure_shunt; /* in host order! 0 for delete. */
- int whackfd;
-};
-
-struct find_oppo_continuation {
- struct adns_continuation ac; /* common prefix */
- struct find_oppo_bundle b;
-};
-
-static void
-cannot_oppo(struct connection *c
- , struct find_oppo_bundle *b
- , err_t ugh)
-{
- char pcb[ADDRTOT_BUF];
- char ocb[ADDRTOT_BUF];
-
- addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
- addrtot(&b->our_client, 0, ocb, sizeof(ocb));
-
- DBG(DBG_DNS | DBG_OPPO, DBG_log("Can't Opportunistically initiate for %s to %s: %s"
- , ocb, pcb, ugh));
-
- whack_log(RC_OPPOFAILURE
- , "Can't Opportunistically initiate for %s to %s: %s"
- , ocb, pcb, ugh);
-
- if (c != NULL && c->policy_next != NULL)
- {
- /* there is some policy that comes afterwards */
- struct spd_route *shunt_spd;
- struct connection *nc = c->policy_next;
- struct state *st;
-
- passert(c->kind == CK_TEMPLATE);
- passert(c->policy_next->kind == CK_PERMANENT);
-
- DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt"
- , ocb, pcb, c->policy_next->name));
-
- /*
- * okay, here we need add to the "next" policy, which is ought
- * to be an instance.
- * We will add another entry to the spd_route list for the specific
- * situation that we have.
- */
-
- shunt_spd = clone_thing(nc->spd, "shunt eroute policy");
-
- shunt_spd->next = nc->spd.next;
- nc->spd.next = shunt_spd;
-
- happy(addrtosubnet(&b->peer_client, &shunt_spd->that.client));
-
- if (sameaddr(&b->peer_client, &shunt_spd->that.host_addr))
- shunt_spd->that.has_client = FALSE;
-
- /*
- * override the tunnel destination with the one from the secondaried
- * policy
- */
- shunt_spd->that.host_addr = nc->spd.that.host_addr;
-
- /* now, lookup the state, and poke it up.
- */
-
- st = state_with_serialno(nc->newest_ipsec_sa);
-
- /* XXX what to do if the IPSEC SA has died? */
- passert(st != NULL);
-
- /* link the new connection instance to the state's list of
- * connections
- */
-
- DBG(DBG_OPPO, DBG_log("installing state: %ld for %s to %s"
- , nc->newest_ipsec_sa
- , ocb, pcb));
-
-#ifdef DEBUG
- if (DBGP(DBG_OPPO | DBG_CONTROLMORE))
- {
- char state_buf[LOG_WIDTH];
- char state_buf2[LOG_WIDTH];
- time_t n = now();
-
- fmt_state(FALSE, st, n
- , state_buf, sizeof(state_buf)
- , state_buf2, sizeof(state_buf2));
- DBG_log("cannot_oppo, failure SA1: %s", state_buf);
- DBG_log("cannot_oppo, failure SA2: %s", state_buf2);
- }
-#endif /* DEBUG */
-
- if (!route_and_eroute(c, shunt_spd, st))
- {
- whack_log(RC_OPPOFAILURE
- , "failed to instantiate shunt policy %s for %s to %s"
- , c->name
- , ocb, pcb);
- }
- return;
- }
-
-#ifdef KLIPS
- if (b->held)
- {
- /* Replace HOLD with b->failure_shunt.
- * If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
- */
- if (b->failure_shunt == 0)
- {
- DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass"
- , ocb, pcb));
- }
-
- (void) replace_bare_shunt(&b->our_client, &b->peer_client
- , b->policy_prio
- , b->failure_shunt
- , b->failure_shunt != 0
- , b->transport_proto
- , ugh);
- }
-#endif
-}
-
-static void initiate_opportunistic_body(struct find_oppo_bundle *b
- , struct adns_continuation *ac, err_t ac_ugh); /* forward */
-
-void
-initiate_opportunistic(const ip_address *our_client
-, const ip_address *peer_client
-, int transport_proto
-, bool held
-, int whackfd)
-{
- struct find_oppo_bundle b;
-
- b.want = (whackfd == NULL_FD ? "whack" : "acquire");
- b.failure_ok = FALSE;
- b.our_client = *our_client;
- b.peer_client = *peer_client;
- b.transport_proto = transport_proto;
- b.held = held;
- b.policy_prio = BOTTOM_PRIO;
- b.failure_shunt = 0;
- b.whackfd = whackfd;
- b.step = fos_start;
- initiate_opportunistic_body(&b, NULL, NULL);
-}
-
-static void
-continue_oppo(struct adns_continuation *acr, err_t ugh)
-{
- struct find_oppo_continuation *cr = (void *)acr; /* inherit, damn you! */
- struct connection *c;
- bool was_held = cr->b.held;
- int whackfd = cr->b.whackfd;
-
- /* note: cr->id has no resources; cr->sgw_id is id_none:
- * neither need freeing.
- */
- whack_log_fd = whackfd;
-
-#ifdef KLIPS
- /* Discover and record whether %hold has gone away.
- * This could have happened while we were awaiting DNS.
- * We must check BEFORE any call to cannot_oppo.
- */
- if (was_held)
- cr->b.held = has_bare_hold(&cr->b.our_client, &cr->b.peer_client
- , cr->b.transport_proto);
-#endif
-
-#ifdef DEBUG
- /* if we're going to ignore the error, at least note it in debugging log */
- if (cr->b.failure_ok && ugh != NULL)
- {
- DBG(DBG_CONTROL | DBG_DNS,
- {
- char ocb[ADDRTOT_BUF];
- char pcb[ADDRTOT_BUF];
-
- addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
- addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
- DBG_log("continuing from failed DNS lookup for %s, %s to %s: %s"
- , cr->b.want, ocb, pcb, ugh);
- });
- }
-#endif
-
- if (!cr->b.failure_ok && ugh != NULL)
- {
- c = find_connection_for_clients(NULL, &cr->b.our_client, &cr->b.peer_client
- , cr->b.transport_proto);
- cannot_oppo(c, &cr->b
- , builddiag("%s: %s", cr->b.want, ugh));
- }
- else if (was_held && !cr->b.held)
- {
- /* was_held indicates we were started due to a %trap firing
- * (as opposed to a "whack --oppohere --oppothere").
- * Since the %hold has gone, we can assume that somebody else
- * has beaten us to the punch. We can go home. But lets log it.
- */
- char ocb[ADDRTOT_BUF];
- char pcb[ADDRTOT_BUF];
-
- addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
- addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
-
- loglog(RC_COMMENT
- , "%%hold otherwise handled during DNS lookup for Opportunistic Initiation for %s to %s"
- , ocb, pcb);
- }
- else
- {
- initiate_opportunistic_body(&cr->b, &cr->ac, ugh);
- whackfd = NULL_FD; /* was handed off */
- }
-
- whack_log_fd = NULL_FD;
- close_any(whackfd);
-}
-
-#ifdef USE_KEYRR
-static err_t
-check_key_recs(enum myid_state try_state
-, const struct connection *c
-, struct adns_continuation *ac)
-{
- /* Check if KEY lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- enum myid_state old_myid_state = myid_state;
- const struct RSA_private_key *our_RSA_pri;
- err_t ugh = NULL;
-
- myid_state = try_state;
-
- if (old_myid_state != myid_state
- && old_myid_state == MYID_SPECIFIED)
- {
- ugh = "%myid was specified while we were guessing";
- }
- else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- pubkey_list_t *kr;
-
- ugh = "no KEY RR found for us";
- for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
- {
- ugh = "all our KEY RRs have the wrong public key";
- if (kr->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- if (ugh != NULL)
- myid_state = old_myid_state;
- return ugh;
-}
-#endif /* USE_KEYRR */
-
-static err_t
-check_txt_recs(enum myid_state try_state
-, const struct connection *c
-, struct adns_continuation *ac)
-{
- /* Check if TXT lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- enum myid_state old_myid_state = myid_state;
- const struct RSA_private_key *our_RSA_pri;
- err_t ugh = NULL;
-
- myid_state = try_state;
-
- if (old_myid_state != myid_state
- && old_myid_state == MYID_SPECIFIED)
- {
- ugh = "%myid was specified while we were guessing";
- }
- else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- struct gw_info *gwp;
-
- ugh = "no TXT RR found for us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- ugh = "all our TXT RRs have the wrong public key";
- if (gwp->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- if (ugh != NULL)
- myid_state = old_myid_state;
- return ugh;
-}
-
-
-/* note: gateways_from_dns must be NULL iff this is the first call */
-static void
-initiate_opportunistic_body(struct find_oppo_bundle *b
-, struct adns_continuation *ac
-, err_t ac_ugh)
-{
- struct connection *c;
- struct spd_route *sr;
-
- /* What connection shall we use?
- * First try for one that explicitly handles the clients.
- */
- DBG(DBG_CONTROL,
- {
- char ours[ADDRTOT_BUF];
- char his[ADDRTOT_BUF];
- int ourport;
- int hisport;
-
- addrtot(&b->our_client, 0, ours, sizeof(ours));
- addrtot(&b->peer_client, 0, his, sizeof(his));
- ourport = ntohs(portof(&b->our_client));
- hisport = ntohs(portof(&b->peer_client));
- DBG_log("initiate on demand from %s:%d to %s:%d proto=%d state: %s because: %s"
- , ours, ourport, his, hisport, b->transport_proto
- , oppo_step_name[b->step], b->want);
- });
- if (isanyaddr(&b->our_client) || isanyaddr(&b->peer_client))
- {
- cannot_oppo(NULL, b, "impossible IP address");
- }
- else if ((c = find_connection_for_clients(&sr
- , &b->our_client
- , &b->peer_client
- , b->transport_proto)) == NULL)
- {
- /* No connection explicitly handles the clients and there
- * are no Opportunistic connections -- whine and give up.
- * The failure policy cannot be gotten from a connection; we pick %pass.
- */
- cannot_oppo(NULL, b, "no routed Opportunistic template covers this pair");
- }
- else if (c->kind != CK_TEMPLATE)
- {
- /* We've found a connection that can serve.
- * Do we have to initiate it?
- * Not if there is currently an IPSEC SA.
- * But if there is an IPSEC SA, then KLIPS would not
- * have generated the acquire. So we assume that there isn't one.
- * This may be redundant if a non-opportunistic
- * negotiation is already being attempted.
- */
-
- /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
-
- if(c->kind == CK_INSTANCE)
- {
- char cib[CONN_INST_BUF];
- /* there is already an instance being negotiated, no nothing */
- DBG(DBG_CONTROL, DBG_log("found existing instance \"%s\"%s, rekeying it"
- , c->name
- , (fmt_conn_instance(c, cib), cib)));
- /* XXX-mcr - return; */
- }
-
- /* otherwise, there is some kind of static conn that can handle
- * this connection, so we initiate it */
-
-#ifdef KLIPS
- if (b->held)
- {
- /* what should we do on failure? */
- (void) assign_hold(c, sr, b->transport_proto, &b->our_client, &b->peer_client);
- }
-#endif
- ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
- b->whackfd = NULL_FD; /* protect from close */
- }
- else
- {
- /* We are handling an opportunistic situation.
- * This involves several DNS lookup steps that require suspension.
- * Note: many facts might change while we're suspended.
- * Here be dragons.
- *
- * The first chunk of code handles the result of the previous
- * DNS query (if any). It also selects the kind of the next step.
- * The second chunk initiates the next DNS query (if any).
- */
- enum find_oppo_step next_step;
- err_t ugh = ac_ugh;
- char mycredentialstr[BUF_LEN];
- char cib[CONN_INST_BUF];
-
- DBG(DBG_CONTROL, DBG_log("creating new instance from \"%s\"%s"
- , c->name
- , (fmt_conn_instance(c, cib), cib)));
-
-
- idtoa(&sr->this.id, mycredentialstr, sizeof(mycredentialstr));
-
- passert(c->policy & POLICY_OPPO); /* can't initiate Road Warrior connections */
-
- /* handle any DNS answer; select next step */
-
- switch (b->step)
- {
- case fos_start:
- /* just starting out: select first query step */
- next_step = fos_myid_ip_txt;
- break;
-
- case fos_myid_ip_txt: /* TXT for our default IP address as %myid */
- ugh = check_txt_recs(MYID_IP, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our IP (%s:TXT) as identity: %s"
- , myid_str[MYID_IP]
- , ugh));
- if (!logged_myid_ip_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our IP (%s:TXT) as identity: %s"
- , myid_str[MYID_IP]
- , ugh);
- logged_myid_ip_txt_warning = TRUE;
- }
-
- next_step = fos_myid_hostname_txt;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_ip_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our IP (%s:TXT) as identity!"
- , myid_str[MYID_IP]);
- logged_myid_ip_txt_warning = TRUE;
- }
-
- next_step = fos_our_client;
- }
- break;
-
- case fos_myid_hostname_txt: /* TXT for our hostname as %myid */
- ugh = check_txt_recs(MYID_HOSTNAME, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our hostname as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:TXT) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh));
- if (!logged_myid_fqdn_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our hostname (%s:TXT) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh);
- logged_myid_fqdn_txt_warning = TRUE;
- }
-#ifdef USE_KEYRR
- next_step = fos_myid_ip_key;
- ugh = NULL; /* failure can be recovered from */
-#endif
- }
- else
- {
- /* we can use our hostname as OE identity for initiation */
- if (!logged_myid_fqdn_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our hostname (%s:TXT) as identity!"
- , myid_str[MYID_HOSTNAME]);
- logged_myid_fqdn_txt_warning = TRUE;
- }
- next_step = fos_our_client;
- }
- break;
-
-#ifdef USE_KEYRR
- case fos_myid_ip_key: /* KEY for our default IP address as %myid */
- ugh = check_key_recs(MYID_IP, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our IP (%s:KEY) as identity: %s"
- , myid_str[MYID_IP]
- , ugh));
- if (!logged_myid_ip_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our IP (%s:KEY) as identity: %s"
- , myid_str[MYID_IP]
- , ugh);
- logged_myid_ip_key_warning = TRUE;
- }
-
- next_step = fos_myid_hostname_key;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_ip_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our IP (%s:KEY) as identity!"
- , myid_str[MYID_IP]);
- logged_myid_ip_key_warning = TRUE;
- }
- next_step = fos_our_client;
- }
- break;
-
- case fos_myid_hostname_key: /* KEY for our hostname as %myid */
- ugh = check_key_recs(MYID_HOSTNAME, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:KEY) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh));
- if (!logged_myid_fqdn_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our hostname (%s:KEY) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh);
- logged_myid_fqdn_key_warning = TRUE;
- }
-
- next_step = fos_myid_hostname_key;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_fqdn_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our hostname (%s:KEY) as identity!"
- , myid_str[MYID_HOSTNAME]);
- logged_myid_fqdn_key_warning = TRUE;
- }
- next_step = fos_our_client;
- }
- break;
-#endif
-
- case fos_our_client: /* TXT for our client */
- {
- /* Our client is not us: we must check the TXT records.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
-
- next_step = fos_his_client; /* normal situation */
-
- passert(sr != NULL);
-
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (sameaddr(&sr->this.host_addr, &b->our_client))
- {
- /* this wasn't true when we started -- bail */
- ugh = "our IP address changed underfoot";
- }
- else if (!same_id(&ac->sgw_id, &sr->this.id))
- {
- /* this wasn't true when we started -- bail */
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in quick_inI1_outR1_tail
- * for checking the other side.
- */
- struct gw_info *gwp;
-
- ugh = "no TXT RR for our client delegates us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- passert(same_id(&gwp->gw_id, &sr->this.id));
-
- ugh = "TXT RR for our client has wrong key";
- /* If there is a key from the TXT record,
- * we count it as a win if we match the key.
- * If there was no key, we have a tentative win:
- * we need to check our KEY record to be sure.
- */
- if (!gwp->gw_key_present)
- {
- /* Success, but the TXT had no key
- * so we must check our our own KEY records.
- */
- next_step = fos_our_txt;
- ugh = NULL; /* good! */
- break;
- }
- if (same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- }
- break;
-
- case fos_our_txt: /* TXT for us */
- {
- /* Check if TXT lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
-
- next_step = fos_his_client; /* unless we decide to look for KEY RR */
-
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- struct gw_info *gwp;
-
- ugh = "no TXT RR for us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- passert(same_id(&gwp->gw_id, &sr->this.id));
-
- ugh = "TXT RR for us has wrong key";
- if (gwp->gw_key_present
- && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
- {
- DBG(DBG_CONTROL,
- DBG_log("initiate on demand found TXT with right public key at: %s"
- , mycredentialstr));
- ugh = NULL;
- break;
- }
- }
-#ifdef USE_KEYRR
- if (ugh != NULL)
- {
- /* if no TXT with right key, try KEY */
- DBG(DBG_CONTROL,
- DBG_log("will try for KEY RR since initiate on demand found %s: %s"
- , ugh, mycredentialstr));
- next_step = fos_our_key;
- ugh = NULL;
- }
-#endif
- }
- }
- break;
-
-#ifdef USE_KEYRR
- case fos_our_key: /* KEY for us */
- {
- /* Check if KEY lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
-
- next_step = fos_his_client; /* always */
-
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- pubkey_list_t *kr;
-
- ugh = "no KEY RR found for us (and no good TXT RR)";
- for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
- {
- ugh = "all our KEY RRs have the wrong public key (and no good TXT RR)";
- if (kr->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa))
- {
- /* do this only once a day */
- if (!logged_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "found KEY RR but not TXT RR for %s. See http://www.freeswan.org/err/txt-change.html."
- , mycredentialstr);
- logged_txt_warning = TRUE;
- }
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- }
- break;
-#endif /* USE_KEYRR */
-
- case fos_his_client: /* TXT for his client */
- {
- /* We've finished last DNS queries: TXT for his client.
- * Using the information, try to instantiate a connection
- * and start negotiating.
- * We now know the peer. The chosing of "c" ignored this,
- * so we will disregard its current value.
- * !!! We need to randomize the entry in gw that we choose.
- */
- next_step = fos_done; /* no more queries */
-
- c = build_outgoing_opportunistic_connection(ac->gateways_from_dns
- , &b->our_client
- , &b->peer_client);
-
- if (c == NULL)
- {
- /* We cannot seem to instantiate a suitable connection:
- * complain clearly.
- */
- char ocb[ADDRTOT_BUF]
- , pcb[ADDRTOT_BUF]
- , pb[ADDRTOT_BUF];
-
- addrtot(&b->our_client, 0, ocb, sizeof(ocb));
- addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
- passert(id_is_ipaddr(&ac->gateways_from_dns->gw_id));
- addrtot(&ac->gateways_from_dns->gw_id.ip_addr, 0, pb, sizeof(pb));
- loglog(RC_OPPOFAILURE
- , "no suitable connection for opportunism"
- " between %s and %s with %s as peer"
- , ocb, pcb, pb);
-
-#ifdef KLIPS
- if (b->held)
- {
- /* Replace HOLD with PASS.
- * The type of replacement *ought* to be
- * specified by policy.
- */
- (void) replace_bare_shunt(&b->our_client, &b->peer_client
- , BOTTOM_PRIO
- , SPI_PASS /* fail into PASS */
- , TRUE, b->transport_proto
- , "no suitable connection");
- }
-#endif
- }
- else
- {
- /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
- passert(c->kind == CK_INSTANCE);
- passert(c->gw_info != NULL);
- passert(HAS_IPSEC_POLICY(c->policy));
- passert(LHAS(LELEM(RT_UNROUTED) | LELEM(RT_ROUTED_PROSPECTIVE), c->spd.routing));
-#ifdef KLIPS
- if (b->held)
- {
- /* what should we do on failure? */
- (void) assign_hold(c, &c->spd
- , b->transport_proto
- , &b->our_client, &b->peer_client);
- }
-#endif
- c->gw_info->key->last_tried_time = now();
- ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
- b->whackfd = NULL_FD; /* protect from close */
- }
- }
- break;
-
- default:
- bad_case(b->step);
- }
-
- /* the second chunk: initiate the next DNS query (if any) */
- DBG(DBG_CONTROL,
- {
- char ours[ADDRTOT_BUF];
- char his[ADDRTOT_BUF];
-
- addrtot(&b->our_client, 0, ours, sizeof(ours));
- addrtot(&b->peer_client, 0, his, sizeof(his));
- DBG_log("initiate on demand from %s to %s new state: %s with ugh: %s"
- , ours, his, oppo_step_name[b->step], ugh ? ugh : "ok");
- });
-
- if (ugh != NULL)
- {
- b->policy_prio = c->prio;
- b->failure_shunt = shunt_policy_spi(c, FALSE);
- cannot_oppo(c, b, ugh);
- }
- else if (next_step == fos_done)
- {
- /* nothing to do */
- }
- else
- {
- /* set up the next query */
- struct find_oppo_continuation *cr = alloc_thing(struct find_oppo_continuation
- , "opportunistic continuation");
- struct id id;
-
- b->policy_prio = c->prio;
- b->failure_shunt = shunt_policy_spi(c, FALSE);
- cr->b = *b; /* copy; start hand off of whackfd */
- cr->b.failure_ok = FALSE;
- cr->b.step = next_step;
-
- for (sr = &c->spd
- ; sr!=NULL && !sameaddr(&sr->this.host_addr, &b->our_client)
- ; sr = sr->next)
- ;
-
- if (sr == NULL)
- sr = &c->spd;
-
- /* If a %hold shunt has replaced the eroute for this template,
- * record this fact.
- */
- if (b->held
- && sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr))
- {
- sr->routing = RT_ROUTED_ECLIPSED;
- eclipse_count++;
- }
-
- /* Switch to issue next query.
- * A case may turn out to be unnecessary. If so, it falls
- * through to the next case.
- * Figuring out what %myid can stand for must be done before
- * our client credentials are looked up: we must know what
- * the client credentials may use to identify us.
- * On the other hand, our own credentials should be looked
- * up after our clients in case our credentials are not
- * needed at all.
- * XXX this is a wasted effort if we don't have credentials
- * BUT they are not needed.
- */
- switch (next_step)
- {
- case fos_myid_ip_txt:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
- cr->b.failure_ok = TRUE;
- cr->b.want = b->want = "TXT record for IP address as %myid";
- ugh = start_adns_query(&myids[MYID_IP]
- , &myids[MYID_IP]
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
- }
- cr->b.step = fos_myid_hostname_txt;
- /* fall through */
-
- case fos_myid_hostname_txt:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
-#ifdef USE_KEYRR
- cr->b.failure_ok = TRUE;
-#else
- cr->b.failure_ok = FALSE;
-#endif
- cr->b.want = b->want = "TXT record for hostname as %myid";
- ugh = start_adns_query(&myids[MYID_HOSTNAME]
- , &myids[MYID_HOSTNAME]
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
- }
-
-#ifdef USE_KEYRR
- cr->b.step = fos_myid_ip_key;
- /* fall through */
-
- case fos_myid_ip_key:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
- cr->b.failure_ok = TRUE;
- cr->b.want = b->want = "KEY record for IP address as %myid (no good TXT)";
- ugh = start_adns_query(&myids[MYID_IP]
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
- }
- cr->b.step = fos_myid_hostname_key;
- /* fall through */
-
- case fos_myid_hostname_key:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
- cr->b.failure_ok = FALSE; /* last attempt! */
- cr->b.want = b->want = "KEY record for hostname as %myid (no good TXT)";
- ugh = start_adns_query(&myids[MYID_HOSTNAME]
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
- }
-#endif
- cr->b.step = fos_our_client;
- /* fall through */
-
- case fos_our_client: /* TXT for our client */
- if (!sameaddr(&c->spd.this.host_addr, &b->our_client))
- {
- /* Check that at least one TXT(reverse(b->our_client)) is workable.
- * Note: {unshare|free}_id_content not needed for id: ephemeral.
- */
- cr->b.want = b->want = "our client's TXT record";
- iptoid(&b->our_client, &id);
- ugh = start_adns_query(&id
- , &c->spd.this.id /* we are the security gateway */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
- }
- cr->b.step = fos_our_txt;
- /* fall through */
-
- case fos_our_txt: /* TXT for us */
- cr->b.failure_ok = b->failure_ok = TRUE;
- cr->b.want = b->want = "our TXT record";
- ugh = start_adns_query(&sr->this.id
- , &sr->this.id /* we are the security gateway XXX - maybe ignore? mcr */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
-
-#ifdef USE_KEYRR
- case fos_our_key: /* KEY for us */
- cr->b.want = b->want = "our KEY record";
- cr->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&sr->this.id
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
-#endif /* USE_KEYRR */
-
- case fos_his_client: /* TXT for his client */
- /* note: {unshare|free}_id_content not needed for id: ephemeral */
- cr->b.want = b->want = "target's TXT record";
- cr->b.failure_ok = b->failure_ok = FALSE;
- iptoid(&b->peer_client, &id);
- ugh = start_adns_query(&id
- , (const struct id *) NULL /* security gateway unconstrained */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
-
- default:
- bad_case(next_step);
- }
-
- if (ugh == NULL)
- b->whackfd = NULL_FD; /* complete hand-off */
- else
- cannot_oppo(c, b, ugh);
- }
- }
- close_any(b->whackfd);
-}
-
-void
-terminate_connection(const char *nm)
-{
- /* Loop because more than one may match (master and instances)
- * But at least one is required (enforced by con_by_name).
- */
- struct connection *c, *n;
-
- for (c = con_by_name(nm, TRUE); c != NULL; c = n)
- {
- n = c->ac_next; /* grab this before c might disappear */
- if (streq(c->name, nm)
- && c->kind >= CK_PERMANENT
- && !NEVER_NEGOTIATE(c->policy))
- {
- set_cur_connection(c);
- plog("terminating SAs using this connection");
- c->policy &= ~POLICY_UP;
- flush_pending_by_connection(c);
- delete_states_by_connection(c, FALSE);
- reset_cur_connection();
- }
- }
-}
-
-/* check nexthop safety
- * Our nexthop must not be within a routed client subnet, and vice versa.
- * Note: we don't think this is true. We think that KLIPS will
- * not process a packet output by an eroute.
- */
-#ifdef NEVER
-//bool
-//check_nexthop(const struct connection *c)
-//{
-// struct connection *d;
-//
-// if (addrinsubnet(&c->spd.this.host_nexthop, &c->spd.that.client))
-// {
-// loglog(RC_LOG_SERIOUS, "cannot perform routing for connection \"%s\""
-// " because nexthop is within peer's client network",
-// c->name);
-// return FALSE;
-// }
-//
-// for (d = connections; d != NULL; d = d->next)
-// {
-// if (d->routing != RT_UNROUTED)
-// {
-// if (addrinsubnet(&c->spd.this.host_nexthop, &d->spd.that.client))
-// {
-// loglog(RC_LOG_SERIOUS, "cannot do routing for connection \"%s\"
-// " because nexthop is contained in"
-// " existing routing for connection \"%s\"",
-// c->name, d->name);
-// return FALSE;
-// }
-// if (addrinsubnet(&d->spd.this.host_nexthop, &c->spd.that.client))
-// {
-// loglog(RC_LOG_SERIOUS, "cannot do routing for connection \"%s\"
-// " because it contains nexthop of"
-// " existing routing for connection \"%s\"",
-// c->name, d->name);
-// return FALSE;
-// }
-// }
-// }
-// return TRUE;
-//}
-#endif /* NEVER */
-
-/* an ISAKMP SA has been established.
- * Note the serial number, and release any connections with
- * the same peer ID but different peer IP address.
- */
-bool uniqueIDs = FALSE; /* --uniqueids? */
-
-void
-ISAKMP_SA_established(struct connection *c, so_serial_t serial)
-{
- c->newest_isakmp_sa = serial;
-
- /* the connection is now oriented so that we are able to determine
- * whether we are a mode config server with a virtual IP to send.
- */
- if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
- c->spd.that.modecfg = TRUE;
-
- if (uniqueIDs)
- {
- /* for all connections: if the same Phase 1 IDs are used
- * for a different IP address, unorient that connection.
- */
- struct connection *d;
-
- for (d = connections; d != NULL; )
- {
- struct connection *next = d->ac_next; /* might move underneath us */
-
-#ifdef NAT_TRAVERSAL
- if (d->kind >= CK_PERMANENT
- && same_id(&c->spd.this.id, &d->spd.this.id)
- && same_id(&c->spd.that.id, &d->spd.that.id)
- && (!sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr) ||
- (c->spd.that.host_port != d->spd.that.host_port)))
-#else
- if (d->kind >= CK_PERMANENT
- && same_id(&c->spd.this.id, &d->spd.this.id)
- && same_id(&c->spd.that.id, &d->spd.that.id)
- && !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr))
-#endif
- {
- release_connection(d, FALSE);
- }
- d = next;
- }
- }
-}
-
-/* Find the connection to connection c's peer's client with the
- * largest value of .routing. All other things being equal,
- * preference is given to c. If none is routed, return NULL.
- *
- * If erop is non-null, set *erop to a connection sharing both
- * our client subnet and peer's client subnet with the largest value
- * of .routing. If none is erouted, set *erop to NULL.
- *
- * The return value is used to find other connections sharing a route.
- * *erop is used to find other connections sharing an eroute.
- */
-struct connection *
-route_owner(struct connection *c
- , struct spd_route **srp
- , struct connection **erop
- , struct spd_route **esrp)
-{
- struct connection *d
- , *best_ro = c
- , *best_ero = c;
- struct spd_route *srd, *src;
- struct spd_route *best_sr, *best_esr;
- enum routing_t best_routing, best_erouting;
-
- passert(oriented(*c));
- best_sr = NULL;
- best_esr = NULL;
- best_routing = c->spd.routing;
- best_erouting = best_routing;
-
- for (d = connections; d != NULL; d = d->ac_next)
- {
- for (srd = &d->spd; srd; srd = srd->next)
- {
- if (srd->routing == RT_UNROUTED)
- continue;
-
- for (src = &c->spd; src; src=src->next)
- {
- if (!samesubnet(&src->that.client, &srd->that.client))
- continue;
- if (src->that.protocol != srd->that.protocol)
- continue;
- if (src->that.port != srd->that.port)
- continue;
- passert(oriented(*d));
- if (srd->routing > best_routing)
- {
- best_ro = d;
- best_sr = srd;
- best_routing = srd->routing;
- }
-
- if (!samesubnet(&src->this.client, &srd->this.client))
- continue;
- if (src->this.protocol != srd->this.protocol)
- continue;
- if (src->this.port != srd->this.port)
- continue;
- if (srd->routing > best_erouting)
- {
- best_ero = d;
- best_esr = srd;
- best_erouting = srd->routing;
- }
- }
- }
- }
-
- DBG(DBG_CONTROL,
- {
- char cib[CONN_INST_BUF];
- err_t m = builddiag("route owner of \"%s\"%s %s:"
- , c->name
- , (fmt_conn_instance(c, cib), cib)
- , enum_name(&routing_story, c->spd.routing));
-
- if (!routed(best_ro->spd.routing))
- m = builddiag("%s NULL", m);
- else if (best_ro == c)
- m = builddiag("%s self", m);
- else
- m = builddiag("%s \"%s\"%s %s", m
- , best_ro->name
- , (fmt_conn_instance(best_ro, cib), cib)
- , enum_name(&routing_story, best_ro->spd.routing));
-
- if (erop != NULL)
- {
- m = builddiag("%s; eroute owner:", m);
- if (!erouted(best_ero->spd.routing))
- m = builddiag("%s NULL", m);
- else if (best_ero == c)
- m = builddiag("%s self", m);
- else
- m = builddiag("%s \"%s\"%s %s", m
- , best_ero->name
- , (fmt_conn_instance(best_ero, cib), cib)
- , enum_name(&routing_story, best_ero->spd.routing));
- }
-
- DBG_log("%s", m);
- });
-
- if (erop != NULL)
- *erop = erouted(best_erouting)? best_ero : NULL;
-
- if (srp != NULL )
- {
- *srp = best_sr;
- if (esrp != NULL )
- *esrp = best_esr;
- }
-
- return routed(best_routing)? best_ro : NULL;
-}
-
-/* Find a connection that owns the shunt eroute between subnets.
- * There ought to be only one.
- * This might get to be a bottleneck -- try hashing if it does.
- */
-struct connection *
-shunt_owner(const ip_subnet *ours, const ip_subnet *his)
-{
- struct connection *c;
- struct spd_route *sr;
-
- for (c = connections; c != NULL; c = c->ac_next)
- {
- for (sr = &c->spd; sr; sr = sr->next)
- {
- if (shunt_erouted(sr->routing)
- && samesubnet(ours, &sr->this.client)
- && samesubnet(his, &sr->that.client))
- return c;
- }
- }
- return NULL;
-}
-
-/* Find some connection with this pair of hosts.
- * We don't know enough to chose amongst those available.
- * ??? no longer usefully different from find_host_pair_connections
- */
-struct connection *
-find_host_connection(const ip_address *me, u_int16_t my_port
-, const ip_address *him, u_int16_t his_port, lset_t policy)
-{
- struct connection *c = find_host_pair_connections(me, my_port, him, his_port);
-
- if (policy != LEMPTY)
- {
- lset_t auth_requested = policy & POLICY_ID_AUTH_MASK;
-
- /* if we have requirements for the policy,
- * choose the first matching connection.
- */
- while (c != NULL)
- {
- if (c->policy & auth_requested)
- {
- break;
- }
- c = c->hp_next;
- }
- }
- return c;
-}
-
-/* given an up-until-now satisfactory connection, find the best connection
- * now that we just got the Phase 1 Id Payload from the peer.
- *
- * Comments in the code describe the (tricky!) matching criteria.
- * Although this routine could handle the initiator case,
- * it isn't currently called in this case.
- * If it were, it could "upgrade" an Opportunistic Connection
- * to a Road Warrior Connection if a suitable Peer ID were found.
- *
- * In RFC 2409 "The Internet Key Exchange (IKE)",
- * in 5.1 "IKE Phase 1 Authenticated With Signatures", describing Main
- * Mode:
- *
- * Initiator Responder
- * ----------- -----------
- * HDR, SA -->
- * <-- HDR, SA
- * HDR, KE, Ni -->
- * <-- HDR, KE, Nr
- * HDR*, IDii, [ CERT, ] SIG_I -->
- * <-- HDR*, IDir, [ CERT, ] SIG_R
- *
- * In 5.4 "Phase 1 Authenticated With a Pre-Shared Key":
- *
- * HDR, SA -->
- * <-- HDR, SA
- * HDR, KE, Ni -->
- * <-- HDR, KE, Nr
- * HDR*, IDii, HASH_I -->
- * <-- HDR*, IDir, HASH_R
- *
- * refine_host_connection could be called in two case:
- *
- * - the Responder receives the IDii payload:
- * + [PSK] after using PSK to decode this message
- * + before sending its IDir payload
- * + before using its ID in HASH_R computation
- * + [DSig] before using its private key to sign SIG_R
- * + before using the Initiator's ID in HASH_I calculation
- * + [DSig] before using the Initiator's public key to check SIG_I
- *
- * - the Initiator receives the IDir payload:
- * + [PSK] after using PSK to encode previous message and decode this message
- * + after sending its IDii payload
- * + after using its ID in HASH_I computation
- * + [DSig] after using its private key to sign SIG_I
- * + before using the Responder's ID to compute HASH_R
- * + [DSig] before using Responder's public key to check SIG_R
- *
- * refine_host_connection can choose a different connection, as long as
- * nothing already used is changed.
- *
- * In the Initiator case, the particular connection might have been
- * specified by whatever provoked Pluto to initiate. For example:
- * whack --initiate connection-name
- * The advantages of switching connections when we're the Initiator seem
- * less important than the disadvantages, so after FreeS/WAN 1.9, we
- * don't do this.
- */
-struct connection *
-refine_host_connection(const struct state *st, const struct id *peer_id
-, chunk_t peer_ca)
-{
- struct connection *c = st->st_connection;
- u_int16_t auth = st->st_oakley.auth;
- struct connection *d;
- struct connection *best_found = NULL;
- lset_t auth_policy;
- const chunk_t *psk = NULL;
- bool wcpip; /* wildcard Peer IP? */
-
- int wildcards, our_pathlen, peer_pathlen;
- int best_wildcards = MAX_WILDCARDS;
- int best_our_pathlen = MAX_CA_PATH_LEN;
- int best_peer_pathlen = MAX_CA_PATH_LEN;
-
- if (same_id(&c->spd.that.id, peer_id)
- && trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen)
- && peer_pathlen == 0
- && match_requested_ca(c->requested_ca, c->spd.this.ca, &our_pathlen)
- && our_pathlen == 0)
- {
- DBG(DBG_CONTROL,
- DBG_log("current connection is a full match"
- " -- no need to look further");
- )
- return c;
- }
-
- switch (auth)
- {
- case OAKLEY_PRESHARED_KEY:
- auth_policy = POLICY_PSK;
- psk = get_preshared_secret(c);
- /* It should be virtually impossible to fail to find PSK:
- * we just used it to decode the current message!
- */
- if (psk == NULL)
- return NULL; /* cannot determine PSK! */
- break;
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- auth_policy = POLICY_XAUTH_PSK;
- psk = get_preshared_secret(c);
- if (psk == NULL)
- return NULL; /* cannot determine PSK! */
- break;
- case OAKLEY_RSA_SIG:
- auth_policy = POLICY_RSASIG;
- break;
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- auth_policy = POLICY_XAUTH_RSASIG;
- break;
- default:
- bad_case(auth);
- }
-
- /* The current connection won't do: search for one that will.
- * First search for one with the same pair of hosts.
- * If that fails, search for a suitable Road Warrior or Opportunistic
- * connection (i.e. wildcard peer IP).
- * We need to match:
- * - peer_id (slightly complicated by instantiation)
- * - if PSK auth, the key must not change (we used it to decode message)
- * - policy-as-used must be acceptable to new connection
- */
- d = c->host_pair->connections;
- for (wcpip = FALSE; ; wcpip = TRUE)
- {
- for (; d != NULL; d = d->hp_next)
- {
- const char *match_name[] = {"no", "ok"};
-
- bool matching_id = match_id(peer_id
- , &d->spd.that.id, &wildcards);
- bool matching_auth = (d->policy & auth_policy) != LEMPTY;
-
- bool matching_trust = trusted_ca(peer_ca
- , d->spd.that.ca, &peer_pathlen);
- bool matching_request = match_requested_ca(c->requested_ca
- , d->spd.this.ca, &our_pathlen);
- bool match = matching_id && matching_auth &&
- matching_trust && matching_request;
-
- DBG(DBG_CONTROLMORE,
- DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s)"
- , d->name
- , match ? "full":" no"
- , match_name[matching_id]
- , match_name[matching_auth]
- , match_name[matching_trust]
- , match_name[matching_request])
- )
-
- /* do we have a match? */
- if (!match)
- continue;
-
- /* ignore group connections */
- if (d->policy & POLICY_GROUP)
- continue;
-
-#ifdef NAT_TRAVERSAL
- if (c->spd.that.host_port != d->spd.that.host_port
- && d->kind == CK_INSTANCE)
- continue;
-#endif
-
- switch (auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- /* secret must match the one we already used */
- {
- const chunk_t *dpsk = get_preshared_secret(d);
-
- if (dpsk == NULL)
- continue; /* no secret */
-
- if (psk != dpsk)
- if (psk->len != dpsk->len
- || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0)
- continue; /* different secret */
- }
- break;
-
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- /*
- * We must at least be able to find our private key
- .*/
- if (d->spd.this.sc == NULL /* no smartcard */
- && get_RSA_private_key(d) == NULL) /* no private key */
- continue;
- break;
-
- default:
- bad_case(auth);
- }
-
- /* d has passed all the tests.
- * We'll go with it if the Peer ID was an exact match.
- */
- if (match && wildcards == 0 && peer_pathlen == 0 && our_pathlen == 0)
- return d;
-
- /* We'll remember it as best_found in case an exact
- * match doesn't come along.
- */
- if (best_found == NULL || wildcards < best_wildcards
- || ((wildcards == best_wildcards && peer_pathlen < best_peer_pathlen)
- || (peer_pathlen == best_peer_pathlen && our_pathlen < best_our_pathlen)))
- {
- best_found = d;
- best_wildcards = wildcards;
- best_peer_pathlen = peer_pathlen;
- best_our_pathlen = our_pathlen;
- }
- }
- if (wcpip)
- return best_found; /* been around twice already */
-
- /* Starting second time around.
- * We're willing to settle for a connection that needs Peer IP
- * instantiated: Road Warrior or Opportunistic.
- * Look on list of connections for host pair with wildcard Peer IP
- */
- d = find_host_pair_connections(&c->spd.this.host_addr, c->spd.this.host_port
- , (ip_address *)NULL, c->spd.that.host_port);
- }
-}
-
-#ifdef VIRTUAL_IP
-/**
- * With virtual addressing, we must not allow someone to use an already
- * used (by another id) addr/net.
- */
-static bool
-is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id)
-{
- struct connection *d;
-
- for (d = connections; d != NULL; d = d->ac_next)
- {
- switch (d->kind)
- {
- case CK_PERMANENT:
- case CK_INSTANCE:
- if ((subnetinsubnet(peer_net,&d->spd.that.client) ||
- subnetinsubnet(&d->spd.that.client,peer_net))
- && !same_id(&d->spd.that.id, peer_id))
- {
- char buf[BUF_LEN];
- char client[SUBNETTOT_BUF];
-
- subnettot(peer_net, 0, client, sizeof(client));
- idtoa(&d->spd.that.id, buf, sizeof(buf));
- plog("Virtual IP %s is already used by '%s'", client, buf);
- idtoa(peer_id, buf, sizeof(buf));
- plog("Your ID is '%s'", buf);
- return TRUE; /* already used by another one */
- }
- break;
- case CK_GOING_AWAY:
- default:
- break;
- }
- }
- return FALSE; /* you can safely use it */
-}
-#endif
-
-/* find_client_connection: given a connection suitable for ISAKMP
- * (i.e. the hosts match), find a one suitable for IPSEC
- * (i.e. with matching clients).
- *
- * If we don't find an exact match (not even our current connection),
- * we try for one that still needs instantiation. Try Road Warrior
- * abstract connections and the Opportunistic abstract connections.
- * This requires inverse instantiation: abstraction.
- *
- * After failing to find an exact match, we abstract the peer
- * to be NO_IP (the wildcard value). This enables matches with
- * Road Warrior and Opportunistic abstract connections.
- *
- * After failing that search, we also abstract the Phase 1 peer ID
- * if possible. If the peer's ID was the peer's IP address, we make
- * it NO_ID; instantiation will make it the peer's IP address again.
- *
- * If searching for a Road Warrior abstract connection fails,
- * and conditions are suitable, we search for the best Opportunistic
- * abstract connection.
- *
- * Note: in the end, both Phase 1 IDs must be preserved, after any
- * instantiation. They are the IDs that have been authenticated.
- */
-
-#define PATH_WEIGHT 1
-#define WILD_WEIGHT (MAX_CA_PATH_LEN+1)
-#define PRIO_WEIGHT (MAX_WILDCARDS+1)*WILD_WEIGHT
-
-/* fc_try: a helper function for find_client_connection */
-static struct connection *
-fc_try(const struct connection *c
-, struct host_pair *hp
-, const struct id *peer_id
-, const ip_subnet *our_net
-, const ip_subnet *peer_net
-, const u_int8_t our_protocol
-, const u_int16_t our_port
-, const u_int8_t peer_protocol
-, const u_int16_t peer_port
-, chunk_t peer_ca
-, const ietfAttrList_t *peer_list)
-{
- struct connection *d;
- struct connection *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- int wildcards, pathlen;
-
- const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr);
-
- for (d = hp->connections; d != NULL; d = d->hp_next)
- {
- struct spd_route *sr;
-
- if (d->policy & POLICY_GROUP)
- continue;
-
- if (!(same_id(&c->spd.this.id, &d->spd.this.id)
- && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
- && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
- && group_membership(peer_list, d->name, d->spd.that.groups)))
- continue;
-
- /* compare protocol and ports */
- if (d->spd.this.protocol != our_protocol
- || d->spd.this.port != our_port
- || d->spd.that.protocol != peer_protocol
- || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
- continue;
-
- /* non-Opportunistic case:
- * our_client must match.
- *
- * So must peer_client, but the testing is complicated
- * by the fact that the peer might be a wildcard
- * and if so, the default value of that.client
- * won't match the default peer_net. The appropriate test:
- *
- * If d has a peer client, it must match peer_net.
- * If d has no peer client, peer_net must just have peer itself.
- */
-
- for (sr = &d->spd; best != d && sr != NULL; sr = sr->next)
- {
- policy_prio_t prio;
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
- char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
-
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
- subnettot(&sr->this.client, 0, s3, sizeof(s3));
- subnettot(&sr->that.client, 0, d3, sizeof(d3));
- DBG_log(" fc_try trying "
- "%s:%s:%d/%d -> %s:%d/%d vs %s:%s:%d/%d -> %s:%d/%d"
- , c->name, s1, c->spd.this.protocol, c->spd.this.port
- , d1, c->spd.that.protocol, c->spd.that.port
- , d->name, s3, sr->this.protocol, sr->this.port
- , d3, sr->that.protocol, sr->that.port);
- }
-#endif /* DEBUG */
-
- if (!samesubnet(&sr->this.client, our_net))
- continue;
-
- if (sr->that.has_client)
- {
- if (sr->that.has_client_wildcard)
- {
- if (!subnetinsubnet(peer_net, &sr->that.client))
- continue;
- }
- else
- {
-#ifdef VIRTUAL_IP
- if ((!samesubnet(&sr->that.client, peer_net)) && (!is_virtual_connection(d)))
-#else
- if (!samesubnet(&sr->that.client, peer_net))
-#endif
- continue;
-#ifdef VIRTUAL_IP
- if (is_virtual_connection(d)
- && ( (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr))
- || is_virtual_net_used(peer_net, peer_id?peer_id:&c->spd.that.id)))
- continue;
-#endif
- }
- }
- else
- {
- if (!peer_net_is_host)
- continue;
- }
-
- /* We've run the gauntlet -- success:
- * We've got an exact match of subnets.
- * The connection is feasible, but we continue looking for the best.
- * The highest priority wins, implementing eroute-like rule.
- * - a routed connection is preferrred
- * - given that, the smallest number of ID wildcards are preferred
- * - given that, the shortest CA pathlength is preferred
- */
- prio = PRIO_WEIGHT * routed(sr->routing)
- + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
- + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen)
- + 1;
- if (prio > best_prio)
- {
- best = d;
- best_prio = prio;
- }
- }
- }
-
- if (best != NULL && NEVER_NEGOTIATE(best->policy))
- best = NULL;
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try concluding with %s [%ld]"
- , (best ? best->name : "none"), best_prio)
- )
- return best;
-}
-
-static struct connection *
-fc_try_oppo(const struct connection *c
-, struct host_pair *hp
-, const ip_subnet *our_net
-, const ip_subnet *peer_net
-, const u_int8_t our_protocol
-, const u_int16_t our_port
-, const u_int8_t peer_protocol
-, const u_int16_t peer_port
-, chunk_t peer_ca
-, const ietfAttrList_t *peer_list)
-{
- struct connection *d;
- struct connection *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- int wildcards, pathlen;
-
- for (d = hp->connections; d != NULL; d = d->hp_next)
- {
- struct spd_route *sr;
- policy_prio_t prio;
-
- if (d->policy & POLICY_GROUP)
- continue;
-
- if (!(same_id(&c->spd.this.id, &d->spd.this.id)
- && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
- && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
- && group_membership(peer_list, d->name, d->spd.that.groups)))
- continue;
-
- /* compare protocol and ports */
- if (d->spd.this.protocol != our_protocol
- || d->spd.this.port != our_port
- || d->spd.that.protocol != peer_protocol
- || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
- continue;
-
- /* Opportunistic case:
- * our_net must be inside d->spd.this.client
- * and peer_net must be inside d->spd.that.client
- * Note: this host_pair chain also has shunt
- * eroute conns (clear, drop), but they won't
- * be marked as opportunistic.
- */
- for (sr = &d->spd; sr != NULL; sr = sr->next)
- {
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
- char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
-
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
- subnettot(&sr->this.client, 0, s3, sizeof(s3));
- subnettot(&sr->that.client, 0, d3, sizeof(d3));
- DBG_log(" fc_try_oppo trying %s:%s -> %s vs %s:%s -> %s"
- , c->name, s1, d1, d->name, s3, d3);
- }
-#endif /* DEBUG */
-
- if (!subnetinsubnet(our_net, &sr->this.client)
- || !subnetinsubnet(peer_net, &sr->that.client))
- continue;
-
- /* The connection is feasible, but we continue looking for the best.
- * The highest priority wins, implementing eroute-like rule.
- * - our smallest client subnet is preferred (longest mask)
- * - given that, his smallest client subnet is preferred
- * - given that, a routed connection is preferrred
- * - given that, the smallest number of ID wildcards are preferred
- * - given that, the shortest CA pathlength is preferred
- */
- prio = PRIO_WEIGHT * (d->prio + routed(sr->routing))
- + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
- + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen);
- if (prio > best_prio)
- {
- best = d;
- best_prio = prio;
- }
- }
- }
-
- /* if the best wasn't opportunistic, we fail: it must be a shunt */
- if (best != NULL
- && (NEVER_NEGOTIATE(best->policy)
- || (best->policy & POLICY_OPPO) == LEMPTY))
- {
- best = NULL;
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try_oppo concluding with %s [%ld]"
- , (best ? best->name : "none"), best_prio)
- )
- return best;
-
-}
-
-/*
- * get the peer's CA and group attributes
- */
-chunk_t
-get_peer_ca_and_groups(struct connection *c, const ietfAttrList_t **peer_list)
-{
- struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
-
- *peer_list = NULL;
-
- if (p1st != NULL
- && p1st->st_peer_pubkey != NULL
- && p1st->st_peer_pubkey->issuer.ptr != NULL)
- {
- x509acert_t *ac = get_x509acert(p1st->st_peer_pubkey->issuer
- , p1st->st_peer_pubkey->serial);;
-
- if (ac != NULL && verify_x509acert(ac, strict_crl_policy))
- *peer_list = ac->groups;
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("no valid attribute cert found")
- )
- }
- return p1st->st_peer_pubkey->issuer;
- }
- return empty_chunk;
-}
-
-struct connection *
-find_client_connection(struct connection *c
-, const ip_subnet *our_net, const ip_subnet *peer_net
-, const u_int8_t our_protocol, const u_int16_t our_port
-, const u_int8_t peer_protocol, const u_int16_t peer_port)
-{
- struct connection *d;
- struct spd_route *sr;
-
- const ietfAttrList_t *peer_list = NULL;
- chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_list);
-
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
-
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
-
- DBG_log("find_client_connection starting with %s"
- , (c ? c->name : "(none)"));
- DBG_log(" looking for %s:%d/%d -> %s:%d/%d"
- , s1, our_protocol, our_port
- , d1, peer_protocol, peer_port);
- }
-#endif /* DEBUG */
-
- /* give priority to current connection
- * but even greater priority to a routed concrete connection
- */
- {
- struct connection *unrouted = NULL;
- int srnum = -1;
-
- for (sr = &c->spd; unrouted == NULL && sr != NULL; sr = sr->next)
- {
- srnum++;
-
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
-
- subnettot(&sr->this.client, 0, s2, sizeof(s2));
- subnettot(&sr->that.client, 0, d2, sizeof(d2));
- DBG_log(" concrete checking against sr#%d %s -> %s"
- , srnum, s2, d2);
- }
-#endif /* DEBUG */
-
- if (samesubnet(&sr->this.client, our_net)
- && samesubnet(&sr->that.client, peer_net)
- && sr->this.protocol == our_protocol
- && sr->this.port == our_port
- && sr->that.protocol == peer_protocol
- && sr->that.port == peer_port
- && group_membership(peer_list, c->name, sr->that.groups))
- {
- passert(oriented(*c));
- if (routed(sr->routing))
- return c;
-
- unrouted = c;
- }
- }
-
- /* exact match? */
- d = fc_try(c, c->host_pair, NULL, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try %s gives %s"
- , c->name
- , (d ? d->name : "none"))
- )
-
- if (d == NULL)
- d = unrouted;
- }
-
- if (d == NULL)
- {
- /* look for an abstract connection to match */
- struct spd_route *sr;
- struct host_pair *hp = NULL;
-
- for (sr = &c->spd; hp==NULL && sr != NULL; sr = sr->next)
- {
- hp = find_host_pair(&sr->this.host_addr
- , sr->this.host_port
- , NULL
- , sr->that.host_port);
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
-
- subnettot(&sr->this.client, 0, s2, sizeof(s2));
- subnettot(&sr->that.client, 0, d2, sizeof(d2));
-
- DBG_log(" checking hostpair %s -> %s is %s"
- , s2, d2
- , (hp ? "found" : "not found"));
- }
-#endif /* DEBUG */
- }
-
- if (hp != NULL)
- {
- /* RW match with actual peer_id or abstract peer_id? */
- d = fc_try(c, hp, NULL, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
-
- if (d == NULL
- && subnetishost(our_net)
- && subnetishost(peer_net))
- {
- /* Opportunistic match?
- * Always use abstract peer_id.
- * Note that later instantiation will result in the same peer_id.
- */
- d = fc_try_oppo(c, hp, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
- }
- }
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" concluding with d = %s"
- , (d ? d->name : "none"))
- )
- return d;
-}
-
-int
-connection_compare(const struct connection *ca
-, const struct connection *cb)
-{
- int ret;
-
- /* DBG_log("comparing %s to %s", ca->name, cb->name); */
-
- ret = strcasecmp(ca->name, cb->name);
- if (ret != 0)
- return ret;
-
- ret = ca->kind - cb->kind; /* note: enum connection_kind behaves like int */
- if (ret != 0)
- return ret;
-
- /* same name, and same type */
- switch (ca->kind)
- {
- case CK_INSTANCE:
- return ca->instance_serial < cb->instance_serial ? -1
- : ca->instance_serial > cb->instance_serial ? 1
- : 0;
-
- default:
- return ca->prio < cb->prio ? -1
- : ca->prio > cb->prio ? 1
- : 0;
- }
-}
-
-static int
-connection_compare_qsort(const void *a, const void *b)
-{
- return connection_compare(*(const struct connection *const *)a
- , *(const struct connection *const *)b);
-}
-
-void
-show_connections_status(bool all, const char *name)
-{
- struct connection *c;
- int count, i;
- struct connection **array;
-
- /* make an array of connections, and sort it */
- count = 0;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (name == NULL || streq(c->name, name))
- count++;
- }
- array = alloc_bytes(sizeof(struct connection *)*count, "connection array");
-
- count=0;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (name == NULL || streq(c->name, name))
- array[count++]=c;
- }
-
- /* sort it! */
- qsort(array, count, sizeof(struct connection *), connection_compare_qsort);
-
- for (i = 0; i < count; i++)
- {
- const char *ifn;
- char instance[1 + 10 + 1];
- char prio[POLICY_PRIO_BUF];
-
- c = array[i];
-
- ifn = oriented(*c)? c->interface->rname : "";
-
- instance[0] = '\0';
- if (c->kind == CK_INSTANCE && c->instance_serial != 0)
- snprintf(instance, sizeof(instance), "[%lu]", c->instance_serial);
-
- /* show topology */
- {
- char topo[CONNECTION_BUF];
- struct spd_route *sr = &c->spd;
- int num=0;
-
- while (sr != NULL)
- {
- (void) format_connection(topo, sizeof(topo), c, sr);
- whack_log(RC_COMMENT, "\"%s\"%s: %s; %s; eroute owner: #%lu"
- , c->name, instance, topo
- , enum_name(&routing_story, sr->routing)
- , sr->eroute_owner);
- sr = sr->next;
- num++;
- }
- }
-
- if (all)
- {
- /* show CAs if defined */
- if (c->spd.this.ca.ptr != NULL || c->spd.that.ca.ptr != NULL)
- {
- char this_ca[BUF_LEN], that_ca[BUF_LEN];
-
- dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any");
- dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any");
-
- whack_log(RC_COMMENT
- , "\"%s\"%s: CAs: '%s'...'%s'"
- , c->name
- , instance
- , this_ca
- , that_ca);
- }
-
- /* show group attributes if defined */
- if (c->spd.that.groups != NULL)
- {
- char buf[BUF_LEN];
-
- format_groups(c->spd.that.groups, buf, BUF_LEN);
- whack_log(RC_COMMENT
- , "\"%s\"%s: groups: %s"
- , c->name
- , instance
- , buf);
- }
-
- whack_log(RC_COMMENT
- , "\"%s\"%s: ike_life: %lus; ipsec_life: %lus;"
- " rekey_margin: %lus; rekey_fuzz: %lu%%; keyingtries: %lu"
- , c->name
- , instance
- , (unsigned long) c->sa_ike_life_seconds
- , (unsigned long) c->sa_ipsec_life_seconds
- , (unsigned long) c->sa_rekey_margin
- , (unsigned long) c->sa_rekey_fuzz
- , (unsigned long) c->sa_keying_tries);
-
- /* show DPD parameters if defined */
-
- if (c->dpd_action != DPD_ACTION_NONE)
- whack_log(RC_COMMENT
- , "\"%s\"%s: dpd_action: %s;"
- " dpd_delay: %lus; dpd_timeout: %lus;"
- , c->name
- , instance
- , enum_show(&dpd_action_names, c->dpd_action)
- , (unsigned long) c->dpd_delay
- , (unsigned long) c->dpd_timeout);
-
- if (c->policy_next)
- {
- whack_log(RC_COMMENT
- , "\"%s\"%s: policy_next: %s"
- , c->name, instance, c->policy_next->name);
- }
-
- /* Note: we display key_from_DNS_on_demand as if policy [lr]KOD */
- fmt_policy_prio(c->prio, prio);
- whack_log(RC_COMMENT
- , "\"%s\"%s: policy: %s%s%s; prio: %s; interface: %s; "
- , c->name
- , instance
- , prettypolicy(c->policy)
- , c->spd.this.key_from_DNS_on_demand? "+lKOD" : ""
- , c->spd.that.key_from_DNS_on_demand? "+rKOD" : ""
- , prio
- , ifn);
- }
-
- whack_log(RC_COMMENT
- , "\"%s\"%s: newest ISAKMP SA: #%ld; newest IPsec SA: #%ld; "
- , c->name
- , instance
- , c->newest_isakmp_sa
- , c->newest_ipsec_sa);
-
- if (all)
- {
- ike_alg_show_connection(c, instance);
- kernel_alg_show_connection(c, instance);
- }
- }
- if (count > 0)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
-
- pfree(array);
-}
-
-/* struct pending, the structure representing Quick Mode
- * negotiations delayed until a Keying Channel has been negotiated.
- * Essentially, a pending call to quick_outI1.
- */
-
-struct pending {
- int whack_sock;
- struct state *isakmp_sa;
- struct connection *connection;
- lset_t policy;
- unsigned long try;
- so_serial_t replacing;
-
- struct pending *next;
-};
-
-/* queue a Quick Mode negotiation pending completion of a suitable Main Mode */
-void
-add_pending(int whack_sock
-, struct state *isakmp_sa
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
-{
- bool already_queued = FALSE;
- struct pending *p = c->host_pair->pending;
-
- while (p != NULL)
- {
- if (streq(c->name, p->connection->name))
- {
- already_queued = TRUE;
- break;
- }
- p = p->next;
- }
- DBG(DBG_CONTROL,
- DBG_log("Queuing pending Quick Mode with %s \"%s\"%s"
- , ip_str(&c->spd.that.host_addr)
- , c->name
- , already_queued? " already done" : "")
- )
- if (already_queued)
- return;
-
- p = alloc_thing(struct pending, "struct pending");
- p->whack_sock = whack_sock;
- p->isakmp_sa = isakmp_sa;
- p->connection = c;
- p->policy = policy;
- p->try = try;
- p->replacing = replacing;
- p->next = c->host_pair->pending;
- c->host_pair->pending = p;
-}
-
-/* Release all the whacks awaiting the completion of this state.
- * This is accomplished by closing all the whack socket file descriptors.
- * We go to a lot of trouble to tell each whack, but to not tell it twice.
- */
-void
-release_pending_whacks(struct state *st, err_t story)
-{
- struct pending *p;
- struct stat stst;
-
- if (st->st_whack_sock == NULL_FD || fstat(st->st_whack_sock, &stst) != 0)
- zero(&stst); /* resulting st_dev/st_ino ought to be distinct */
-
- release_whack(st);
-
- for (p = st->st_connection->host_pair->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == st && p->whack_sock != NULL_FD)
- {
- struct stat pst;
-
- if (fstat(p->whack_sock, &pst) == 0
- && (stst.st_dev != pst.st_dev || stst.st_ino != pst.st_ino))
- {
- passert(whack_log_fd == NULL_FD);
- whack_log_fd = p->whack_sock;
- whack_log(RC_COMMENT
- , "%s for ISAKMP SA, but releasing whack for pending IPSEC SA"
- , story);
- whack_log_fd = NULL_FD;
- }
- close(p->whack_sock);
- p->whack_sock = NULL_FD;
- }
- }
-}
-
-static void
-delete_pending(struct pending **pp)
-{
- struct pending *p = *pp;
-
- *pp = p->next;
- if (p->connection != NULL)
- connection_discard(p->connection);
- close_any(p->whack_sock);
- pfree(p);
-}
-
-void
-unpend(struct state *st)
-{
- struct pending **pp
- , *p;
-
- for (pp = &st->st_connection->host_pair->pending; (p = *pp) != NULL; )
- {
- if (p->isakmp_sa == st)
- {
- DBG(DBG_CONTROL, DBG_log("unqueuing pending Quick Mode with %s \"%s\""
- , ip_str(&p->connection->spd.that.host_addr)
- , p->connection->name));
- (void) quick_outI1(p->whack_sock, st, p->connection, p->policy
- , p->try, p->replacing);
- p->whack_sock = NULL_FD; /* ownership transferred */
- p->connection = NULL; /* ownership transferred */
- delete_pending(pp);
- }
- else
- {
- pp = &p->next;
- }
- }
-}
-
-/* a Main Mode negotiation has been replaced; update any pending */
-void
-update_pending(struct state *os, struct state *ns)
-{
- struct pending *p;
-
- for (p = os->st_connection->host_pair->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == os)
- p->isakmp_sa = ns;
-#ifdef NAT_TRAVERSAL
- if (p->connection->spd.this.host_port != ns->st_connection->spd.this.host_port)
- {
- p->connection->spd.this.host_port = ns->st_connection->spd.this.host_port;
- p->connection->spd.that.host_port = ns->st_connection->spd.that.host_port;
- }
-#endif
- }
-}
-
-/* a Main Mode negotiation has failed; discard any pending */
-void
-flush_pending_by_state(struct state *st)
-{
- struct host_pair *hp = st->st_connection->host_pair;
-
- if (hp != NULL)
- {
- struct pending **pp
- , *p;
-
- for (pp = &hp->pending; (p = *pp) != NULL; )
- {
- if (p->isakmp_sa == st)
- delete_pending(pp);
- else
- pp = &p->next;
- }
- }
-}
-
-/* a connection has been deleted; discard any related pending */
-static void
-flush_pending_by_connection(struct connection *c)
-{
- if (c->host_pair != NULL)
- {
- struct pending **pp
- , *p;
-
- for (pp = &c->host_pair->pending; (p = *pp) != NULL; )
- {
- if (p->connection == c)
- {
- p->connection = NULL; /* prevent delete_pending from releasing */
- delete_pending(pp);
- }
- else
- {
- pp = &p->next;
- }
- }
- }
-}
-
-void
-show_pending_phase2(const struct host_pair *hp, const struct state *st)
-{
- const struct pending *p;
-
- for (p = hp->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == st)
- {
- /* connection-name state-number [replacing state-number] */
- char cip[CONN_INST_BUF];
-
- fmt_conn_instance(p->connection, cip);
- whack_log(RC_COMMENT, "#%lu: pending Phase 2 for \"%s\"%s replacing #%lu"
- , p->isakmp_sa->st_serialno
- , p->connection->name
- , cip
- , p->replacing);
- }
- }
-}
-
-/* Delete a connection if it is an instance and it is no longer in use.
- * We must be careful to avoid circularity:
- * we don't touch it if it is CK_GOING_AWAY.
- */
-void
-connection_discard(struct connection *c)
-{
- if (c->kind == CK_INSTANCE)
- {
- /* see if it is being used by a pending */
- struct pending *p;
-
- for (p = c->host_pair->pending; p != NULL; p = p->next)
- if (p->connection == c)
- return; /* in use, so we're done */
-
- if (!states_use_connection(c))
- delete_connection(c, FALSE);
- }
-}
-
-
-/* A template connection's eroute can be eclipsed by
- * either a %hold or an eroute for an instance iff
- * the template is a /32 -> /32. This requires some special casing.
- */
-
-long eclipse_count = 0;
-
-struct connection *
-eclipsed(struct connection *c, struct spd_route **esrp)
-{
- struct connection *ue;
- struct spd_route *sr1 = &c->spd;
-
- ue = NULL;
-
- while (sr1 != NULL && ue != NULL)
- {
- for (ue = connections; ue != NULL; ue = ue->ac_next)
- {
- struct spd_route *srue = &ue->spd;
-
- while (srue != NULL
- && srue->routing == RT_ROUTED_ECLIPSED
- && !(samesubnet(&sr1->this.client, &srue->this.client)
- && samesubnet(&sr1->that.client, &srue->that.client)))
- {
- srue = srue->next;
- }
- if (srue != NULL && srue->routing==RT_ROUTED_ECLIPSED)
- {
- *esrp = srue;
- break;
- }
- }
- }
- return ue;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/programs/pluto/connections.h b/programs/pluto/connections.h
deleted file mode 100644
index 33fbc3fea..000000000
--- a/programs/pluto/connections.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/* information about connections between hosts and clients
- * Copyright (C) 1998-2001 D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: connections.h,v 1.19 2006/10/19 15:38:27 as Exp $
- */
-
-#ifndef _CONNECTIONS_H
-#define _CONNECTIONS_H
-
-#include <sys/queue.h>
-
-#include "id.h"
-#include "certs.h"
-#include "ac.h"
-#include "smartcard.h"
-#include "whack.h"
-
-/* There are two kinds of connections:
- * - ISAKMP connections, between hosts (for IKE communication)
- * - IPsec connections, between clients (for secure IP communication)
- *
- * An ISAKMP connection looks like:
- * host<--->host
- *
- * An IPsec connection looks like:
- * client-subnet<-->host<->nexthop<--->nexthop<->host<-->client-subnet
- *
- * For the connection to be relevant to this instance of Pluto,
- * exactly one of the hosts must be a public interface of our machine
- * known to this instance.
- *
- * The client subnet might simply be the host -- this is a
- * representation of "host mode".
- *
- * Each nexthop defaults to the neighbouring host's IP address.
- * The nexthop is a property of the pair of hosts, not each
- * individually. It is only needed for IPsec because of the
- * way IPsec is mixed into the kernel routing logic. Furthermore,
- * only this end's nexthop is actually used. Eventually, nexthop
- * will be unnecessary.
- *
- * Other information represented:
- * - each connection has a name: a chunk of uninterpreted text
- * that is unique for each connection.
- * - security requirements (currently just the "policy" flags from
- * the whack command to initiate the connection, but eventually
- * much more. Different for ISAKMP and IPsec connections.
- * - rekeying parameters:
- * + time an SA may live
- * + time before SA death that a rekeying should be attempted
- * (only by the initiator)
- * + number of times to attempt rekeying
- * - With the current KLIPS, we must route packets for a client
- * subnet through the ipsec interface (ipsec0). Only one
- * gateway can get traffic for a specific (client) subnet.
- * Furthermore, if the routing isn't in place, packets will
- * be sent in the clear.
- * "routing" indicates whether the routing has been done for
- * this connection. Note that several connections may claim
- * the same routing, as long as they agree about where the
- * packets are to be sent.
- * - With the current KLIPS, only one outbound IPsec SA bundle can be
- * used for a particular client. This is due to a limitation
- * of using only routing for selection. So only one IPsec state (SA)
- * may "own" the eroute. "eroute_owner" is the serial number of
- * this state, SOS_NOBODY if there is none. "routing" indicates
- * what kind of erouting has been done for this connection, if any.
- *
- * Details on routing is in constants.h
- *
- * Operations on Connections:
- *
- * - add a new connection (with all details) [whack command]
- * - delete a connection (by name) [whack command]
- * - initiate a connection (by name) [whack command]
- * - find a connection (by IP addresses of hosts)
- * [response to peer request; finding ISAKMP connection for IPsec connection]
- *
- * Some connections are templates, missing the address of the peer
- * (represented by INADDR_ANY). These are always arranged so that the
- * missing end is "that" (there can only be one missing end). These can
- * be instantiated (turned into real connections) by Pluto in one of two
- * different ways: Road Warrior Instantiation or Opportunistic
- * Instantiation. A template connection is marked for Opportunistic
- * Instantiation by specifying the peer client as 0.0.0.0/32 (or the IPV6
- * equivalent). Otherwise, it is suitable for Road Warrior Instantiation.
- *
- * Instantiation creates a new temporary connection, with the missing
- * details filled in. The resulting template lasts only as long as there
- * is a state that uses it.
- */
-
-/* connection policy priority: how important this policy is
- * - used to implement eroute-like precedence (augmented by a small
- * bonus for a routed connection).
- * - a whole number
- * - larger is more important
- * - three subcomponents. In order of decreasing significance:
- * + length of source subnet mask (8 bits)
- * + length of destination subnet mask (8 bits)
- * + bias (8 bit)
- * - a bias of 1 is added to allow prio BOTTOM_PRIO to be less than all
- * normal priorities
- * - other bias values are created on the fly to give mild preference
- * to certaion conditions (eg. routedness)
- * - priority is inherited -- an instance of a policy has the same priority
- * as the original policy, even though its subnets might be smaller.
- * - display format: n,m
- */
-typedef unsigned long policy_prio_t;
-#define BOTTOM_PRIO ((policy_prio_t)0) /* smaller than any real prio */
-#define set_policy_prio(c) { (c)->prio = \
- ((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
- | ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
- | (policy_prio_t)1; }
-#define POLICY_PRIO_BUF (3+1+3+1)
-extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]);
-
-#ifdef VIRTUAL_IP
-struct virtual_t;
-#endif
-
-struct end {
- struct id id;
- ip_address
- host_addr,
- host_nexthop,
- host_srcip;
- ip_subnet client;
-
- bool key_from_DNS_on_demand;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_id_wildcards;
- bool has_natip;
- char *updown;
- u_int16_t host_port; /* host order */
- u_int16_t port; /* host order */
- u_int8_t protocol;
- cert_t cert; /* end certificate */
- chunk_t ca; /* CA distinguished name */
- struct ietfAttrList *groups;/* access control groups */
- smartcard_t *sc; /* smartcard reader and key info */
-#ifdef VIRTUAL_IP
- struct virtual_t *virt;
-#endif
- bool modecfg; /* this end: request local address from server */
- /* that end: give local addresses to clients */
- bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
- /* rules if client behind host is a subnet */
- certpolicy_t sendcert; /* whether or not to send the certificate */
-};
-
-struct spd_route {
- struct spd_route *next;
- struct end this;
- struct end that;
- so_serial_t eroute_owner;
- enum routing_t routing; /* level of routing in place */
- uint32_t reqid;
-};
-
-struct connection {
- char *name;
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_rekey_fuzz;
- unsigned long sa_keying_tries;
-
- /* RFC 3706 DPD */
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
-
- char *log_file_name; /* name of log file */
- FILE *log_file; /* possibly open FILE */
- CIRCLEQ_ENTRY(connection) log_link; /* linked list of open conns */
- bool log_file_err; /* only bitch once */
-
- struct spd_route spd;
-
- /* internal fields: */
-
- unsigned long instance_serial;
- policy_prio_t prio;
- bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
- enum connection_kind kind;
- const struct iface *interface; /* filled in iff oriented */
-
- so_serial_t /* state object serial number */
- newest_isakmp_sa,
- newest_ipsec_sa;
-
-
-#ifdef DEBUG
- lset_t extra_debugging;
-#endif
-
- /* note: if the client is the gateway, the following must be equal */
- sa_family_t addr_family; /* between gateways */
- sa_family_t tunnel_addr_family; /* between clients */
-
- struct connection *policy_next; /* if multiple policies,
- next one to apply */
-
- struct gw_info *gw_info;
- struct alg_info_esp *alg_info_esp;
- struct alg_info_ike *alg_info_ike;
-
- struct host_pair *host_pair;
- struct connection *hp_next; /* host pair list link */
-
- struct connection *ac_next; /* all connections list link */
-
- generalName_t *requested_ca; /* collected certificate requests */
- bool got_certrequest;
-};
-
-#define oriented(c) ((c).interface != NULL)
-extern bool orient(struct connection *c);
-
-extern bool same_peer_ids(const struct connection *c
- , const struct connection *d, const struct id *his_id);
-
-/* Format the topology of a connection end, leaving out defaults.
- * Largest left end looks like: client === host : port [ host_id ] --- hop
- * Note: if that==NULL, skip nexthop
- */
-#define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10)
-extern size_t format_end(char *buf, size_t buf_len
- , const struct end *this, const struct end *that
- , bool is_left, lset_t policy);
-
-extern void add_connection(const whack_message_t *wm);
-extern void initiate_connection(const char *name, int whackfd);
-extern void initiate_opportunistic(const ip_address *our_client
- , const ip_address *peer_client, int transport_proto, bool held, int whackfd);
-extern void terminate_connection(const char *nm);
-extern void release_connection(struct connection *c, bool relations);
-extern void delete_connection(struct connection *c, bool relations);
-extern void delete_connections_by_name(const char *name, bool strict);
-extern void delete_every_connection(void);
-extern char *add_group_instance(struct connection *group, const ip_subnet *target);
-extern void remove_group_instance(const struct connection *group, const char *name);
-extern void release_dead_interfaces(void);
-extern void check_orientations(void);
-extern struct connection *route_owner(struct connection *c
- , struct spd_route **srp
- , struct connection **erop
- , struct spd_route **esrp);
-extern struct connection *shunt_owner(const ip_subnet *ours
- , const ip_subnet *his);
-
-extern bool uniqueIDs; /* --uniqueids? */
-extern void ISAKMP_SA_established(struct connection *c, so_serial_t serial);
-
-#define his_id_was_instantiated(c) ((c)->kind == CK_INSTANCE \
- && (id_is_ipaddr(&(c)->spd.that.id)? \
- sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
-
-struct state; /* forward declaration of tag (defined in state.h) */
-extern struct connection
- *con_by_name(const char *nm, bool strict),
- *find_host_connection(const ip_address *me, u_int16_t my_port
- , const ip_address *him, u_int16_t his_port, lset_t policy),
- *refine_host_connection(const struct state *st, const struct id *id
- , chunk_t peer_ca),
- *find_client_connection(struct connection *c
- , const ip_subnet *our_net
- , const ip_subnet *peer_net
- , const u_int8_t our_protocol
- , const u_int16_t out_port
- , const u_int8_t peer_protocol
- , const u_int16_t peer_port),
- *find_connection_by_reqid(uint32_t reqid);
-
-extern struct connection *
-find_connection_for_clients(struct spd_route **srp
- , const ip_address *our_client
- , const ip_address *peer_client
- , int transport_proto);
-
-extern chunk_t get_peer_ca_and_groups(struct connection *c
- , const ietfAttrList_t **peer_list);
-
-/* instantiating routines
- * Note: connection_discard() is in state.h because all its work
- * is looking through state objects.
- */
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
-struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
-extern struct connection *rw_instantiate(struct connection *c
- , const ip_address *him
-#ifdef NAT_TRAVERSAL
- , u_int16_t his_port
-#endif
-#ifdef VIRTUAL_IP
- , const ip_subnet *his_net
-#endif
- , const struct id *his_id);
-
-extern struct connection *oppo_instantiate(struct connection *c
- , const ip_address *him
- , const struct id *his_id
- , struct gw_info *gw
- , const ip_address *our_client
- , const ip_address *peer_client);
-
-extern struct connection
- *build_outgoing_opportunistic_connection(struct gw_info *gw
- , const ip_address *our_client
- , const ip_address *peer_client);
-
-/* worst case: "[" serial "] " myclient "=== ..." peer "===" hisclient '\0' */
-#define CONN_INST_BUF \
- (2 + 10 + 1 + SUBNETTOT_BUF + 7 + ADDRTOT_BUF + 3 + SUBNETTOT_BUF + 1)
-
-extern void fmt_conn_instance(const struct connection *c
- , char buf[CONN_INST_BUF]);
-
-/* operations on "pending", the structure representing Quick Mode
- * negotiations delayed until a Keying Channel has been negotiated.
- */
-
-struct pending; /* forward declaration (opaque outside connections.c) */
-
-extern void add_pending(int whack_sock
- , struct state *isakmp_sa
- , struct connection *c
- , lset_t policy
- , unsigned long try
- , so_serial_t replacing);
-
-extern void release_pending_whacks(struct state *st, err_t story);
-extern void unpend(struct state *st);
-extern void update_pending(struct state *os, struct state *ns);
-extern void flush_pending_by_state(struct state *st);
-extern void show_pending_phase2(const struct host_pair *hp, const struct state *st);
-
-extern void connection_discard(struct connection *c);
-
-/* A template connection's eroute can be eclipsed by
- * either a %hold or an eroute for an instance iff
- * the template is a /32 -> /32. This requires some special casing.
- */
-#define eclipsable(sr) (subnetishost(&(sr)->this.client) && subnetishost(&(sr)->that.client))
-extern long eclipse_count;
-extern struct connection *eclipsed(struct connection *c, struct spd_route **);
-
-
-/* print connection status */
-
-extern void show_connections_status(bool all, const char *name);
-extern int connection_compare(const struct connection *ca
- , const struct connection *cb);
-#ifdef NAT_TRAVERSAL
-void
-update_host_pair(const char *why, struct connection *c,
- const ip_address *myaddr, u_int16_t myport ,
- const ip_address *hisaddr, u_int16_t hisport);
-#endif /* NAT_TRAVERSAL */
-
-#endif /* _CONNECTIONS_H */
diff --git a/programs/pluto/constants.c b/programs/pluto/constants.c
deleted file mode 100644
index 322de74ac..000000000
--- a/programs/pluto/constants.c
+++ /dev/null
@@ -1,1356 +0,0 @@
-/* tables of names for values defined in constants.h
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: constants.c,v 1.24 2007/01/21 08:35:47 as Exp $
- */
-
-/*
- * Note that the array sizes are all specified; this is to enable range
- * checking by code that only includes constants.h.
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <netinet/in.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "packet.h"
-
-/* string naming compile-time options that have interop implications */
-
-const char compile_time_interop_options[] = ""
-#ifdef THREADS
- " THREADS"
-#endif
-#ifdef LIBCURL
- " LIBCURL"
-#endif
-#ifdef LDAP_VER
-#if LDAP_VER == 2
- " LDAP_V2"
-#else
- " LDAP_V3"
-#endif
-#endif
-#ifdef SMARTCARD
- " SMARTCARD"
-#endif
-#ifdef VENDORID
- " VENDORID"
-#endif
-#ifdef CISCO_QUIRKS
- " CISCO_QUIRKS"
-#endif
-#ifdef USE_KEYRR
- " KEYRR"
-#endif
- ;
-
-/* version */
-
-static const char *const version_name[] = {
- "ISAKMP Version 1.0",
-};
-
-enum_names version_names =
- { ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
- ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
- version_name, NULL };
-
-/* RFC 2459 CRL reason codes */
-
-static const char *const crl_reason_name[] = {
- "unspecified",
- "key compromise",
- "ca compromise",
- "affiliation changed",
- "superseded",
- "cessation of operation",
- "certificate hold",
- "reason #7",
- "remove from crl"
- };
-
-enum_names crl_reason_names =
- { REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL};
-
-/* RFC 3706 Dead Peer Detection */
-
-static const char *const dpd_action_name[] = {
- "none",
- "clear",
- "hold",
- "restart"
- };
-
-enum_names dpd_action_names =
- { DPD_ACTION_NONE, DPD_ACTION_RESTART, dpd_action_name, NULL};
-
-/* Timer events */
-
-static const char *const timer_event_name[] = {
- "EVENT_NULL",
- "EVENT_REINIT_SECRET",
- "EVENT_SHUNT_SCAN",
- "EVENT_SO_DISCARD",
- "EVENT_RETRANSMIT",
- "EVENT_SA_REPLACE",
- "EVENT_SA_REPLACE_IF_USED",
- "EVENT_SA_EXPIRE",
- "EVENT_NAT_T_KEEPALIVE",
- "EVENT_DPD",
- "EVENT_DPD_TIMEOUT",
- "EVENT_LOG_DAILY"
- };
-
-enum_names timer_event_names =
- { EVENT_NULL, EVENT_LOG_DAILY, timer_event_name, NULL };
-
-/* Domain of Interpretation */
-
-static const char *const doi_name[] = {
- "ISAKMP_DOI_ISAKMP",
- "ISAKMP_DOI_IPSEC",
-};
-
-enum_names doi_names = { ISAKMP_DOI_ISAKMP, ISAKMP_DOI_IPSEC, doi_name, NULL };
-
-/* debugging settings: a set of selections for reporting
- * These would be more naturally situated in log.h,
- * but they are shared with whack.
- * It turns out that "debug-" is clutter in all contexts this is used,
- * so we leave it off.
- */
-#ifdef DEBUG
-const char *const debug_bit_names[] = {
- "raw",
- "crypt",
- "parsing",
- "emitting",
- "control",
- "lifecycle",
- "klips",
- "dns",
- "natt",
- "oppo",
- "controlmore",
-
- "private",
-
- "impair-delay-adns-key-answer",
- "impair-delay-adns-txt-answer",
- "impair-bust-mi2",
- "impair-bust-mr2",
-
- NULL
- };
-#endif
-
-/* State of exchanges */
-
-static const char *const state_name[] = {
- "STATE_MAIN_R0",
- "STATE_MAIN_I1",
- "STATE_MAIN_R1",
- "STATE_MAIN_I2",
- "STATE_MAIN_R2",
- "STATE_MAIN_I3",
- "STATE_MAIN_R3",
- "STATE_MAIN_I4",
-
- "STATE_QUICK_R0",
- "STATE_QUICK_I1",
- "STATE_QUICK_R1",
- "STATE_QUICK_I2",
- "STATE_QUICK_R2",
-
- "STATE_INFO",
- "STATE_INFO_PROTECTED",
-
- "STATE_XAUTH_I0",
- "STATE_XAUTH_R1",
- "STATE_XAUTH_I1",
- "STATE_XAUTH_R2",
- "STATE_XAUTH_I2",
- "STATE_XAUTH_R3",
-
- "STATE_MODE_CFG_R0",
- "STATE_MODE_CFG_I1",
- "STATE_MODE_CFG_R1",
- "STATE_MODE_CFG_I2",
-
- "STATE_MODE_CFG_I0",
- "STATE_MODE_CFG_R3",
- "STATE_MODE_CFG_I3",
- "STATE_MODE_CFG_R4",
-
- "STATE_IKE_ROOF"
- };
-
-enum_names state_names =
- { STATE_MAIN_R0, STATE_IKE_ROOF-1, state_name, NULL };
-
-/* story for state */
-
-const char *const state_story[] = {
- "expecting MI1", /* STATE_MAIN_R0 */
- "sent MI1, expecting MR1", /* STATE_MAIN_I1 */
- "sent MR1, expecting MI2", /* STATE_MAIN_R1 */
- "sent MI2, expecting MR2", /* STATE_MAIN_I2 */
- "sent MR2, expecting MI3", /* STATE_MAIN_R2 */
- "sent MI3, expecting MR3", /* STATE_MAIN_I3 */
- "sent MR3, ISAKMP SA established", /* STATE_MAIN_R3 */
- "ISAKMP SA established", /* STATE_MAIN_I4 */
-
- "expecting QI1", /* STATE_QUICK_R0 */
- "sent QI1, expecting QR1", /* STATE_QUICK_I1 */
- "sent QR1, inbound IPsec SA installed, expecting QI2", /* STATE_QUICK_R1 */
- "sent QI2, IPsec SA established", /* STATE_QUICK_I2 */
- "IPsec SA established", /* STATE_QUICK_R2 */
-
- "got Informational Message in clear", /* STATE_INFO */
- "got encrypted Informational Message", /* STATE_INFO_PROTECTED */
-
- "expecting XAUTH request", /* STATE_XAUTH_I0 */
- "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
- "sent XAUTH reply, expecting status", /* STATE_XAUTH_I1 */
- "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
- "sent XAUTH ack, established", /* STATE_XAUTH_I2 */
- "received XAUTH ack, established", /* STATE_XAUTH_R3 */
-
- "expecting ModeCfg request", /* STATE_MODE_CFG_R0 */
- "sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
- "sent ModeCfg reply, established", /* STATE_MODE_CFG_R1 */
- "received ModeCfg reply, established", /* STATE_MODE_CFG_I2 */
-
- "expecting ModeCfg set", /* STATE_MODE_CFG_I0 */
- "sent ModeCfg set, expecting ack", /* STATE_MODE_CFG_R3 */
- "sent ModeCfg ack, established", /* STATE_MODE_CFG_I3 */
- "received ModeCfg ack, established", /* STATE_MODE_CFG_R4 */
- };
-
-/* kind of struct connection */
-
-static const char *const connection_kind_name[] = {
- "CK_GROUP", /* policy group: instantiates to template */
- "CK_TEMPLATE", /* abstract connection, with wildcard */
- "CK_PERMANENT", /* normal connection */
- "CK_INSTANCE", /* instance of template, created for a particular attempt */
- "CK_GOING_AWAY" /* instance being deleted -- don't delete again */
-};
-
-enum_names connection_kind_names =
- { CK_GROUP, CK_GOING_AWAY, connection_kind_name, NULL };
-
-/* routing status names */
-
-static const char *const routing_story_strings[] = {
- "unrouted", /* RT_UNROUTED: unrouted */
- "unrouted HOLD", /* RT_UNROUTED_HOLD: unrouted, but HOLD shunt installed */
- "eroute eclipsed", /* RT_ROUTED_ECLIPSED: RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
- "prospective erouted", /* RT_ROUTED_PROSPECTIVE: routed, and prospective shunt installed */
- "erouted HOLD", /* RT_ROUTED_HOLD: routed, and HOLD shunt installed */
- "fail erouted", /* RT_ROUTED_FAILURE: routed, and failure-context shunt eroute installed */
- "erouted", /* RT_ROUTED_TUNNEL: routed, and erouted to an IPSEC SA group */
- "keyed, unrouted", /* RT_UNROUTED_KEYED: was routed+keyed, but it got turned into an outer policy */
- };
-
-enum_names routing_story =
- { RT_UNROUTED, RT_ROUTED_TUNNEL, routing_story_strings, NULL};
-
-/* Payload types (RFC 2408 "ISAKMP" section 3.1) */
-
-const char *const payload_name[] = {
- "ISAKMP_NEXT_NONE",
- "ISAKMP_NEXT_SA",
- "ISAKMP_NEXT_P",
- "ISAKMP_NEXT_T",
- "ISAKMP_NEXT_KE",
- "ISAKMP_NEXT_ID",
- "ISAKMP_NEXT_CERT",
- "ISAKMP_NEXT_CR",
- "ISAKMP_NEXT_HASH",
- "ISAKMP_NEXT_SIG",
- "ISAKMP_NEXT_NONCE",
- "ISAKMP_NEXT_N",
- "ISAKMP_NEXT_D",
- "ISAKMP_NEXT_VID",
- "ISAKMP_NEXT_MODECFG",
- "ISAKMP_NEXT_15",
- "ISAKMP_NEXT_16",
- "ISAKMP_NEXT_17",
- "ISAKMP_NEXT_18",
- "ISAKMP_NEXT_19",
- "ISAKMP_NEXT_NAT-D",
- "ISAKMP_NEXT_NAT-OA",
- NULL
- };
-
-const char *const payload_name_nat_d[] = { "ISAKMP_NEXT_NAT-D",
- "ISAKMP_NEXT_NAT-OA", NULL };
-
-static enum_names payload_names_nat_d =
- { ISAKMP_NEXT_NATD_DRAFTS, ISAKMP_NEXT_NATOA_DRAFTS, payload_name_nat_d, NULL };
-
-enum_names payload_names =
- { ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_nat_d };
-
-/* Exchange types (note: two discontinuous ranges) */
-
-static const char *const exchange_name[] = {
- "ISAKMP_XCHG_NONE",
- "ISAKMP_XCHG_BASE",
- "ISAKMP_XCHG_IDPROT",
- "ISAKMP_XCHG_AO",
- "ISAKMP_XCHG_AGGR",
- "ISAKMP_XCHG_INFO",
- "ISAKMP_XCHG_MODE_CFG",
- };
-
-static const char *const exchange_name2[] = {
- "ISAKMP_XCHG_QUICK",
- "ISAKMP_XCHG_NGRP",
- "ISAKMP_XCHG_ACK_INFO",
- };
-
-static enum_names exchange_desc2 =
- { ISAKMP_XCHG_QUICK, ISAKMP_XCHG_ACK_INFO, exchange_name2, NULL };
-
-enum_names exchange_names =
- { ISAKMP_XCHG_NONE, ISAKMP_XCHG_MODE_CFG, exchange_name, &exchange_desc2 };
-
-/* Flag BITS */
-const char *const flag_bit_names[] = {
- "ISAKMP_FLAG_ENCRYPTION",
- "ISAKMP_FLAG_COMMIT",
- NULL
- };
-
-/* Situation BITS definition for IPsec DOI */
-
-const char *const sit_bit_names[] = {
- "SIT_IDENTITY_ONLY",
- "SIT_SECRECY",
- "SIT_INTEGRITY",
- NULL
- };
-
-/* Protocol IDs (RFC 2407 "IPsec DOI" section 4.4.1) */
-
-static const char *const protocol_name[] = {
- "PROTO_ISAKMP",
- "PROTO_IPSEC_AH",
- "PROTO_IPSEC_ESP",
- "PROTO_IPCOMP",
- };
-
-enum_names protocol_names =
- { PROTO_ISAKMP, PROTO_IPCOMP, protocol_name, NULL };
-
-/* IPsec ISAKMP transform values */
-
-static const char *const isakmp_transform_name[] = {
- "KEY_IKE",
- };
-
-enum_names isakmp_transformid_names =
- { KEY_IKE, KEY_IKE, isakmp_transform_name, NULL };
-
-/* IPsec AH transform values */
-
-static const char *const ah_transform_name[] = {
- "AH_MD5",
- "AH_SHA",
- "AH_DES",
- "AH_SHA2_256",
- "AH_SHA2_384",
- "AH_SHA2_512",
- "AH_RIPEMD"
- };
-
-enum_names ah_transformid_names =
- { AH_MD5, AH_RIPEMD, ah_transform_name, NULL };
-
-/* IPsec ESP transform values */
-
-static const char *const esp_transform_name[] = {
- "ESP_DES_IV64",
- "ESP_DES",
- "ESP_3DES",
- "ESP_RC5",
- "ESP_IDEA",
- "ESP_CAST",
- "ESP_BLOWFISH",
- "ESP_3IDEA",
- "ESP_DES_IV32",
- "ESP_RC4",
- "ESP_NULL",
- "ESP_AES",
- "ESP_AES-CTR",
- "ESP_AES-CCM_8",
- "ESP_AES-CCM_12",
- "ESP_AES-CCM_16"
- };
-
-/*
- * ipsec drafts suggest "high" ESP ids values for testing,
- * assign generic ESP_ID<num> if not officially defined
- */
-static const char *const esp_transform_name_high[] = {
- "ESP_SERPENT",
- "ESP_TWOFISH"
- };
-
-enum_names esp_transformid_names_high =
- { ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
-
-enum_names esp_transformid_names =
- { ESP_DES_IV64, ESP_AES_CCM_16, esp_transform_name, &esp_transformid_names_high };
-
-/* IPCOMP transform values */
-
-static const char *const ipcomp_transform_name[] = {
- "IPCOMP_OUI",
- "IPCOMP_DEFLAT",
- "IPCOMP_LZS",
- "IPCOMP_LZJH",
- };
-
-enum_names ipcomp_transformid_names =
- { IPCOMP_OUI, IPCOMP_LZJH, ipcomp_transform_name, NULL };
-
-/* Identification type values */
-
-static const char *const ident_name[] = {
- "ID_IPV4_ADDR",
- "ID_FQDN",
- "ID_USER_FQDN",
- "ID_IPV4_ADDR_SUBNET",
- "ID_IPV6_ADDR",
- "ID_IPV6_ADDR_SUBNET",
- "ID_IPV4_ADDR_RANGE",
- "ID_IPV6_ADDR_RANGE",
- "ID_DER_ASN1_DN",
- "ID_DER_ASN1_GN",
- "ID_KEY_ID",
- };
-
-enum_names ident_names =
- { ID_IPV4_ADDR, ID_KEY_ID, ident_name, NULL };
-
-/* Certificate type values */
-
-static const char *const cert_type_name[] = {
- "CERT_NONE",
- "CERT_PKCS7_WRAPPED_X509",
- "CERT_PGP",
- "CERT_DNS_SIGNED_KEY",
- "CERT_X509_SIGNATURE",
- "CERT_X509_KEY_EXCHANGE",
- "CERT_KERBEROS_TOKENS",
- "CERT_CRL",
- "CERT_ARL",
- "CERT_SPKI",
- "CERT_X509_ATTRIBUTE",
- };
-
-enum_names cert_type_names =
- { CERT_NONE, CERT_X509_ATTRIBUTE, cert_type_name, NULL };
-
-/* Certificate policy names */
-
-static const char *const cert_policy_name[] = {
- "ALWAYS_SEND",
- "SEND_IF_ASKED",
- "NEVER_SEND",
- };
-
-enum_names cert_policy_names =
- { CERT_ALWAYS_SEND, CERT_NEVER_SEND, cert_policy_name, NULL };
-
-/* Goal BITs for establishing an SA
- * Note: we drop the POLICY_ prefix so that logs are more concise.
- */
-
-const char *const sa_policy_bit_names[] = {
- "PSK",
- "RSASIG",
- "ENCRYPT",
- "AUTHENTICATE",
- "COMPRESS",
- "TUNNEL",
- "PFS",
- "DISABLEARRIVALCHECK",
- "SHUNT0",
- "SHUNT1",
- "FAILSHUNT0",
- "FAILSHUNT1",
- "DONTREKEY",
- "OPPORTUNISTIC",
- "GROUP",
- "GROUTED",
- "UP",
- "MODECFGPUSH",
- "XAUTHPSK",
- "XAUTHRSASIG",
- "XAUTHSERVER",
- NULL
- };
-
-const char *const policy_shunt_names[4] = {
- "TRAP",
- "PASS",
- "DROP",
- "REJECT",
- };
-
-const char *const policy_fail_names[4] = {
- "NONE",
- "PASS",
- "DROP",
- "REJECT",
- };
-
-/* Oakley transform attributes
- * oakley_attr_bit_names does double duty: it is used for enum names
- * and bit names.
- */
-
-const char *const oakley_attr_bit_names[] = {
- "OAKLEY_ENCRYPTION_ALGORITHM",
- "OAKLEY_HASH_ALGORITHM",
- "OAKLEY_AUTHENTICATION_METHOD",
- "OAKLEY_GROUP_DESCRIPTION",
- "OAKLEY_GROUP_TYPE",
- "OAKLEY_GROUP_PRIME",
- "OAKLEY_GROUP_GENERATOR_ONE",
- "OAKLEY_GROUP_GENERATOR_TWO",
- "OAKLEY_GROUP_CURVE_A",
- "OAKLEY_GROUP_CURVE_B",
- "OAKLEY_LIFE_TYPE",
- "OAKLEY_LIFE_DURATION",
- "OAKLEY_PRF",
- "OAKLEY_KEY_LENGTH",
- "OAKLEY_FIELD_SIZE",
- "OAKLEY_GROUP_ORDER",
- "OAKLEY_BLOCK_SIZE",
- NULL
- };
-
-static const char *const oakley_var_attr_name[] = {
- "OAKLEY_GROUP_PRIME (variable length)",
- "OAKLEY_GROUP_GENERATOR_ONE (variable length)",
- "OAKLEY_GROUP_GENERATOR_TWO (variable length)",
- "OAKLEY_GROUP_CURVE_A (variable length)",
- "OAKLEY_GROUP_CURVE_B (variable length)",
- NULL,
- "OAKLEY_LIFE_DURATION (variable length)",
- NULL,
- NULL,
- NULL,
- "OAKLEY_GROUP_ORDER (variable length)",
- };
-
-static enum_names oakley_attr_desc_tv = {
- OAKLEY_ENCRYPTION_ALGORITHM + ISAKMP_ATTR_AF_TV,
- OAKLEY_GROUP_ORDER + ISAKMP_ATTR_AF_TV, oakley_attr_bit_names, NULL };
-
-enum_names oakley_attr_names = {
- OAKLEY_GROUP_PRIME, OAKLEY_GROUP_ORDER,
- oakley_var_attr_name, &oakley_attr_desc_tv };
-
-/* for each Oakley attribute, which enum_names describes its values? */
-enum_names *oakley_attr_val_descs[] = {
- NULL, /* (none) */
- &oakley_enc_names, /* OAKLEY_ENCRYPTION_ALGORITHM */
- &oakley_hash_names, /* OAKLEY_HASH_ALGORITHM */
- &oakley_auth_names, /* OAKLEY_AUTHENTICATION_METHOD */
- &oakley_group_names, /* OAKLEY_GROUP_DESCRIPTION */
- &oakley_group_type_names,/* OAKLEY_GROUP_TYPE */
- NULL, /* OAKLEY_GROUP_PRIME */
- NULL, /* OAKLEY_GROUP_GENERATOR_ONE */
- NULL, /* OAKLEY_GROUP_GENERATOR_TWO */
- NULL, /* OAKLEY_GROUP_CURVE_A */
- NULL, /* OAKLEY_GROUP_CURVE_B */
- &oakley_lifetime_names, /* OAKLEY_LIFE_TYPE */
- NULL, /* OAKLEY_LIFE_DURATION */
- &oakley_prf_names, /* OAKLEY_PRF */
- NULL, /* OAKLEY_KEY_LENGTH */
- NULL, /* OAKLEY_FIELD_SIZE */
- NULL, /* OAKLEY_GROUP_ORDER */
- };
-
-/* IPsec DOI attributes (RFC 2407 "IPsec DOI" section 4.5) */
-
-static const char *const ipsec_attr_name[] = {
- "SA_LIFE_TYPE",
- "SA_LIFE_DURATION",
- "GROUP_DESCRIPTION",
- "ENCAPSULATION_MODE",
- "AUTH_ALGORITHM",
- "KEY_LENGTH",
- "KEY_ROUNDS",
- "COMPRESS_DICT_SIZE",
- "COMPRESS_PRIVATE_ALG",
- };
-
-static const char *const ipsec_var_attr_name[] = {
- "SA_LIFE_DURATION (variable length)",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "COMPRESS_PRIVATE_ALG (variable length)",
- };
-
-static enum_names ipsec_attr_desc_tv = {
- SA_LIFE_TYPE + ISAKMP_ATTR_AF_TV,
- COMPRESS_PRIVATE_ALG + ISAKMP_ATTR_AF_TV,
- ipsec_attr_name, NULL };
-
-enum_names ipsec_attr_names = {
- SA_LIFE_DURATION, COMPRESS_PRIVATE_ALG,
- ipsec_var_attr_name, &ipsec_attr_desc_tv };
-
-/* for each IPsec attribute, which enum_names describes its values? */
-enum_names *ipsec_attr_val_descs[] = {
- NULL, /* (none) */
- &sa_lifetime_names, /* SA_LIFE_TYPE */
- NULL, /* SA_LIFE_DURATION */
- &oakley_group_names, /* GROUP_DESCRIPTION */
- &enc_mode_names, /* ENCAPSULATION_MODE */
- &auth_alg_names, /* AUTH_ALGORITHM */
- NULL, /* KEY_LENGTH */
- NULL, /* KEY_ROUNDS */
- NULL, /* COMPRESS_DICT_SIZE */
- NULL, /* COMPRESS_PRIVATE_ALG */
- };
-
-/* SA Lifetime Type attribute */
-
-static const char *const sa_lifetime_name[] = {
- "SA_LIFE_TYPE_SECONDS",
- "SA_LIFE_TYPE_KBYTES",
- };
-
-enum_names sa_lifetime_names =
- { SA_LIFE_TYPE_SECONDS, SA_LIFE_TYPE_KBYTES, sa_lifetime_name, NULL };
-
-/* Encapsulation Mode attribute */
-
-static const char *const enc_mode_name[] = {
- "ENCAPSULATION_MODE_TUNNEL",
- "ENCAPSULATION_MODE_TRANSPORT",
- "ENCAPSULATION_MODE_UDP_TUNNEL",
- "ENCAPSULATION_MODE_UDP_TRANSPORT",
- };
-
-static const char *const enc_udp_mode_name[] = {
- "ENCAPSULATION_MODE_UDP_TUNNEL",
- "ENCAPSULATION_MODE_UDP_TRANSPORT",
- };
-
-static enum_names enc_udp_mode_names =
- { ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS, ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS, enc_udp_mode_name, NULL };
-
-enum_names enc_mode_names =
- { ENCAPSULATION_MODE_TUNNEL, ENCAPSULATION_MODE_UDP_TRANSPORT_RFC, enc_mode_name, &enc_udp_mode_names };
-
-/* Auth Algorithm attribute */
-
-static const char *const auth_alg_name[] = {
- "AUTH_ALGORITHM_HMAC_MD5",
- "AUTH_ALGORITHM_HMAC_SHA1",
- "AUTH_ALGORITHM_DES_MAC",
- "AUTH_ALGORITHM_KPDK",
- "AUTH_ALGORITHM_HMAC_SHA2_256",
- "AUTH_ALGORITHM_HMAC_SHA2_384",
- "AUTH_ALGORITHM_HMAC_SHA2_512",
- "AUTH_ALGORITHM_HMAC_RIPEMD",
- };
-
-static const char *const extended_auth_alg_name[] = {
- "AUTH_ALGORITHM_NULL"
- };
-
-enum_names extended_auth_alg_names =
- { AUTH_ALGORITHM_NULL, AUTH_ALGORITHM_NULL, extended_auth_alg_name, NULL };
-
-enum_names auth_alg_names =
- { AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_HMAC_RIPEMD, auth_alg_name
- , &extended_auth_alg_names };
-
-/* From draft-beaulieu-ike-xauth */
-static const char *const xauth_type_name[] = {
- "Generic",
- "RADIUS-CHAP",
- "OTP",
- "S/KEY",
-};
-
-enum_names xauth_type_names =
- { XAUTH_TYPE_GENERIC, XAUTH_TYPE_SKEY, xauth_type_name, NULL};
-
-/* From draft-beaulieu-ike-xauth */
-static const char *const xauth_attr_tv_name[] = {
- "XAUTH_TYPE",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "XAUTH_STATUS",
- };
-
-enum_names xauth_attr_tv_names = {
- XAUTH_TYPE + ISAKMP_ATTR_AF_TV,
- XAUTH_STATUS + ISAKMP_ATTR_AF_TV, xauth_attr_tv_name, NULL };
-
-static const char *const unity_attr_name[] = {
- "UNITY_BANNER",
- "UNITY_SAVE_PASSWD",
- "UNITY_DEF_DOMAIN",
- "UNITY_SPLITDNS_NAME",
- "UNITY_SPLIT_INCLUDE",
- "UNITY_NATT_PORT",
- "UNITY_LOCAL_LAN",
- "UNITY_PFS",
- "UNITY_FW_TYPE",
- "UNITY_BACKUP_SERVERS",
- "UNITY_DDNS_HOSTNAME",
-};
-
-enum_names unity_attr_names =
- { UNITY_BANNER , UNITY_DDNS_HOSTNAME, unity_attr_name , &xauth_attr_tv_names };
-
-
-static const char *const xauth_attr_name[] = {
- "XAUTH_USER_NAME",
- "XAUTH_USER_PASSWORD",
- "XAUTH_PASSCODE",
- "XAUTH_MESSAGE",
- "XAUTH_CHALLENGE",
- "XAUTH_DOMAIN",
- "XAUTH_STATUS (wrong TLV syntax, should be TV)",
- "XAUTH_NEXT_PIN",
- "XAUTH_ANSWER",
- };
-
-enum_names xauth_attr_names =
- { XAUTH_USER_NAME , XAUTH_ANSWER, xauth_attr_name , &unity_attr_names };
-
-static const char *const modecfg_attr_name[] = {
- "INTERNAL_IP4_ADDRESS",
- "INTERNAL_IP4_NETMASK",
- "INTERNAL_IP4_DNS",
- "INTERNAL_IP4_NBNS",
- "INTERNAL_ADDRESS_EXPIRY",
- "INTERNAL_IP4_DHCP",
- "APPLICATION_VERSION",
- "INTERNAL_IP6_ADDRESS",
- "INTERNAL_IP6_NETMASK",
- "INTERNAL_IP6_DNS",
- "INTERNAL_IP6_NBNS",
- "INTERNAL_IP6_DHCP",
- "INTERNAL_IP4_SUBNET",
- "SUPPORTED_ATTRIBUTES",
- "INTERNAL_IP6_SUBNET",
- };
-
-enum_names modecfg_attr_names =
- { INTERNAL_IP4_ADDRESS, INTERNAL_IP6_SUBNET, modecfg_attr_name , &xauth_attr_names };
-
-/* Oakley Lifetime Type attribute */
-
-static const char *const oakley_lifetime_name[] = {
- "OAKLEY_LIFE_SECONDS",
- "OAKLEY_LIFE_KILOBYTES",
- };
-
-enum_names oakley_lifetime_names =
- { OAKLEY_LIFE_SECONDS, OAKLEY_LIFE_KILOBYTES, oakley_lifetime_name, NULL };
-
-/* Oakley PRF attribute (none defined) */
-
-enum_names oakley_prf_names =
- { 1, 0, NULL, NULL };
-
-/* Oakley Encryption Algorithm attribute */
-
-static const char *const oakley_enc_name[] = {
- "OAKLEY_DES_CBC",
- "OAKLEY_IDEA_CBC",
- "OAKLEY_BLOWFISH_CBC",
- "OAKLEY_RC5_R16_B64_CBC",
- "OAKLEY_3DES_CBC",
- "OAKLEY_CAST_CBC",
- "OAKLEY_AES_CBC",
- };
-
-#ifdef NO_EXTRA_IKE
-enum_names oakley_enc_names =
- { OAKLEY_DES_CBC, OAKLEY_AES_CBC, oakley_enc_name, NULL };
-#else
-static const char *const oakley_enc_name_draft_aes_cbc_02[] = {
- "OAKLEY_MARS_CBC" /* 65001 */,
- "OAKLEY_RC6_CBC" /* 65002 */,
- "OAKLEY_ID_65003" /* 65003 */,
- "OAKLEY_SERPENT_CBC" /* 65004 */,
- "OAKLEY_TWOFISH_CBC" /* 65005 */,
-};
-static const char *const oakley_enc_name_ssh[] = {
- "OAKLEY_TWOFISH_CBC_SSH",
-};
-enum_names oakley_enc_names_ssh =
- { OAKLEY_TWOFISH_CBC_SSH, OAKLEY_TWOFISH_CBC_SSH, oakley_enc_name_ssh
- , NULL };
-
-enum_names oakley_enc_names_draft_aes_cbc_02 =
- { OAKLEY_MARS_CBC, OAKLEY_TWOFISH_CBC, oakley_enc_name_draft_aes_cbc_02
- , &oakley_enc_names_ssh };
-
-enum_names oakley_enc_names =
- { OAKLEY_DES_CBC, OAKLEY_AES_CBC, oakley_enc_name
- , &oakley_enc_names_draft_aes_cbc_02 };
-#endif
-
-/* Oakley Hash Algorithm attribute */
-
-static const char *const oakley_hash_name[] = {
- "OAKLEY_MD5",
- "OAKLEY_SHA",
- "OAKLEY_TIGER",
- "OAKLEY_SHA2_256",
- "OAKLEY_SHA2_384",
- "OAKLEY_SHA2_512",
- };
-
-enum_names oakley_hash_names =
- { OAKLEY_MD5, OAKLEY_SHA2_512, oakley_hash_name, NULL };
-
-/* Oakley Authentication Method attribute */
-
-static const char *const oakley_auth_name1[] = {
- "OAKLEY_PRESHARED_KEY",
- "OAKLEY_DSS_SIG",
- "OAKLEY_RSA_SIG",
- "OAKLEY_RSA_ENC",
- "OAKLEY_RSA_ENC_REV",
- "OAKLEY_ELGAMAL_ENC",
- "OAKLEY_ELGAMAL_ENC_REV",
- };
-
-static const char *const oakley_auth_name2[] = {
- "HybridInitRSA",
- "HybridRespRSA",
- "HybridInitDSS",
- "HybridRespDSS",
- };
-
-static const char *const oakley_auth_name3[] = {
- "XAUTHInitPreShared",
- "XAUTHRespPreShared",
- "XAUTHInitDSS",
- "XAUTHRespDSS",
- "XAUTHInitRSA",
- "XAUTHRespRSA",
- "XAUTHInitRSAEncryption",
- "XAUTHRespRSAEncryption",
- "XAUTHInitRSARevisedEncryption",
- "XAUTHRespRSARevisedEncryption",
- };
-
-static enum_names oakley_auth_names1 =
- { OAKLEY_PRESHARED_KEY, OAKLEY_ELGAMAL_ENC_REV
- , oakley_auth_name1, NULL };
-
-static enum_names oakley_auth_names2 =
- { HybridInitRSA, HybridRespDSS
- , oakley_auth_name2, &oakley_auth_names1 };
-
-enum_names oakley_auth_names =
- { XAUTHInitPreShared, XAUTHRespRSARevisedEncryption
- , oakley_auth_name3, &oakley_auth_names2 };
-
-/* Oakley Group Description attribute */
-
-static const char *const oakley_group_name[] = {
- "OAKLEY_GROUP_MODP768",
- "OAKLEY_GROUP_MODP1024",
- "OAKLEY_GROUP_GP155",
- "OAKLEY_GROUP_GP185",
- "OAKLEY_GROUP_MODP1536",
- };
-
-static const char *const oakley_group_name_rfc3526[] = {
- "OAKLEY_GROUP_MODP2048",
- "OAKLEY_GROUP_MODP3072",
- "OAKLEY_GROUP_MODP4096",
- "OAKLEY_GROUP_MODP6144",
- "OAKLEY_GROUP_MODP8192"
-};
-enum_names oakley_group_names_rfc3526 =
- { OAKLEY_GROUP_MODP2048, OAKLEY_GROUP_MODP8192,
- oakley_group_name_rfc3526, NULL };
-
-enum_names oakley_group_names =
- { OAKLEY_GROUP_MODP768, OAKLEY_GROUP_MODP1536,
- oakley_group_name, &oakley_group_names_rfc3526 };
-
-/* Oakley Group Type attribute */
-
-static const char *const oakley_group_type_name[] = {
- "OAKLEY_GROUP_TYPE_MODP",
- "OAKLEY_GROUP_TYPE_ECP",
- "OAKLEY_GROUP_TYPE_EC2N",
- };
-
-enum_names oakley_group_type_names =
- { OAKLEY_GROUP_TYPE_MODP, OAKLEY_GROUP_TYPE_EC2N, oakley_group_type_name, NULL };
-
-/* Notify messages -- error types */
-
-static const char *const notification_name[] = {
- "INVALID_PAYLOAD_TYPE",
- "DOI_NOT_SUPPORTED",
- "SITUATION_NOT_SUPPORTED",
- "INVALID_COOKIE",
- "INVALID_MAJOR_VERSION",
- "INVALID_MINOR_VERSION",
- "INVALID_EXCHANGE_TYPE",
- "INVALID_FLAGS",
- "INVALID_MESSAGE_ID",
- "INVALID_PROTOCOL_ID",
- "INVALID_SPI",
- "INVALID_TRANSFORM_ID",
- "ATTRIBUTES_NOT_SUPPORTED",
- "NO_PROPOSAL_CHOSEN",
- "BAD_PROPOSAL_SYNTAX",
- "PAYLOAD_MALFORMED",
- "INVALID_KEY_INFORMATION",
- "INVALID_ID_INFORMATION",
- "INVALID_CERT_ENCODING",
- "INVALID_CERTIFICATE",
- "CERT_TYPE_UNSUPPORTED",
- "INVALID_CERT_AUTHORITY",
- "INVALID_HASH_INFORMATION",
- "AUTHENTICATION_FAILED",
- "INVALID_SIGNATURE",
- "ADDRESS_NOTIFICATION",
- "NOTIFY_SA_LIFETIME",
- "CERTIFICATE_UNAVAILABLE",
- "UNSUPPORTED_EXCHANGE_TYPE",
- "UNEQUAL_PAYLOAD_LENGTHS",
- };
-
-static const char *const notification_status_name[] = {
- "CONNECTED",
- };
-
-static const char *const ipsec_notification_name[] = {
- "IPSEC_RESPONDER_LIFETIME",
- "IPSEC_REPLAY_STATUS",
- "IPSEC_INITIAL_CONTACT",
- };
-
-static const char *const notification_dpd_name[] = {
- "R_U_THERE",
- "R_U_THERE_ACK",
-};
-
-enum_names notification_dpd_names =
- { R_U_THERE, R_U_THERE_ACK,
- notification_dpd_name, NULL };
-
-enum_names ipsec_notification_names =
- { IPSEC_RESPONDER_LIFETIME, IPSEC_INITIAL_CONTACT,
- ipsec_notification_name, &notification_dpd_names };
-
-enum_names notification_status_names =
- { CONNECTED, CONNECTED,
- notification_status_name, &ipsec_notification_names };
-
-enum_names notification_names =
- { INVALID_PAYLOAD_TYPE, UNEQUAL_PAYLOAD_LENGTHS,
- notification_name, &notification_status_names };
-
-/* MODECFG
- * From draft-dukes-ike-mode-cfg
- */
-const char *const attr_msg_type_name[] = {
- "ISAKMP_CFG_RESERVED",
- "ISAKMP_CFG_REQUEST",
- "ISAKMP_CFG_REPLY",
- "ISAKMP_CFG_SET",
- "ISAKMP_CFG_ACK",
- NULL
- };
-
-enum_names attr_msg_type_names =
- { 0 , ISAKMP_CFG_ACK, attr_msg_type_name , NULL };
-
-/* socket address family info */
-
-static const char *const af_inet_name[] = {
- "AF_INET",
- };
-
-static const char *const af_inet6_name[] = {
- "AF_INET6",
- };
-
-static enum_names af_names6 = { AF_INET6, AF_INET6, af_inet6_name, NULL };
-
-enum_names af_names = { AF_INET, AF_INET, af_inet_name, &af_names6 };
-
-static ip_address ipv4_any, ipv6_any;
-static ip_subnet ipv4_wildcard, ipv6_wildcard;
-static ip_subnet ipv4_all, ipv6_all;
-
-const struct af_info af_inet4_info = {
- AF_INET,
- "AF_INET",
- sizeof(struct in_addr),
- sizeof(struct sockaddr_in),
- 32,
- ID_IPV4_ADDR, ID_IPV4_ADDR_SUBNET, ID_IPV4_ADDR_RANGE,
- &ipv4_any, &ipv4_wildcard, &ipv4_all,
- };
-
-const struct af_info af_inet6_info = {
- AF_INET6,
- "AF_INET6",
- sizeof(struct in6_addr),
- sizeof(struct sockaddr_in6),
- 128,
- ID_IPV6_ADDR, ID_IPV6_ADDR_SUBNET, ID_IPV6_ADDR_RANGE,
- &ipv6_any, &ipv6_wildcard, &ipv6_all,
- };
-
-const struct af_info *
-aftoinfo(int af)
-{
- switch (af)
- {
- case AF_INET:
- return &af_inet4_info;
- case AF_INET6:
- return &af_inet6_info;
- default:
- return NULL;
- }
-}
-
-bool
-subnetisnone(const ip_subnet *sn)
-{
- ip_address base;
-
- networkof(sn, &base);
- return isanyaddr(&base) && subnetishost(sn);
-}
-
-/* BIND enumerated types */
-
-#include <arpa/nameser.h>
-
-static const char *const rr_type_name[] = {
- "T_A", /* 1 host address */
- "T_NS", /* 2 authoritative server */
- "T_MD", /* 3 mail destination */
- "T_MF", /* 4 mail forwarder */
- "T_CNAME", /* 5 canonical name */
- "T_SOA", /* 6 start of authority zone */
- "T_MB", /* 7 mailbox domain name */
- "T_MG", /* 8 mail group member */
- "T_MR", /* 9 mail rename name */
- "T_NULL", /* 10 null resource record */
- "T_WKS", /* 11 well known service */
- "T_PTR", /* 12 domain name pointer */
- "T_HINFO", /* 13 host information */
- "T_MINFO", /* 14 mailbox information */
- "T_MX", /* 15 mail routing information */
- "T_TXT", /* 16 text strings */
- "T_RP", /* 17 responsible person */
- "T_AFSDB", /* 18 AFS cell database */
- "T_X25", /* 19 X_25 calling address */
- "T_ISDN", /* 20 ISDN calling address */
- "T_RT", /* 21 router */
- "T_NSAP", /* 22 NSAP address */
- "T_NSAP_PTR", /* 23 reverse NSAP lookup (deprecated) */
- "T_SIG", /* 24 security signature */
- "T_KEY", /* 25 security key */
- "T_PX", /* 26 X.400 mail mapping */
- "T_GPOS", /* 27 geographical position (withdrawn) */
- "T_AAAA", /* 28 IP6 Address */
- "T_LOC", /* 29 Location Information */
- "T_NXT", /* 30 Next Valid Name in Zone */
- "T_EID", /* 31 Endpoint identifier */
- "T_NIMLOC", /* 32 Nimrod locator */
- "T_SRV", /* 33 Server selection */
- "T_ATMA", /* 34 ATM Address */
- "T_NAPTR", /* 35 Naming Authority PoinTeR */
- NULL
- };
-
-enum_names rr_type_names = { T_A, T_NAPTR, rr_type_name, NULL };
-
-/* Query type values which do not appear in resource records */
-static const char *const rr_qtype_name[] = {
- "T_IXFR", /* 251 incremental zone transfer */
- "T_AXFR", /* 252 transfer zone of authority */
- "T_MAILB", /* 253 transfer mailbox records */
- "T_MAILA", /* 254 transfer mail agent records */
- "T_ANY", /* 255 wildcard match */
- NULL
- };
-
-enum_names rr_qtype_names = { T_IXFR, T_ANY, rr_qtype_name, &rr_type_names };
-
-static const char *const rr_class_name[] = {
- "C_IN", /* 1 the arpa internet */
- NULL
- };
-
-enum_names rr_class_names = { C_IN, C_IN, rr_class_name, NULL };
-
-/*
- * NAT-Traversal defines for nat_traveral type from nat_traversal.h
- *
- */
-const char *const natt_type_bitnames[] = {
- "draft-ietf-ipsec-nat-t-ike-00/01", /* 0 */
- "draft-ietf-ipsec-nat-t-ike-02/03",
- "RFC 3947",
- "3", /* 3 */
- "4", "5", "6", "7",
- "8", "9", "10", "11",
- "12", "13", "14", "15",
- "16", "17", "18", "19",
- "20", "21", "22", "23",
- "24", "25", "26", "27",
- "28", "29",
- "nat is behind me",
- "nat is behind peer"
-};
-
-/* look up enum names in an enum_names */
-
-const char *
-enum_name(enum_names *ed, unsigned long val)
-{
- enum_names *p;
-
- for (p = ed; p != NULL; p = p->en_next_range)
- {
- if (p->en_first <= val && val <= p->en_last)
- return p->en_names[val - p->en_first];
- }
- return NULL;
-}
-
-/* find or construct a string to describe an enum value
- * Result may be in STATIC buffer!
- */
-const char *
-enum_show(enum_names *ed, unsigned long val)
-{
- const char *p = enum_name(ed, val);
-
- if (p == NULL)
- {
- static char buf[12]; /* only one! I hope that it is big enough */
-
- snprintf(buf, sizeof(buf), "%lu??", val);
- p = buf;
- }
- return p;
-}
-
-
-static char bitnamesbuf[200]; /* only one! I hope that it is big enough! */
-
-int
-enum_search(enum_names *ed, const char *str)
-{
- enum_names *p;
- const char *ptr;
- unsigned en;
-
- for (p = ed; p != NULL; p = p->en_next_range)
- for (en = p->en_first; en <= p->en_last ;en++)
- {
- ptr = p->en_names[en - p->en_first];
- if (ptr == 0) continue;
- /* if (strncmp(ptr, str, strlen(ptr))==0) */
- if (strcmp(ptr, str) == 0)
- return en;
- }
- return -1;
-}
-
-/* construct a string to name the bits on in a set
- * Result may be in STATIC buffer!
- * Note: prettypolicy depends on internal details.
- */
-const char *
-bitnamesof(const char *const table[], lset_t val)
-{
- char *p = bitnamesbuf;
- lset_t bit;
- const char *const *tp;
-
- if (val == 0)
- return "none";
-
- for (tp = table, bit = 01; val != 0; bit <<= 1)
- {
- if (val & bit)
- {
- const char *n = *tp;
- size_t nl;
-
- if (n == NULL || *n == '\0')
- {
- /* no name for this bit, so use hex */
- static char flagbuf[sizeof("0x80000000")];
-
- snprintf(flagbuf, sizeof(flagbuf), "0x%llx", bit);
- n = flagbuf;
- }
-
- nl = strlen(n);
-
- if (p != bitnamesbuf && p < bitnamesbuf+sizeof(bitnamesbuf) - 1)
- *p++ = '+';
-
- if (bitnamesbuf+sizeof(bitnamesbuf) - p > (ptrdiff_t)nl)
- {
- strcpy(p, n);
- p += nl;
- }
- val -= bit;
- }
- if (*tp != NULL)
- tp++; /* move on, but not past end */
- }
- *p = '\0';
- return bitnamesbuf;
-}
-
-/* print a policy: like bitnamesof, but it also does the non-bitfields.
- * Suppress the shunt and fail fields if 0.
- */
-const char *
-prettypolicy(lset_t policy)
-{
- const char *bn = bitnamesof(sa_policy_bit_names
- , policy & ~(POLICY_SHUNT_MASK | POLICY_FAIL_MASK));
- size_t len;
- lset_t shunt = (policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT;
- lset_t fail = (policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT;
-
- if (bn != bitnamesbuf)
- bitnamesbuf[0] = '\0';
- len = strlen(bitnamesbuf);
- if (shunt != 0)
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+%s"
- , policy_shunt_names[shunt]);
- len += strlen(bitnamesbuf + len);
- }
- if (fail != 0)
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+failure%s"
- , policy_fail_names[fail]);
- len += strlen(bitnamesbuf + len);
- }
- if (NEVER_NEGOTIATE(policy))
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+NEVER_NEGOTIATE");
- len += strlen(bitnamesbuf + len);
- }
- return bitnamesbuf;
-}
-
-/* test a set by seeing if all bits have names */
-
-bool
-testset(const char *const table[], lset_t val)
-{
- lset_t bit;
- const char *const *tp;
-
- for (tp = table, bit = 01; val != 0; bit <<= 1, tp++)
- {
- const char *n = *tp;
-
- if (n == NULL || ((val & bit) && *n == '\0'))
- return FALSE;
- val &= ~bit;
- }
- return TRUE;
-}
-
-
-const char sparse_end[] = "end of sparse names";
-
-/* look up enum names in a sparse_names */
-const char *sparse_name(sparse_names sd, unsigned long val)
-{
- const struct sparse_name *p;
-
- for (p = sd; p->name != sparse_end; p++)
- if (p->val == val)
- return p->name;
- return NULL;
-}
-
-/* find or construct a string to describe an sparse value
- * Result may be in STATIC buffer!
- */
-const char *
-sparse_val_show(sparse_names sd, unsigned long val)
-{
- const char *p = sparse_name(sd, val);
-
- if (p == NULL)
- {
- static char buf[12]; /* only one! I hope that it is big enough */
-
- snprintf(buf, sizeof(buf), "%lu??", val);
- p = buf;
- }
- return p;
-}
-
-void init_constants(void)
-{
- happy(anyaddr(AF_INET, &ipv4_any));
- happy(anyaddr(AF_INET6, &ipv6_any));
-
- happy(addrtosubnet(&ipv4_any, &ipv4_wildcard));
- happy(addrtosubnet(&ipv6_any, &ipv6_wildcard));
-
- happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
- happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
-}
diff --git a/programs/pluto/constants.h b/programs/pluto/constants.h
deleted file mode 100644
index 1fbfad1da..000000000
--- a/programs/pluto/constants.h
+++ /dev/null
@@ -1,1264 +0,0 @@
-
-/* manifest constants
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: constants.h,v 1.28 2007/02/21 14:21:48 as Exp $
- */
-
-#ifndef _CONSTANTS_H
-#define _CONSTANTS_H
-
-extern const char compile_time_interop_options[];
-
-extern void init_constants(void);
-
-/*
- * NOTE:For debugging purposes, constants.c has tables to map numbers back to names.
- * Any changes here should be reflected there.
- */
-
-#define elemsof(array) (sizeof(array) / sizeof(*(array))) /* number of elements in an array */
-
-/* Many routines return only success or failure, but wish to describe
- * the failure in a message. We use the convention that they return
- * a NULL on success and a pointer to constant string on failure.
- * The fact that the string is a constant is limiting, but it
- * avoids storage management issues: the recipient is allowed to assume
- * that the string will live "long enough" (usually forever).
- * <freeswan.h> defines err_t for this return type.
- */
-
-typedef int bool;
-#define FALSE 0
-#define TRUE 1
-
-#define NULL_FD (-1) /* NULL file descriptor */
-#define dup_any(fd) ((fd) == NULL_FD? NULL_FD : dup(fd))
-#define close_any(fd) { if ((fd) != NULL_FD) { close(fd); (fd) = NULL_FD; } }
-
-#define BITS_PER_BYTE 8
-
-#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
-#define strcaseeq(a, b) (strcasecmp((a), (b)) == 0) /* clearer shorthand */
-
-/* set type with room for at least 64 elements for ALG opts (was 32 in stock FS) */
-
-typedef unsigned long long lset_t;
-#define LEMPTY 0ULL
-#define LELEM(opt) (1ULL << (opt))
-#define LRANGE(lwb, upb) LRANGES(LELEM(lwb), LELEM(upb))
-#define LRANGES(first, last) (last - first + last)
-#define LHAS(set, elem) ((LELEM(elem) & (set)) != LEMPTY)
-#define LIN(subset, set) (((subset) & (set)) == (subset))
-#define LDISJOINT(a, b) (((a) & (b)) == LEMPTY)
-
-/* Control and lock pathnames */
-
-#ifndef DEFAULT_CTLBASE
-# define DEFAULT_CTLBASE "/var/run/pluto"
-#endif
-
-#define CTL_SUFFIX ".ctl" /* for UNIX domain socket pathname */
-#define LOCK_SUFFIX ".pid" /* for pluto's lock */
-#define INFO_SUFFIX ".info" /* for UNIX domain socket for apps */
-
-/* Routines to check and display values.
- *
- * An enum_names describes an enumeration.
- * enum_name() returns the name of an enum value, or NULL if invalid.
- * enum_show() is like enum_name, except it formats a numeric representation
- * for any invalid value (in a static area!)
- *
- * bitnames() formats a display of a set of named bits (in a static area)
- */
-
-struct enum_names {
- unsigned long en_first; /* first value in range */
- unsigned long en_last; /* last value in range (inclusive) */
- const char *const *en_names;
- const struct enum_names *en_next_range; /* descriptor of next range */
-};
-
-typedef const struct enum_names enum_names;
-
-extern const char *enum_name(enum_names *ed, unsigned long val);
-extern const char *enum_show(enum_names *ed, unsigned long val);
-extern int enum_search(enum_names *ed, const char *string);
-
-extern bool testset(const char *const table[], lset_t val);
-extern const char *bitnamesof(const char *const table[], lset_t val);
-
-/* sparse_names is much like enum_names, except values are
- * not known to be contiguous or ordered.
- * The array of names is ended with one with the name sparse_end
- * (this avoids having to reserve a value to signify the end).
- * Often appropriate for enums defined by others.
- */
-struct sparse_name {
- unsigned long val;
- const char *const name;
-};
-typedef const struct sparse_name sparse_names[];
-
-extern const char *sparse_name(sparse_names sd, unsigned long val);
-extern const char *sparse_val_show(sparse_names sd, unsigned long val);
-extern const char sparse_end[];
-
-#define FULL_INET_ADDRESS_SIZE 6
-
-/* Group parameters from draft-ietf-ike-01.txt section 6 */
-
-#define MODP_GENERATOR "2"
-
-#define MODP768_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF"
-
-#define MODP1024_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED " \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 " \
- "FFFFFFFF FFFFFFFF"
-
-#define MODP1536_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED " \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D " \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F " \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D " \
- "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF "
-
-/* draft-ietf-ipsec-ike-modp-groups-03.txt */
-#define MODP2048_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"
-
-#define MODP3072_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"
-
-#define MODP4096_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" \
- "FFFFFFFF FFFFFFFF"
-
-/* copy&pasted from rfc3526: */
-#define MODP6144_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08" \
- "8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B" \
- "302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9" \
- "A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6" \
- "49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8" \
- "FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C" \
- "180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718" \
- "3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D" \
- "04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D" \
- "B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226" \
- "1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC" \
- "E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26" \
- "99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB" \
- "04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2" \
- "233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127" \
- "D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406" \
- "AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918" \
- "DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151" \
- "2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03" \
- "F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F" \
- "BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B" \
- "B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632" \
- "387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E" \
- "6DCC4024 FFFFFFFF FFFFFFFF"
-
-/* copy&pasted from rfc3526: */
-#define MODP8192_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \
- "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \
- "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \
- "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \
- "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \
- "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \
- "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \
- "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \
- "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \
- "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" \
- "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" \
- "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" \
- "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" \
- "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" \
- "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" \
- "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" \
- "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" \
- "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" \
- "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" \
- "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" \
- "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"
-#define LOCALSECRETSIZE (256 / BITS_PER_BYTE)
-
-/* limits on nonce sizes. See RFC2409 "The internet key exchange (IKE)" 5 */
-#define MINIMUM_NONCE_SIZE 8 /* bytes */
-#define DEFAULT_NONCE_SIZE 16 /* bytes */
-#define MAXIMUM_NONCE_SIZE 256 /* bytes */
-
-#define COOKIE_SIZE 8
-#define MAX_ISAKMP_SPI_SIZE 16
-
-#define MD2_DIGEST_SIZE (128 / BITS_PER_BYTE)
-#define MD5_DIGEST_SIZE (128 / BITS_PER_BYTE)
-#define SHA1_DIGEST_SIZE (160 / BITS_PER_BYTE)
-#define SHA2_256_DIGEST_SIZE (256 / BITS_PER_BYTE)
-#define SHA2_384_DIGEST_SIZE (384 / BITS_PER_BYTE)
-#define SHA2_512_DIGEST_SIZE (512 / BITS_PER_BYTE)
-
-#define MD5_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA1_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA2_256_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA2_384_BLOCK_SIZE (1024 / BITS_PER_BYTE)
-#define SHA2_512_BLOCK_SIZE (1024 / BITS_PER_BYTE)
-
-#define DES_CBC_BLOCK_SIZE (64 / BITS_PER_BYTE)
-
-#define DSS_QBITS 160 /* bits in DSS's "q" (FIPS 186-1) */
-
-/* Maximum is required for SHA2_512 */
-#define MAX_DIGEST_LEN SHA2_512_DIGEST_SIZE
-#define MAX_HASH_BLOCK_SIZE SHA2_512_BLOCK_SIZE
-
-/* RFC 2404 "HMAC-SHA-1-96" section 3 */
-#define HMAC_SHA1_KEY_LEN SHA1_DIGEST_SIZE
-
-/* RFC 2403 "HMAC-MD5-96" section 3 */
-#define HMAC_MD5_KEY_LEN MD5_DIGEST_SIZE
-
-#define IKE_UDP_PORT 500
-
-/* RFC 2560 OCSP - certificate status */
-
-typedef enum {
- CERT_GOOD = 0,
- CERT_REVOKED = 1,
- CERT_UNKNOWN = 2,
- CERT_UNDEFINED = 3
-} cert_status_t;
-
-/* RFC 2459 CRL reason codes */
-
-extern enum_names crl_reason_names;
-
-typedef enum {
- REASON_UNSPECIFIED = 0,
- REASON_KEY_COMPROMISE = 1,
- REASON_CA_COMPROMISE = 2,
- REASON_AFFILIATION_CHANGED = 3,
- REASON_SUPERSEDED = 4,
- REASON_CESSATION_OF_OPERATON = 5,
- REASON_CERTIFICATE_HOLD = 6,
- REASON_REMOVE_FROM_CRL = 8
-} crl_reason_t;
-
-/* RFC 3706 Dead Peer Detection */
-
-extern enum_names dpd_action_names;
-
-typedef enum {
- DPD_ACTION_NONE = 0,
- DPD_ACTION_CLEAR = 1,
- DPD_ACTION_HOLD = 2,
- DPD_ACTION_RESTART = 3,
- DPD_ACTION_UNKNOWN = 4
-} dpd_action_t;
-
-/* Timer events */
-
-extern enum_names timer_event_names;
-
-enum event_type {
- EVENT_NULL, /* non-event */
- EVENT_REINIT_SECRET, /* Refresh cookie secret */
-#ifdef KLIPS
- EVENT_SHUNT_SCAN, /* scan shunt eroutes known to kernel */
-#endif
- EVENT_SO_DISCARD, /* discard unfinished state object */
- EVENT_RETRANSMIT, /* Retransmit packet */
- EVENT_SA_REPLACE, /* SA replacement event */
- EVENT_SA_REPLACE_IF_USED, /* SA replacement event */
- EVENT_SA_EXPIRE, /* SA expiration event */
- EVENT_NAT_T_KEEPALIVE, /* NAT Traversal Keepalive */
- EVENT_DPD, /* dead peer detection */
- EVENT_DPD_TIMEOUT, /* dead peer detection timeout */
- EVENT_LOG_DAILY /* reset certain log events/stats */
-};
-
-#define EVENT_REINIT_SECRET_DELAY 3600 /* 1 hour */
-#define EVENT_RETRANSMIT_DELAY_0 10 /* 10 seconds */
-
-/* Misc. stuff */
-
-#define MAXIMUM_RETRANSMISSIONS 2
-#define MAXIMUM_RETRANSMISSIONS_INITIAL 20
-
-#define MAX_INPUT_UDP_SIZE 65536
-#define MAX_OUTPUT_UDP_SIZE 65536
-
-/* Version numbers */
-
-#define ISAKMP_MAJOR_VERSION 0x1
-#define ISAKMP_MINOR_VERSION 0x0
-
-extern enum_names version_names;
-
-/* Domain of Interpretation */
-
-extern enum_names doi_names;
-
-#define ISAKMP_DOI_ISAKMP 0
-#define ISAKMP_DOI_IPSEC 1
-
-/* IPsec DOI things */
-
-#define IPSEC_DOI_SITUATION_LENGTH 4
-#define IPSEC_DOI_LDI_LENGTH 4
-#define IPSEC_DOI_SPI_SIZE 4
-
-/* SPI value 0 is invalid and values 1-255 are reserved to IANA.
- * ESP: RFC 2402 2.4; AH: RFC 2406 2.1
- * IPComp RFC 2393 substitutes a CPI in the place of an SPI.
- * see also draft-shacham-ippcp-rfc2393bis-05.txt.
- * We (FreeS/WAN) reserve 0x100 to 0xFFF for manual keying, so
- * Pluto won't generate these values.
- */
-#define IPSEC_DOI_SPI_MIN 0x100
-#define IPSEC_DOI_SPI_OUR_MIN 0x1000
-
-/* debugging settings: a set of selections for reporting
- * These would be more naturally situated in log.h,
- * but they are shared with whack.
- * IMPAIR_* actually change behaviour, usually badly,
- * to aid in testing. Naturally, these are not included in ALL.
- *
- * NOTE: changes here must be done in concert with changes to DBGOPT_*
- * in whack.c. A change to WHACK_MAGIC in whack.h will be required too.
- */
-#ifdef DEBUG
-extern const char *const debug_bit_names[];
-#endif
-
-#define DBG_RAW LELEM(0) /* raw packet I/O */
-#define DBG_CRYPT LELEM(1) /* encryption/decryption of messages */
-#define DBG_PARSING LELEM(2) /* show decoding of messages */
-#define DBG_EMITTING LELEM(3) /* show encoding of messages */
-#define DBG_CONTROL LELEM(4) /* control flow within Pluto */
-#define DBG_LIFECYCLE LELEM(5) /* SA lifecycle */
-#define DBG_KLIPS LELEM(6) /* messages to KLIPS */
-#define DBG_DNS LELEM(7) /* DNS activity */
-#define DBG_NATT LELEM(8) /* NAT-T */
-#define DBG_OPPO LELEM(9) /* opportunism */
-#define DBG_CONTROLMORE LELEM(10) /* more detailed debugging */
-
-#define DBG_PRIVATE LELEM(11) /* private information: DANGER! */
-
-#define IMPAIR0 12 /* first bit for IMPAIR_* */
-
-#define IMPAIR_DELAY_ADNS_KEY_ANSWER LELEM(IMPAIR0+0) /* sleep before answering */
-#define IMPAIR_DELAY_ADNS_TXT_ANSWER LELEM(IMPAIR0+1) /* sleep before answering */
-#define IMPAIR_BUST_MI2 LELEM(IMPAIR0+2) /* make MI2 really large */
-#define IMPAIR_BUST_MR2 LELEM(IMPAIR0+3) /* make MI2 really large */
-
-#define DBG_NONE 0 /* no options on, including impairments */
-#define DBG_ALL LRANGES(DBG_RAW, DBG_CONTROLMORE) /* all logging options on EXCEPT DBG_PRIVATE */
-
-/* State of exchanges
- *
- * The name of the state describes the last message sent, not the
- * message currently being input or output (except during retry).
- * In effect, the state represents the last completed action.
- *
- * Messages are named [MQ][IR]n where
- * - M stands for Main Mode (Phase 1);
- * Q stands for Quick Mode (Phase 2)
- * - I stands for Initiator;
- * R stands for Responder
- * - n, a digit, stands for the number of the message
- *
- * It would be more convenient if each state accepted a message
- * and produced one. This is the case for states at the start
- * or end of an exchange. To fix this, we pretend that there are
- * MR0 and QR0 messages before the MI1 and QR1 messages. Similarly,
- * we pretend that there are MR4 and QR2 messages.
- *
- * STATE_MAIN_R0 and STATE_QUICK_R0 are intermediate states (not
- * retained between messages) representing the state that accepts the
- * first message of an exchange has been read but not processed.
- *
- * state_microcode state_microcode_table in demux.c describes
- * other important details.
- */
-
-extern enum_names state_names;
-extern const char *const state_story[];
-
-enum state_kind {
- STATE_UNDEFINED, /* 0 -- most likely accident */
-
- /* Opportunism states: see "Opportunistic Encryption" 2.2 */
-
- OPPO_ACQUIRE, /* got an ACQUIRE message for this pair */
- OPPO_GW_DISCOVERED, /* got TXT specifying gateway */
-
- /* IKE states */
-
- STATE_MAIN_R0,
- STATE_MAIN_I1,
- STATE_MAIN_R1,
- STATE_MAIN_I2,
- STATE_MAIN_R2,
- STATE_MAIN_I3,
- STATE_MAIN_R3,
- STATE_MAIN_I4,
-
- STATE_QUICK_R0,
- STATE_QUICK_I1,
- STATE_QUICK_R1,
- STATE_QUICK_I2,
- STATE_QUICK_R2,
-
- STATE_INFO,
- STATE_INFO_PROTECTED,
-
- /* XAUTH states */
-
- STATE_XAUTH_I0, /* initiator state (client) */
- STATE_XAUTH_R1, /* responder state (server) */
- STATE_XAUTH_I1,
- STATE_XAUTH_R2,
- STATE_XAUTH_I2,
- STATE_XAUTH_R3,
-
- /* Mode Config pull states */
-
- STATE_MODE_CFG_R0, /* responder state (server) */
- STATE_MODE_CFG_I1, /* initiator state (client) */
- STATE_MODE_CFG_R1,
- STATE_MODE_CFG_I2,
-
- /* Mode Config push states */
-
- STATE_MODE_CFG_I0, /* initiator state (client) */
- STATE_MODE_CFG_R3, /* responder state (server) */
- STATE_MODE_CFG_I3,
- STATE_MODE_CFG_R4,
-
- STATE_IKE_ROOF
-};
-
-#define STATE_IKE_FLOOR STATE_MAIN_R0
-
-#define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
- | LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
-#define ISAKMP_SA_ESTABLISHED_STATES ( \
- LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
- | LELEM(STATE_XAUTH_R1) | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
- | LELEM(STATE_XAUTH_I1) | LELEM(STATE_XAUTH_I2) \
- | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
- | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
-
-#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
- || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
- || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
-
-#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
-#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
-
-#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
- (s) == STATE_MAIN_R3 \
- || (s) == STATE_MAIN_I4 \
- || (s) == STATE_XAUTH_I2 \
- || (s) == STATE_XAUTH_R3 \
- || (s) == STATE_MODE_CFG_R1 \
- || (s) == STATE_MODE_CFG_I2 \
- || (s) == STATE_MODE_CFG_I3 \
- || (s) == STATE_MODE_CFG_R4)
-
-#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
-#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
-
-/* kind of struct connection
- * Ordered (mostly) by concreteness. Order is exploited.
- */
-
-extern enum_names connection_kind_names;
-
-enum connection_kind {
- CK_GROUP, /* policy group: instantiates to template */
- CK_TEMPLATE, /* abstract connection, with wildcard */
- CK_PERMANENT, /* normal connection */
- CK_INSTANCE, /* instance of template, created for a particular attempt */
- CK_GOING_AWAY /* instance being deleted -- don't delete again */
-};
-
-
-/* routing status.
- * Note: routing ignores source address, but erouting does not!
- * Note: a connection can only be routed if it is NEVER_NEGOTIATE
- * or HAS_IPSEC_POLICY.
- */
-
-extern enum_names routing_story;
-
-/* note that this is assumed to be ordered! */
-enum routing_t {
- RT_UNROUTED, /* unrouted */
- RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
- RT_ROUTED_ECLIPSED, /* RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
- RT_ROUTED_PROSPECTIVE, /* routed, and prospective shunt installed */
- RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
- RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
- RT_ROUTED_TUNNEL, /* routed, and erouted to an IPSEC SA group */
- RT_UNROUTED_KEYED /* keyed, but not routed, on purpose */
-};
-
-#define routed(rs) ((rs) > RT_UNROUTED_HOLD)
-#define erouted(rs) ((rs) != RT_UNROUTED)
-#define shunt_erouted(rs) (erouted(rs) && (rs) != RT_ROUTED_TUNNEL)
-
-/* Payload types
- * RFC2408 Internet Security Association and Key Management Protocol (ISAKMP)
- * section 3.1
- *
- * RESERVED 14-127
- * Private USE 128-255
- */
-
-extern enum_names payload_names;
-extern const char *const payload_name[];
-
-#define ISAKMP_NEXT_NONE 0 /* No other payload following */
-#define ISAKMP_NEXT_SA 1 /* Security Association */
-#define ISAKMP_NEXT_P 2 /* Proposal */
-#define ISAKMP_NEXT_T 3 /* Transform */
-#define ISAKMP_NEXT_KE 4 /* Key Exchange */
-#define ISAKMP_NEXT_ID 5 /* Identification */
-#define ISAKMP_NEXT_CERT 6 /* Certificate */
-#define ISAKMP_NEXT_CR 7 /* Certificate Request */
-#define ISAKMP_NEXT_HASH 8 /* Hash */
-#define ISAKMP_NEXT_SIG 9 /* Signature */
-#define ISAKMP_NEXT_NONCE 10 /* Nonce */
-#define ISAKMP_NEXT_N 11 /* Notification */
-#define ISAKMP_NEXT_D 12 /* Delete */
-#define ISAKMP_NEXT_VID 13 /* Vendor ID */
-#define ISAKMP_NEXT_ATTR 14 /* Mode config Attribute */
-
-#define ISAKMP_NEXT_NATD_RFC 20 /* NAT-Traversal: NAT-D (rfc) */
-#define ISAKMP_NEXT_NATOA_RFC 21 /* NAT-Traversal: NAT-OA (rfc) */
-#define ISAKMP_NEXT_ROOF 22 /* roof on payload types */
-
-#define ISAKMP_NEXT_NATD_DRAFTS 130 /* NAT-Traversal: NAT-D (drafts) */
-#define ISAKMP_NEXT_NATOA_DRAFTS 131 /* NAT-Traversal: NAT-OA (drafts) */
-
-/* These values are to be used within the Type field of an Attribute (14)
- * ISAKMP payload.
- */
-#define ISAKMP_CFG_REQUEST 1
-#define ISAKMP_CFG_REPLY 2
-#define ISAKMP_CFG_SET 3
-#define ISAKMP_CFG_ACK 4
-
-extern enum_names attr_msg_type_names;
-
-/* Mode Config attribute values */
-#define INTERNAL_IP4_ADDRESS 1
-#define INTERNAL_IP4_NETMASK 2
-#define INTERNAL_IP4_DNS 3
-#define INTERNAL_IP4_NBNS 4
-#define INTERNAL_ADDRESS_EXPIRY 5
-#define INTERNAL_IP4_DHCP 6
-#define APPLICATION_VERSION 7
-#define INTERNAL_IP6_ADDRESS 8
-#define INTERNAL_IP6_NETMASK 9
-#define INTERNAL_IP6_DNS 10
-#define INTERNAL_IP6_NBNS 11
-#define INTERNAL_IP6_DHCP 12
-#define INTERNAL_IP4_SUBNET 13
-#define SUPPORTED_ATTRIBUTES 14
-#define INTERNAL_IP6_SUBNET 15
-
-extern enum_names modecfg_attr_names;
-
-/* XAUTH attribute values */
-#define XAUTH_TYPE 16520
-#define XAUTH_USER_NAME 16521
-#define XAUTH_USER_PASSWORD 16522
-#define XAUTH_PASSCODE 16523
-#define XAUTH_MESSAGE 16524
-#define XAUTH_CHALLENGE 16525
-#define XAUTH_DOMAIN 16526
-#define XAUTH_STATUS 16527
-#define XAUTH_NEXT_PIN 16528
-#define XAUTH_ANSWER 16529
-
-#define XAUTH_BASE XAUTH_TYPE
-
-extern enum_names xauth_attr_names;
-
-/* ISAKMP mode config attributes specific to the Unity vendor Id */
-#define UNITY_BANNER 28672
-#define UNITY_SAVE_PASSWD 28673
-#define UNITY_DEF_DOMAIN 28674
-#define UNITY_SPLITDNS_NAME 28675
-#define UNITY_SPLIT_INCLUDE 28676
-#define UNITY_NATT_PORT 28677
-#define UNITY_LOCAL_LAN 28678
-#define UNITY_PFS 28679
-#define UNITY_FW_TYPE 28680
-#define UNITY_BACKUP_SERVERS 28681
-#define UNITY_DDNS_HOSTNAME 28682
-
-#define UNITY_BASE UNITY_BANNER
-
-extern enum_names unity_attr_names;
-
-/* XAUTH authentication types */
-#define XAUTH_TYPE_GENERIC 0
-#define XAUTH_TYPE_CHAP 1
-#define XAUTH_TYPE_OTP 2
-#define XAUTH_TYPE_SKEY 3
-
-/* Values for XAUTH_STATUS */
-#define XAUTH_STATUS_FAIL 0
-#define XAUTH_STATUS_OK 1
-
-extern enum_names xauth_type_names;
-
-/* Exchange types
- * RFC2408 "Internet Security Association and Key Management Protocol (ISAKMP)"
- * section 3.1
- *
- * ISAKMP Future Use 6 - 31
- * DOI Specific Use 32 - 239
- * Private Use 240 - 255
- *
- * Note: draft-ietf-ipsec-dhless-enc-mode-00.txt Appendix A
- * defines "DHless RSA Encryption" as 6.
- */
-
-extern enum_names exchange_names;
-
-#define ISAKMP_XCHG_NONE 0
-#define ISAKMP_XCHG_BASE 1
-#define ISAKMP_XCHG_IDPROT 2 /* ID Protection */
-#define ISAKMP_XCHG_AO 3 /* Authentication Only */
-#define ISAKMP_XCHG_AGGR 4 /* Aggressive */
-#define ISAKMP_XCHG_INFO 5 /* Informational */
-#define ISAKMP_XCHG_MODE_CFG 6 /* Mode Config */
-
-/* Extra exchange types, defined by Oakley
- * RFC2409 "The Internet Key Exchange (IKE)", near end of Appendix A
- */
-#define ISAKMP_XCHG_QUICK 32 /* Oakley Quick Mode */
-#define ISAKMP_XCHG_NGRP 33 /* Oakley New Group Mode */
-/* added in draft-ietf-ipsec-ike-01.txt, near end of Appendix A */
-#define ISAKMP_XCHG_ACK_INFO 34 /* Oakley Acknowledged Informational */
-
-/* Flag bits */
-
-extern const char *const flag_bit_names[];
-
-#define ISAKMP_FLAG_ENCRYPTION 0x1
-#define ISAKMP_FLAG_COMMIT 0x2
-
-/* Situation definition for IPsec DOI */
-
-extern const char *const sit_bit_names[];
-
-#define SIT_IDENTITY_ONLY 0x01
-#define SIT_SECRECY 0x02
-#define SIT_INTEGRITY 0x04
-
-/* Protocol IDs
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.1
- */
-
-extern enum_names protocol_names;
-
-#define PROTO_ISAKMP 1
-#define PROTO_IPSEC_AH 2
-#define PROTO_IPSEC_ESP 3
-#define PROTO_IPCOMP 4
-
-/* warning: trans_show uses enum_show, so same static buffer is used */
-#define trans_show(p, t) \
- ((p)==PROTO_IPSEC_AH ? enum_show(&ah_transformid_names, (t)) \
- : (p)==PROTO_IPSEC_ESP ? enum_show(&esp_transformid_names, (t)) \
- : (p)==PROTO_IPCOMP ? enum_show(&ipcomp_transformid_names, (t)) \
- : "??")
-
-/* many transform values are moved to freeswan/ipsec_policy.h */
-
-extern enum_names isakmp_transformid_names;
-
-#define KEY_IKE 1
-
-extern enum_names ah_transformid_names;
-extern enum_names esp_transformid_names;
-extern enum_names ipcomp_transformid_names;
-
-/* the following are from RFC 2393/draft-shacham-ippcp-rfc2393bis-05.txt 3.3 */
-typedef u_int16_t cpi_t;
-#define IPCOMP_CPI_SIZE 2
-#define IPCOMP_FIRST_NEGOTIATED 256
-#define IPCOMP_LAST_NEGOTIATED 61439
-
-/* Identification type values
- * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
- */
-
-extern enum_names ident_names;
-extern enum_names cert_type_names;
-extern enum_names cert_policy_names;
-
-typedef enum certpolicy {
- CERT_ALWAYS_SEND = 0, /* the default */
- CERT_SEND_IF_ASKED = 1,
- CERT_NEVER_SEND = 2,
-
- CERT_YES_SEND = 3, /* synonym for CERT_ALWAYS_SEND */
- CERT_NO_SEND = 4 /* synonym for CERT_NEVER_SEND */
-} certpolicy_t;
-
-/* Policies for establishing an SA
- *
- * These are used to specify attributes (eg. encryption) and techniques
- * (eg PFS) for an SA.
- * Note: certain CD_ definitions in whack.c parallel these -- keep them
- * in sync!
- */
-
-extern const char *const sa_policy_bit_names[];
-extern const char *prettypolicy(lset_t policy);
-
-/* ISAKMP auth techniques (none means never negotiate) */
-#define POLICY_PSK LELEM(0)
-#define POLICY_RSASIG LELEM(1)
-
-#define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */
-#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_RSASIG | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG)
-#define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */
-
-/* Quick Mode (IPSEC) attributes */
-#define POLICY_ENCRYPT LELEM(2) /* must be first of IPSEC policies */
-#define POLICY_AUTHENTICATE LELEM(3) /* must be second */
-#define POLICY_COMPRESS LELEM(4) /* must be third */
-#define POLICY_TUNNEL LELEM(5)
-#define POLICY_PFS LELEM(6)
-#define POLICY_DISABLEARRIVALCHECK LELEM(7) /* supress tunnel egress address checking */
-
-#define POLICY_IPSEC_SHIFT 2 /* log2(POLICY_ENCRYPT) */
-#define POLICY_IPSEC_MASK LRANGES(POLICY_ENCRYPT, POLICY_DISABLEARRIVALCHECK)
-
-/* shunt attributes: what to do when routed without tunnel (2 bits) */
-#define POLICY_SHUNT_SHIFT 8 /* log2(POLICY_SHUNT_PASS) */
-#define POLICY_SHUNT_MASK (03ul << POLICY_SHUNT_SHIFT)
-
-#define POLICY_SHUNT_TRAP (0ul << POLICY_SHUNT_SHIFT) /* default: negotiate */
-#define POLICY_SHUNT_PASS (1ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_DROP (2ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_REJECT (3ul << POLICY_SHUNT_SHIFT)
-
-/* fail attributes: what to do with failed negotiation (2 bits) */
-
-#define POLICY_FAIL_SHIFT 10 /* log2(POLICY_FAIL_PASS) */
-#define POLICY_FAIL_MASK (03ul << POLICY_FAIL_SHIFT)
-
-#define POLICY_FAIL_NONE (0ul << POLICY_FAIL_SHIFT) /* default */
-#define POLICY_FAIL_PASS (1ul << POLICY_FAIL_SHIFT)
-#define POLICY_FAIL_DROP (2ul << POLICY_FAIL_SHIFT)
-#define POLICY_FAIL_REJECT (3ul << POLICY_FAIL_SHIFT)
-
-/* connection policy
- * Other policies could vary per state object. These live in connection.
- */
-#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */
-#define POLICY_OPPO LELEM(13) /* is this opportunistic? */
-#define POLICY_GROUP LELEM(14) /* is this a group template? */
-#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
-#define POLICY_UP LELEM(16) /* do we want this up? */
-#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */
-#define POLICY_XAUTH_PSK LELEM(18) /* do we support XAUTH????PreShared? */
-#define POLICY_XAUTH_RSASIG LELEM(19) /* do we support XAUTH????RSA? */
-#define POLICY_XAUTH_SERVER LELEM(20) /* are we an XAUTH server? */
-
-/* Any IPsec policy? If not, a connection description
- * is only for ISAKMP SA, not IPSEC SA. (A pun, I admit.)
- * Note: a connection can only be routed if it is NEVER_NEGOTIATE
- * or HAS_IPSEC_POLICY.
- */
-#define HAS_IPSEC_POLICY(p) (((p) & POLICY_IPSEC_MASK) != 0)
-
-/* Don't allow negotiation? */
-#define NEVER_NEGOTIATE(p) (LDISJOINT((p), POLICY_ID_AUTH_MASK))
-
-
-/* Oakley transform attributes
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-
-extern enum_names oakley_attr_names;
-extern const char *const oakley_attr_bit_names[];
-
-#define OAKLEY_ENCRYPTION_ALGORITHM 1
-#define OAKLEY_HASH_ALGORITHM 2
-#define OAKLEY_AUTHENTICATION_METHOD 3
-#define OAKLEY_GROUP_DESCRIPTION 4
-#define OAKLEY_GROUP_TYPE 5
-#define OAKLEY_GROUP_PRIME 6 /* B/V */
-#define OAKLEY_GROUP_GENERATOR_ONE 7 /* B/V */
-#define OAKLEY_GROUP_GENERATOR_TWO 8 /* B/V */
-#define OAKLEY_GROUP_CURVE_A 9 /* B/V */
-#define OAKLEY_GROUP_CURVE_B 10 /* B/V */
-#define OAKLEY_LIFE_TYPE 11
-#define OAKLEY_LIFE_DURATION 12 /* B/V */
-#define OAKLEY_PRF 13
-#define OAKLEY_KEY_LENGTH 14
-#define OAKLEY_FIELD_SIZE 15
-#define OAKLEY_GROUP_ORDER 16 /* B/V */
-#define OAKLEY_BLOCK_SIZE 17
-
-/* for each Oakley attribute, which enum_names describes its values? */
-extern enum_names *oakley_attr_val_descs[];
-
-/* IPsec DOI attributes
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.5
- */
-
-extern enum_names ipsec_attr_names;
-
-#define SA_LIFE_TYPE 1
-#define SA_LIFE_DURATION 2 /* B/V */
-#define GROUP_DESCRIPTION 3
-#define ENCAPSULATION_MODE 4
-#define AUTH_ALGORITHM 5
-#define KEY_LENGTH 6
-#define KEY_ROUNDS 7
-#define COMPRESS_DICT_SIZE 8
-#define COMPRESS_PRIVATE_ALG 9 /* B/V */
-
-/* for each IPsec attribute, which enum_names describes its values? */
-extern enum_names *ipsec_attr_val_descs[];
-
-/* SA Lifetime Type attribute
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.5
- * Default time specified in 4.5
- *
- * There are two defaults for IPSEC SA lifetime, SA_LIFE_DURATION_DEFAULT,
- * and PLUTO_SA_LIFE_DURATION_DEFAULT.
- * SA_LIFE_DURATION_DEFAULT is specified in RFC2407 "The Internet IP
- * Security Domain of Interpretation for ISAKMP" 4.5. It applies when
- * an ISAKMP negotiation does not explicitly specify a life duration.
- * PLUTO_SA_LIFE_DURATION_DEFAULT is specified in pluto(8). It applies
- * when a connection description does not specify --ipseclifetime.
- * The value of SA_LIFE_DURATION_MAXIMUM is our local policy.
- */
-
-extern enum_names sa_lifetime_names;
-
-#define SA_LIFE_TYPE_SECONDS 1
-#define SA_LIFE_TYPE_KBYTES 2
-
-#define SA_LIFE_DURATION_DEFAULT 28800 /* eight hours (RFC2407 4.5) */
-#define PLUTO_SA_LIFE_DURATION_DEFAULT 3600 /* one hour (pluto(8)) */
-#define SA_LIFE_DURATION_MAXIMUM 86400 /* one day */
-
-#define SA_REPLACEMENT_MARGIN_DEFAULT 540 /* (IPSEC & IKE) nine minutes */
-#define SA_REPLACEMENT_FUZZ_DEFAULT 100 /* (IPSEC & IKE) 100% of MARGIN */
-#define SA_REPLACEMENT_RETRIES_DEFAULT 3 /* (IPSEC & IKE) */
-
-#define SA_LIFE_DURATION_K_DEFAULT 0xFFFFFFFFlu
-
-/* Encapsulation Mode attribute */
-
-extern enum_names enc_mode_names;
-
-#define ENCAPSULATION_MODE_UNSPECIFIED 0 /* not legal -- used internally */
-#define ENCAPSULATION_MODE_TUNNEL 1
-#define ENCAPSULATION_MODE_TRANSPORT 2
-
-#define ENCAPSULATION_MODE_UDP_TUNNEL_RFC 3
-#define ENCAPSULATION_MODE_UDP_TRANSPORT_RFC 4
-
-#define ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS 61443
-#define ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS 61444
-
-/* Auth Algorithm attribute */
-
-extern enum_names auth_alg_names, extended_auth_alg_names;
-
-#define AUTH_ALGORITHM_NONE 0 /* our private designation */
-#define AUTH_ALGORITHM_HMAC_MD5 1
-#define AUTH_ALGORITHM_HMAC_SHA1 2
-#define AUTH_ALGORITHM_DES_MAC 3
-#define AUTH_ALGORITHM_KPDK 4
-#define AUTH_ALGORITHM_HMAC_SHA2_256 5
-#define AUTH_ALGORITHM_HMAC_SHA2_384 6
-#define AUTH_ALGORITHM_HMAC_SHA2_512 7
-#define AUTH_ALGORITHM_HMAC_RIPEMD 8
-#define AUTH_ALGORITHM_NULL 251
-
-/* Oakley Lifetime Type attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * As far as I can see, there is not specification for
- * OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT. This could lead to interop problems!
- * For no particular reason, we chose three hours.
- * The value of OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM is our local policy.
- */
-extern enum_names oakley_lifetime_names;
-
-#define OAKLEY_LIFE_SECONDS 1
-#define OAKLEY_LIFE_KILOBYTES 2
-
-#define OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT 10800 /* three hours */
-#define OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM 86400 /* one day */
-
-/* Oakley PRF attribute (none defined)
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_prf_names;
-
-/* HMAC (see rfc2104.txt) */
-
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5C
-
-/* Oakley Encryption Algorithm attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * and from http://www.isi.edu/in-notes/iana/assignments/ipsec-registry
- */
-
-extern enum_names oakley_enc_names;
-
-#define OAKLEY_DES_CBC 1
-#define OAKLEY_IDEA_CBC 2
-#define OAKLEY_BLOWFISH_CBC 3
-#define OAKLEY_RC5_R16_B64_CBC 4
-#define OAKLEY_3DES_CBC 5
-#define OAKLEY_CAST_CBC 6
-#define OAKLEY_AES_CBC 7
-
-#define OAKLEY_MARS_CBC 65001
-#define OAKLEY_RC6_CBC 65002
-#define OAKLEY_ID_65003 65003
-#define OAKLEY_SERPENT_CBC 65004
-#define OAKLEY_TWOFISH_CBC 65005
-
-#define OAKLEY_TWOFISH_CBC_SSH 65289
-
-#define OAKLEY_ENCRYPT_MAX 65535 /* pretty useless :) */
-
-/* Oakley Hash Algorithm attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * and from http://www.isi.edu/in-notes/iana/assignments/ipsec-registry
- */
-
-extern enum_names oakley_hash_names;
-
-#define OAKLEY_MD5 1
-#define OAKLEY_SHA 2
-#define OAKLEY_TIGER 3
-#define OAKLEY_SHA2_256 4
-#define OAKLEY_SHA2_384 5
-#define OAKLEY_SHA2_512 6
-
-#define OAKLEY_HASH_MAX 7
-
-/* Oakley Authentication Method attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- * Goofy Hybrid extensions from draft-ietf-ipsec-isakmp-hybrid-auth-05.txt
- * Goofy XAUTH extensions from draft-ietf-ipsec-isakmp-xauth-06.txt
- */
-
-extern enum_names oakley_auth_names;
-
-#define OAKLEY_PRESHARED_KEY 1
-#define OAKLEY_DSS_SIG 2
-#define OAKLEY_RSA_SIG 3
-#define OAKLEY_RSA_ENC 4
-#define OAKLEY_RSA_ENC_REV 5
-#define OAKLEY_ELGAMAL_ENC 6
-#define OAKLEY_ELGAMAL_ENC_REV 7
-
-#define OAKLEY_AUTH_ROOF 8 /* roof on auth values THAT WE SUPPORT */
-
-#define HybridInitRSA 64221
-#define HybridRespRSA 64222
-#define HybridInitDSS 64223
-#define HybridRespDSS 64224
-
-#define XAUTHInitPreShared 65001
-#define XAUTHRespPreShared 65002
-#define XAUTHInitDSS 65003
-#define XAUTHRespDSS 65004
-#define XAUTHInitRSA 65005
-#define XAUTHRespRSA 65006
-#define XAUTHInitRSAEncryption 65007
-#define XAUTHRespRSAEncryption 65008
-#define XAUTHInitRSARevisedEncryption 65009
-#define XAUTHRespRSARevisedEncryption 65010
-
-/* Oakley Group Description attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_group_names;
-
-#define OAKLEY_GROUP_MODP768 1
-#define OAKLEY_GROUP_MODP1024 2
-#define OAKLEY_GROUP_GP155 3
-#define OAKLEY_GROUP_GP185 4
-#define OAKLEY_GROUP_MODP1536 5
-
-#define OAKLEY_GROUP_MODP2048 14
-#define OAKLEY_GROUP_MODP3072 15
-#define OAKLEY_GROUP_MODP4096 16
-#define OAKLEY_GROUP_MODP6144 17
-#define OAKLEY_GROUP_MODP8192 18
-/* you must also touch: constants.c, crypto.c */
-
-/* Oakley Group Type attribute
- * draft-ietf-ipsec-ike-01.txt appendix A
- */
-extern enum_names oakley_group_type_names;
-
-#define OAKLEY_GROUP_TYPE_MODP 1
-#define OAKLEY_GROUP_TYPE_ECP 2
-#define OAKLEY_GROUP_TYPE_EC2N 3
-
-
-/* Notify messages -- error types
- * See RFC2408 ISAKMP 3.14.1
- */
-
-extern enum_names notification_names;
-extern enum_names ipsec_notification_names;
-
-typedef enum {
- NOTHING_WRONG = 0, /* unofficial! */
-
- INVALID_PAYLOAD_TYPE = 1,
- DOI_NOT_SUPPORTED = 2,
- SITUATION_NOT_SUPPORTED = 3,
- INVALID_COOKIE = 4,
- INVALID_MAJOR_VERSION = 5,
- INVALID_MINOR_VERSION = 6,
- INVALID_EXCHANGE_TYPE = 7,
- INVALID_FLAGS = 8,
- INVALID_MESSAGE_ID = 9,
- INVALID_PROTOCOL_ID = 10,
- INVALID_SPI = 11,
- INVALID_TRANSFORM_ID = 12,
- ATTRIBUTES_NOT_SUPPORTED = 13,
- NO_PROPOSAL_CHOSEN = 14,
- BAD_PROPOSAL_SYNTAX = 15,
- PAYLOAD_MALFORMED = 16,
- INVALID_KEY_INFORMATION = 17,
- INVALID_ID_INFORMATION = 18,
- INVALID_CERT_ENCODING = 19,
- INVALID_CERTIFICATE = 20,
- CERT_TYPE_UNSUPPORTED = 21,
- INVALID_CERT_AUTHORITY = 22,
- INVALID_HASH_INFORMATION = 23,
- AUTHENTICATION_FAILED = 24,
- INVALID_SIGNATURE = 25,
- ADDRESS_NOTIFICATION = 26,
- NOTIFY_SA_LIFETIME = 27,
- CERTIFICATE_UNAVAILABLE = 28,
- UNSUPPORTED_EXCHANGE_TYPE = 29,
- UNEQUAL_PAYLOAD_LENGTHS = 30,
-
- /* ISAKMP status type */
- CONNECTED = 16384,
-
- /* IPSEC DOI additions; status types (RFC2407 IPSEC DOI 4.6.3)
- * These must be sent under the protection of an ISAKMP SA.
- */
- IPSEC_RESPONDER_LIFETIME = 24576,
- IPSEC_REPLAY_STATUS = 24577,
- IPSEC_INITIAL_CONTACT = 24578,
-
- /* RFC 3706 DPD */
- R_U_THERE = 36136,
- R_U_THERE_ACK = 36137
-
- } notification_t;
-
-
-/* Public key algorithm number
- * Same numbering as used in DNSsec
- * See RFC 2535 DNSsec 3.2 The KEY Algorithm Number Specification.
- * Also found in BIND 8.2.2 include/isc/dst.h as DST algorithm codes.
- */
-
-enum pubkey_alg
-{
- PUBKEY_ALG_RSA = 1,
- PUBKEY_ALG_DSA = 3,
-};
-
-/* Limits on size of RSA moduli.
- * The upper bound matches that of DNSsec (see RFC 2537).
- * The lower bound must be more than 11 octets for certain
- * the encoding to work, but it must be much larger for any
- * real security. For now, we require 512 bits.
- */
-
-#define RSA_MIN_OCTETS_RFC 12
-
-#define RSA_MIN_OCTETS (512 / BITS_PER_BYTE)
-#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
-
-#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE)
-#define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
-
-/* Note: RFC 2537 encoding adds a few bytes. If you use a small
- * modulus like 3, the overhead is only 2 bytes
- */
-#define RSA_MAX_ENCODING_BYTES (RSA_MAX_OCTETS + 2)
-
-/* socket address family info */
-
-struct af_info
-{
- int af;
- const char *name;
- size_t ia_sz;
- size_t sa_sz;
- int mask_cnt;
- u_int8_t id_addr, id_subnet, id_range;
- const ip_address *any;
- const ip_subnet *none; /* 0.0.0.0/32 or IPv6 equivalent */
- const ip_subnet *all; /* 0.0.0.0/0 or IPv6 equivalent */
-};
-
-extern const struct af_info
- af_inet4_info,
- af_inet6_info;
-
-extern const struct af_info *aftoinfo(int af);
-
-extern enum_names af_names;
-
-#define subnetisaddr(sn, a) (subnetishost(sn) && addrinsubnet((a), (sn)))
-extern bool subnetisnone(const ip_subnet *sn);
-
-/* BIND enumerated types */
-
-extern enum_names
- rr_qtype_names,
- rr_type_names,
- rr_class_names;
-
-/* How authenticated is info that might have come from DNS?
- * In order of increasing confidence.
- */
-enum dns_auth_level {
- DAL_UNSIGNED, /* AD in response, but no signature: no authentication */
- DAL_NOTSEC, /* no AD in response: authentication impossible */
- DAL_SIGNED, /* AD and signature in response: authentic */
- DAL_LOCAL /* locally provided (pretty good) */
-};
-
-/*
- * define a macro for use in error messages
- */
-
-#ifdef USE_KEYRR
-#define RRNAME "TXT or KEY"
-#else
-#define RRNAME "TXT"
-#endif
-
-/* natt traversal types */
-extern const char *const natt_type_bitnames[];
-
-#endif /* _CONSTANTS_H */
diff --git a/programs/pluto/cookie.c b/programs/pluto/cookie.c
deleted file mode 100644
index 458120e46..000000000
--- a/programs/pluto/cookie.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* cookie generation/verification routines.
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: cookie.c,v 1.2 2005/08/17 16:38:20 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "sha1.h"
-#include "rnd.h"
-#include "cookie.h"
-
-const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
-
-/* Generate a cookie.
- * First argument is true if we're to create an Initiator cookie.
- * Length SHOULD be a multiple of sizeof(u_int32_t).
- */
-void
-get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
-{
- u_char buffer[SHA1_DIGEST_SIZE];
- SHA1_CTX ctx;
-
- do {
- if (initiator)
- {
- get_rnd_bytes(cookie, length);
- }
- else /* Responder cookie */
- {
- /* This looks as good as any way */
- size_t addr_length;
- static u_int32_t counter = 0;
- unsigned char addr_buff[
- sizeof(union {struct in_addr A; struct in6_addr B;})];
-
- addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
- SHA1Init(&ctx);
- SHA1Update(&ctx, addr_buff, addr_length);
- SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
- counter++;
- SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
- SHA1Final(buffer, &ctx);
- memcpy(cookie, buffer, length);
- }
- } while (is_zero_cookie(cookie)); /* probably never loops */
-}
diff --git a/programs/pluto/cookie.h b/programs/pluto/cookie.h
deleted file mode 100644
index f5b0e64d1..000000000
--- a/programs/pluto/cookie.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* cookie generation/verification routines.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: cookie.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#include <freeswan.h>
-
-extern const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
-
-extern void get_cookie(bool initiator, u_int8_t *cookie, int length
- , const ip_address *addr);
-
-#define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)
diff --git a/programs/pluto/crl.c b/programs/pluto/crl.c
deleted file mode 100644
index 8d4b3bd7b..000000000
--- a/programs/pluto/crl.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crl.c,v 1.12 2005/12/06 22:49:57 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "asn1.h"
-#include "oid.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "whack.h"
-#include "fetch.h"
-#include "sha1.h"
-
-/* chained lists of X.509 crls */
-
-static x509crl_t *x509crls = NULL;
-
-/* ASN.1 definition of an X.509 certificate list */
-
-static const asn1Object_t crlObjects[] = {
- { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
- { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
- { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 8 */
- { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
- { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
- { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
- { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 12 */
- { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
- { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 15 */
- { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
- { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
- { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST 0
-#define CRL_OBJ_TBS_CERT_LIST 1
-#define CRL_OBJ_VERSION 2
-#define CRL_OBJ_SIG_ALG 4
-#define CRL_OBJ_ISSUER 5
-#define CRL_OBJ_THIS_UPDATE 6
-#define CRL_OBJ_NEXT_UPDATE 7
-#define CRL_OBJ_USER_CERTIFICATE 10
-#define CRL_OBJ_REVOCATION_DATE 11
-#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
-#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
-#define CRL_OBJ_EXTN_ID 22
-#define CRL_OBJ_CRITICAL 23
-#define CRL_OBJ_EXTN_VALUE 24
-#define CRL_OBJ_ALGORITHM 27
-#define CRL_OBJ_SIGNATURE 28
-#define CRL_OBJ_ROOF 29
-
-
-const x509crl_t empty_x509crl = {
- NULL , /* *next */
- UNDEFINED_TIME, /* installed */
- NULL , /* distributionPoints */
- { NULL, 0 } , /* certificateList */
- { NULL, 0 } , /* tbsCertList */
- 1 , /* version */
- OID_UNKNOWN , /* sigAlg */
- { NULL, 0 } , /* issuer */
- UNDEFINED_TIME, /* thisUpdate */
- UNDEFINED_TIME, /* nextUpdate */
- NULL , /* revokedCertificates */
- /* crlExtensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKeySerialNumber */
- OID_UNKNOWN , /* algorithm */
- { NULL, 0 } /* signature */
-};
-
-/*
- * get the X.509 CRL with a given issuer
- */
-static x509crl_t*
-get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
-{
- x509crl_t *crl = x509crls;
- x509crl_t *prev_crl = NULL;
-
- while (crl != NULL)
- {
- if ((keyid.ptr != NULL && crl->authKeyID.ptr != NULL)
- ? same_keyid(keyid, crl->authKeyID)
- : (same_dn(crl->issuer, issuer) && same_serial(serial, crl->authKeySerialNumber)))
- {
- if (crl != x509crls)
- {
- /* bring the CRL up front */
- prev_crl->next = crl->next;
- crl->next = x509crls;
- x509crls = crl;
- }
- return crl;
- }
- prev_crl = crl;
- crl = crl->next;
- }
- return NULL;
-}
-
-/*
- * free the dynamic memory used to store revoked certificates
- */
-static void
-free_revoked_certs(revokedCert_t* revokedCerts)
-{
- while (revokedCerts != NULL)
- {
- revokedCert_t * revokedCert = revokedCerts;
- revokedCerts = revokedCert->next;
- pfree(revokedCert);
- }
-}
-
-/*
- * free the dynamic memory used to store CRLs
- */
-void
-free_crl(x509crl_t *crl)
-{
- free_revoked_certs(crl->revokedCertificates);
- free_generalNames(crl->distributionPoints, TRUE);
- pfree(crl->certificateList.ptr);
- pfree(crl);
-}
-
-static void
-free_first_crl(void)
-{
- x509crl_t *crl = x509crls;
-
- x509crls = crl->next;
- free_crl(crl);
-}
-
-void
-free_crls(void)
-{
- lock_crl_list("free_crls");
-
- while (x509crls != NULL)
- free_first_crl();
-
- unlock_crl_list("free_crls");
-}
-
-/*
- * Insert X.509 CRL into chained list
- */
-bool
-insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
-{
- x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");
-
- *crl = empty_x509crl;
-
- if (parse_x509crl(blob, 0, crl))
- {
- x509cert_t *issuer_cert;
- x509crl_t *oldcrl;
- bool valid_sig;
- generalName_t *gn;
-
- /* add distribution point */
- gn = alloc_thing(generalName_t, "generalName");
- gn->kind = GN_URI;
- gn->name = crl_uri;
- gn->next = crl->distributionPoints;
- crl->distributionPoints = gn;
-
- lock_authcert_list("insert_crl");
- /* get the issuer cacert */
- issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber,
- crl->authKeyID, AUTH_CA);
- if (issuer_cert == NULL)
- {
- plog("crl issuer cacert not found");
- free_crl(crl);
- unlock_authcert_list("insert_crl");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl issuer cacert found")
- )
-
- /* check the issuer's signature of the crl */
- valid_sig = check_signature(crl->tbsCertList, crl->signature
- , crl->algorithm, crl->algorithm, issuer_cert);
- unlock_authcert_list("insert_crl");
-
- if (!valid_sig)
- {
- free_crl(crl);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
-
- lock_crl_list("insert_crl");
- oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber
- , crl->authKeyID);
-
- if (oldcrl != NULL)
- {
- if (crl->thisUpdate > oldcrl->thisUpdate)
- {
- /* keep any known CRL distribution points */
- add_distribution_points(oldcrl->distributionPoints
- , &crl->distributionPoints);
-
- /* now delete the old CRL */
- free_first_crl();
- DBG(DBG_CONTROL,
- DBG_log("thisUpdate is newer - existing crl deleted")
- )
- }
- else
- {
- unlock_crl_list("insert_crls");
- DBG(DBG_CONTROL,
- DBG_log("thisUpdate is not newer - existing crl not replaced");
- )
- free_crl(crl);
- return oldcrl->nextUpdate - time(NULL) > 2*crl_check_interval;
- }
- }
-
- /* insert new CRL */
- crl->next = x509crls;
- x509crls = crl;
-
- unlock_crl_list("insert_crl");
-
- /* If crl caching is enabled then the crl is saved locally.
- * Only http or ldap URIs are cached but not local file URIs.
- * The issuer's subjectKeyID is used as a unique filename
- */
- if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0)
- {
- char path[BUF_LEN];
- char buf[BUF_LEN];
- char digest_buf[SHA1_DIGEST_SIZE];
- chunk_t subjectKeyID = { digest_buf, SHA1_DIGEST_SIZE };
-
- if (issuer_cert->subjectKeyID.ptr == NULL)
- compute_subjectKeyID(issuer_cert, subjectKeyID);
- else
- subjectKeyID = issuer_cert->subjectKeyID;
-
- datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
- snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
- write_chunk(path, "crl", crl->certificateList, 0022, TRUE);
- }
-
- /* is the fetched crl valid? */
- return crl->nextUpdate - time(NULL) > 2*crl_check_interval;
- }
- else
- {
- plog(" error in X.509 crl");
- free_crl(crl);
- return FALSE;
- }
-}
-
-/*
- * Loads CRLs
- */
-void
-load_crls(void)
-{
- struct dirent **filelist;
- u_char buf[BUF_LEN];
- u_char *save_dir;
- int n;
-
- /* change directory to specified path */
- save_dir = getcwd(buf, BUF_LEN);
- if (chdir(CRL_PATH))
- {
- plog("Could not change to directory '%s'", CRL_PATH);
- }
- else
- {
- plog("Changing to directory '%s'", CRL_PATH);
- n = scandir(CRL_PATH, &filelist, file_select, alphasort);
-
- if (n < 0)
- plog(" scandir() error");
- else
- {
- while (n--)
- {
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
- char *filename = filelist[n]->d_name;
-
- if (load_coded_file(filename, NULL, "crl", &blob, &pgp))
- {
- chunk_t crl_uri;
-
- crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
- crl_uri.ptr = alloc_bytes(crl_uri.len + 1, "crl uri");
-
- /* build CRL file URI */
- snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s"
- , CRL_PATH, filename);
-
- insert_crl(blob, crl_uri, FALSE);
- }
- free(filelist[n]);
- }
- free(filelist);
- }
- }
- /* restore directory path */
- chdir(save_dir);
-}
-
-/*
- * Parses a CRL revocation reason code
- */
-static crl_reason_t
-parse_crl_reasonCode(chunk_t object)
-{
- crl_reason_t reason = REASON_UNSPECIFIED;
-
- if (*object.ptr == ASN1_ENUMERATED
- && asn1_length(&object) == 1)
- {
- reason = *object.ptr;
- }
-
- DBG(DBG_PARSING,
- DBG_log(" '%s'", enum_name(&crl_reason_names, reason))
- )
- return reason;
-}
-
-/*
- * Parses an X.509 CRL
- */
-bool
-parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
-{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
- chunk_t extnID;
- chunk_t userCertificate;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < CRL_OBJ_ROOF)
- {
- if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID) {
- case CRL_OBJ_CERTIFICATE_LIST:
- crl->certificateList = object;
- break;
- case CRL_OBJ_TBS_CERT_LIST:
- crl->tbsCertList = object;
- break;
- case CRL_OBJ_VERSION:
- crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", crl->version);
- )
- break;
- case CRL_OBJ_SIG_ALG:
- crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_ISSUER:
- crl->issuer = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case CRL_OBJ_THIS_UPDATE:
- crl->thisUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_NEXT_UPDATE:
- crl->nextUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_USER_CERTIFICATE:
- userCertificate = object;
- break;
- case CRL_OBJ_REVOCATION_DATE:
- {
- /* put all the serial numbers and the revocation date in a chained list
- with revocedCertificates pointing to the first revoked certificate */
-
- revokedCert_t *revokedCert = alloc_thing(revokedCert_t, "revokedCert");
- revokedCert->userCertificate = userCertificate;
- revokedCert->revocationDate = parse_time(object, level);
- revokedCert->revocationReason = REASON_UNSPECIFIED;
- revokedCert->next = crl->revokedCertificates;
- crl->revokedCertificates = revokedCert;
- }
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_ID:
- case CRL_OBJ_EXTN_ID:
- extnID = object;
- break;
- case CRL_OBJ_CRL_ENTRY_CRITICAL:
- case CRL_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
- case CRL_OBJ_EXTN_VALUE:
- {
- u_int extn_oid = known_oid(extnID);
-
- if (extn_oid == OID_CRL_REASON_CODE)
- {
- crl->revokedCertificates->revocationReason =
- parse_crl_reasonCode(object);
- }
- else if (extn_oid == OID_AUTHORITY_KEY_ID)
- {
- parse_authorityKeyIdentifier(object, level
- , &crl->authKeyID, &crl->authKeySerialNumber);
- }
- }
- break;
- case CRL_OBJ_ALGORITHM:
- crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_SIGNATURE:
- crl->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- time(&crl->installed);
- return TRUE;
-}
-
-/* Checks if the current certificate is revoked. It goes through the
- * list of revoked certificates of the corresponding crl. Either the
- * status CERT_GOOD or CERT_REVOKED is returned
- */
-static cert_status_t
-check_revocation(const x509crl_t *crl, chunk_t serial
-, time_t *revocationDate, crl_reason_t * revocationReason)
-{
- revokedCert_t *revokedCert = crl->revokedCertificates;
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
-
- DBG(DBG_CONTROL,
- DBG_dump_chunk("serial number:", serial)
- )
-
- while(revokedCert != NULL)
- {
- /* compare serial numbers */
- if (revokedCert->userCertificate.len == serial.len &&
- memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0)
- {
- *revocationDate = revokedCert->revocationDate;
- *revocationReason = revokedCert->revocationReason;
- return CERT_REVOKED;
- }
- revokedCert = revokedCert->next;
- }
- return CERT_GOOD;
-}
-
-/*
- * check if any crls are about to expire
- */
-void
-check_crls(void)
-{
- x509crl_t *crl;
-
- lock_crl_list("check_crls");
- crl = x509crls;
-
- while (crl != NULL)
- {
- time_t time_left = crl->nextUpdate - time(NULL);
- u_char buf[BUF_LEN];
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, crl->issuer);
- DBG_log("issuer: '%s'",buf);
- if (crl->authKeyID.ptr != NULL)
- {
- datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- DBG_log("%ld seconds left", time_left)
- )
- if (time_left < 2*crl_check_interval)
- {
- fetch_req_t *req = build_crl_fetch_request(crl->issuer
- , crl->authKeySerialNumber
- , crl->authKeyID, crl->distributionPoints);
- add_crl_fetch_request(req);
- }
- crl = crl->next;
- }
- unlock_crl_list("check_crls");
-}
-
-/*
- * verify if a cert hasn't been revoked by a crl
- */
-cert_status_t
-verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
-, crl_reason_t *revocationReason)
-{
- x509crl_t *crl;
-
- ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID);
-
- generalName_t *crluri = (ca == NULL)? NULL : ca->crluri;
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
-
- lock_crl_list("verify_by_crl");
- crl = get_x509crl(cert->issuer, cert->authKeySerialNumber, cert->authKeyID);
-
- if (crl == NULL)
- {
- unlock_crl_list("verify_by_crl");
- plog("crl not found");
-
- if (cert->crlDistributionPoints != NULL)
- {
- fetch_req_t *req = build_crl_fetch_request(cert->issuer
- , cert->authKeySerialNumber
- , cert->authKeyID, cert->crlDistributionPoints);
- add_crl_fetch_request(req);
- }
-
- if (crluri != NULL)
- {
- fetch_req_t *req = build_crl_fetch_request(cert->issuer
- , cert->authKeySerialNumber
- , cert->authKeyID, crluri);
- add_crl_fetch_request(req);
- }
-
- if (cert->crlDistributionPoints != 0 || crluri != NULL)
- {
- wake_fetch_thread("verify_by_crl");
- return CERT_UNKNOWN;
- }
- else
- return CERT_UNDEFINED;
- }
- else
- {
- x509cert_t *issuer_cert;
- bool valid;
-
- DBG(DBG_CONTROL,
- DBG_log("crl found")
- )
-
- add_distribution_points(cert->crlDistributionPoints
- , &crl->distributionPoints);
-
- add_distribution_points(crluri
- , &crl->distributionPoints);
-
- lock_authcert_list("verify_by_crl");
-
- issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber
- , crl->authKeyID, AUTH_CA);
- valid = check_signature(crl->tbsCertList, crl->signature
- , crl->algorithm, crl->algorithm, issuer_cert);
-
- unlock_authcert_list("verify_by_crl");
-
- if (valid)
- {
- cert_status_t status;
-
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
- /* return the expiration date */
- *until = crl->nextUpdate;
-
- /* has the certificate been revoked? */
- status = check_revocation(crl, cert->serialNumber, revocationDate
- , revocationReason);
-
- if (*until < time(NULL))
- {
- fetch_req_t *req;
-
- plog("crl update is overdue since %s"
- , timetoa(until, TRUE));
-
- /* try to fetch a crl update */
- req = build_crl_fetch_request(crl->issuer
- , crl->authKeySerialNumber
- , crl->authKeyID, crl->distributionPoints);
- unlock_crl_list("verify_by_crl");
-
- add_crl_fetch_request(req);
- wake_fetch_thread("verify_by_crl");
- }
- else
- {
- unlock_crl_list("verify_by_crl");
- DBG(DBG_CONTROL,
- DBG_log("crl is valid")
- )
- }
- return status;
- }
- else
- {
- unlock_crl_list("verify_by_crl");
- plog("crl signature is invalid");
- return CERT_UNKNOWN;
- }
- }
-}
-
-/*
- * list all X.509 crls in the chained list
- */
-void
-list_crls(bool utc, bool strict)
-{
- x509crl_t *crl;
-
- lock_crl_list("list_crls");
- crl = x509crls;
-
- if (crl != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 CRLs:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (crl != NULL)
- {
- u_char buf[BUF_LEN];
- u_int revoked = 0;
- revokedCert_t *revokedCert = crl->revokedCertificates;
-
- /* count number of revoked certificates in CRL */
- while (revokedCert != NULL)
- {
- revoked++;
- revokedCert = revokedCert->next;
- }
-
- whack_log(RC_COMMENT, "%s, revoked certs: %d",
- timetoa(&crl->installed, utc), revoked);
- dntoa(buf, BUF_LEN, crl->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
-
- list_distribution_points(crl->distributionPoints);
-
- whack_log(RC_COMMENT, " updates: this %s",
- timetoa(&crl->thisUpdate, utc));
- whack_log(RC_COMMENT, " next %s %s",
- timetoa(&crl->nextUpdate, utc),
- check_expiry(crl->nextUpdate, CRL_WARNING_INTERVAL, strict));
- if (crl->authKeyID.ptr != NULL)
- {
- datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (crl->authKeySerialNumber.ptr != NULL)
- {
- datatot(crl->authKeySerialNumber.ptr, crl->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
-
- crl = crl->next;
- }
- unlock_crl_list("list_crls");
-}
-
diff --git a/programs/pluto/crl.h b/programs/pluto/crl.h
deleted file mode 100644
index 9f985b6cd..000000000
--- a/programs/pluto/crl.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crl.h,v 1.4 2005/07/18 19:36:22 as Exp $
- */
-
-#include "constants.h"
-
-/* access structure for a revoked serial number */
-
-typedef struct revokedCert revokedCert_t;
-
-struct revokedCert{
- revokedCert_t *next;
- chunk_t userCertificate;
- time_t revocationDate;
- crl_reason_t revocationReason;
-};
-
-/* storage structure for an X.509 CRL */
-
-typedef struct x509crl x509crl_t;
-
-struct x509crl {
- x509crl_t *next;
- time_t installed;
- generalName_t *distributionPoints;
- chunk_t certificateList;
- chunk_t tbsCertList;
- u_int version;
- /* signature */
- int sigAlg;
- chunk_t issuer;
- time_t thisUpdate;
- time_t nextUpdate;
- revokedCert_t *revokedCertificates;
- /* v2 extensions */
- /* crlExtensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
-
- /* signatureAlgorithm */
- int algorithm;
- chunk_t signature;
-};
-
-/* apply a strict CRL policy
- * flag set in plutomain.c and used in ipsec_doi.c and rcv_whack.c
- */
-extern bool strict_crl_policy;
-
-/*
- * cache the retrieved CRLs by storing them locally as a file
- */
-extern bool cache_crls;
-
-/*
- * check periodically for expired crls
- */
-extern long crl_check_interval;
-
-/* used for initialization */
-extern const x509crl_t empty_x509crl;
-
-extern bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl);
-extern void load_crls(void);
-extern void check_crls(void);
-extern bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl);
-extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until
- , time_t *revocationDate, crl_reason_t *revocationReason);
-extern void list_crls(bool utc, bool strict);
-extern void free_crls(void);
-extern void free_crl(x509crl_t *crl);
diff --git a/programs/pluto/crypto.c b/programs/pluto/crypto.c
deleted file mode 100644
index 63a53ad5c..000000000
--- a/programs/pluto/crypto.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/* crypto interfaces
- * Copyright (C) 1998-2001 D. Hugh Redelmeier
- * Copyright (C) 2007 Andreas Steffen
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crypto.c,v 1.6 2007/02/21 14:21:48 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#define HEADER_DES_LOCL_H /* stupid trick to force prototype decl in <des.h> */
-#include <crypto/des.h>
-
-#include <errno.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "log.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-#include "alg_info.h"
-#include "ike_alg.h"
-
-
-/* moduli and generator. */
-
-static MP_INT
- modp1024_modulus,
- modp1536_modulus,
- modp2048_modulus,
- modp3072_modulus,
- modp4096_modulus,
- modp6144_modulus,
- modp8192_modulus;
-
-MP_INT groupgenerator; /* MODP group generator (2) */
-
-static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
-
-static struct encrypt_desc crypto_encryptor_3des =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_3DES_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(des_key_schedule) * 3,
- enc_blocksize: DES_CBC_BLOCK_SIZE,
- keydeflen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- keyminlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- keymaxlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- do_crypt: do_3des,
-};
-
-/* MD5 hash test vectors
- * from RFC 1321 "MD5 Message-Digest Algorithm"
- * April 1992, R. Rivest, RSA Data Security
- */
-
-static const u_char md5_test0_msg[] = {
-
-};
-
-static const u_char md5_test0_msg_digest[] = {
- 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
- 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
-};
-
-static const u_char md5_test1_msg[] = {
- 0x61
-};
-
-static const u_char md5_test1_msg_digest[] = {
- 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
- 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
-};
-
-static const u_char md5_test2_msg[] = {
- 0x61, 0x62, 0x63
-};
-
-static const u_char md5_test2_msg_digest[] = {
- 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
- 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72
-};
-
-static const u_char md5_test3_msg[] = {
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
- 0x64, 0x69, 0x67, 0x65, 0x73, 0x74
-};
-
-static const u_char md5_test3_msg_digest[] = {
- 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
- 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0
-};
-
-static const u_char md5_test4_msg[] = {
- 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
- 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a
-};
-
-static const u_char md5_test4_msg_digest[] = {
- 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
- 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
-};
-
-static const u_char md5_test5_msg[] = {
- 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
- 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
- 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
-};
-
-static const u_char md5_test5_msg_digest[] = {
- 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
- 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f
-};
-
-static const u_char md5_test6_msg[] = {
- 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
- 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30
-};
-
-static const u_char md5_test6_msg_digest[] = {
- 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
- 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
-};
-
-static const hash_testvector_t md5_hash_testvectors[] = {
- { sizeof(md5_test0_msg), md5_test0_msg, md5_test0_msg_digest },
- { sizeof(md5_test1_msg), md5_test1_msg, md5_test1_msg_digest },
- { sizeof(md5_test2_msg), md5_test2_msg, md5_test2_msg_digest },
- { sizeof(md5_test3_msg), md5_test3_msg, md5_test3_msg_digest },
- { sizeof(md5_test4_msg), md5_test4_msg, md5_test4_msg_digest },
- { sizeof(md5_test5_msg), md5_test5_msg, md5_test5_msg_digest },
- { sizeof(md5_test6_msg), md5_test6_msg, md5_test6_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* MD5 hmac test vectors
- * from RFC 2202 "Test Cases for HMAC-MD5 and HMAC-SHA-1"
- * September 1997, P. Cheng, IBM & R. Glenn, NIST
- */
-
-static const u_char md5_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
-};
-
-static const u_char md5_hmac1_msg[] = {
- 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-};
-
-static const u_char md5_hmac1[] = {
- 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
- 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
-};
-
-static const u_char md5_hmac2_key[] = {
- 0x4a, 0x65, 0x66, 0x65
-};
-
-static const u_char md5_hmac2_msg[] = {
- 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
- 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
- 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
- 0x69, 0x6e, 0x67, 0x3f
-};
-
-static const u_char md5_hmac2[] = {
- 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
- 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
-};
-
-static const u_char md5_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
-};
-
-static const u_char md5_hmac3_msg[] = {
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd
-};
-
-static const u_char md5_hmac3[] = {
- 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
- 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
-};
-
-static const u_char md5_hmac4_key[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19
-};
-
-static const u_char md5_hmac4_msg[] = {
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd
-};
-
-static const u_char md5_hmac4[] = {
- 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
- 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
-};
-
-static const u_char md5_hmac6_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-};
-
-static const u_char md5_hmac6_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
- 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
- 0x20, 0x46, 0x69, 0x72, 0x73, 0x74
-};
-
-static const u_char md5_hmac6[] = {
- 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
- 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd
-};
-
-static const u_char md5_hmac7_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e,
- 0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72,
- 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e,
- 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d,
- 0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74,
- 0x61
-};
-
-static const u_char md5_hmac7[] = {
- 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
- 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e
-};
-
-static const hmac_testvector_t md5_hmac_testvectors[] = {
- { sizeof(md5_hmac1_key), md5_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, md5_hmac1 },
- { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, md5_hmac2 },
- { sizeof(md5_hmac3_key), md5_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, md5_hmac3 },
- { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, md5_hmac4 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, md5_hmac6 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, md5_hmac7 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static struct hash_desc crypto_hasher_md5 =
-{
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_MD5,
- algo_next: NULL,
- hash_ctx_size: sizeof(MD5_CTX),
- hash_block_size: MD5_BLOCK_SIZE,
- hash_digest_size: MD5_DIGEST_SIZE,
- hash_testvectors: md5_hash_testvectors,
- hmac_testvectors: md5_hmac_testvectors,
- hash_init: (void (*)(void *)) MD5Init,
- hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update,
- hash_final: (void (*)(u_char *, void *)) MD5Final
-};
-
-/* SHA-1 test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha1_short2_msg[] = {
- 0x5e
-};
-
-static const u_char sha1_short2_msg_digest[] = {
- 0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca,
- 0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4,
- 0xc4, 0xdb, 0x59, 0xc2
-};
-
-static const u_char sha1_short4_msg[] = {
- 0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e,
- 0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46
-};
-
-static const u_char sha1_short4_msg_digest[] = {
- 0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1,
- 0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8,
- 0x2b, 0x54, 0x4a, 0x35
-};
-
-static const u_char sha1_long2_msg[] = {
- 0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a,
- 0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f,
- 0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd,
- 0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15,
- 0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea,
- 0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92,
- 0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa,
- 0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f,
- 0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95,
- 0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04,
- 0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6,
- 0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca,
- 0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54,
- 0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b,
- 0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a,
- 0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60,
- 0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f,
- 0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80,
- 0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e,
- 0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27,
- 0xcd, 0xbb, 0xfb
-};
-
-static const u_char sha1_long2_msg_digest[] = {
- 0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60,
- 0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20,
- 0x2b, 0xad, 0x27, 0xb3
-};
-
-static const hash_testvector_t sha1_hash_testvectors[] = {
- { sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest },
- { sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest },
- { sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-1 hmac test vectors
- * from RFC 2202 "Test Cases for HMAC-MD5 and HMAC-SHA-1"
- * September 1997, P. Cheng, IBM & R. Glenn, NIST
- */
-
-static const u_char sha1_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b
-};
-
-static const u_char sha1_hmac1[] = {
- 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
- 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
- 0xf1, 0x46, 0xbe, 0x00
-};
-
-static const u_char sha1_hmac2[] = {
- 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
- 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
- 0x25, 0x9a, 0x7c, 0x79
-};
-
-static const u_char sha1_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa
-};
-
-static const u_char sha1_hmac3[] = {
- 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
- 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
- 0x63, 0xf1, 0x75, 0xd3
-};
-
-static const u_char sha1_hmac4[] = {
- 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
- 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
- 0x2d, 0x72, 0x35, 0xda
-};
-
-static const u_char sha1_hmac6[] = {
- 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
- 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
- 0xed, 0x40, 0x21, 0x12
-};
-
-static const u_char sha1_hmac7[] = {
- 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
- 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
- 0xbb, 0xff, 0x1a, 0x91
-};
-
-static const hmac_testvector_t sha1_hmac_testvectors[] = {
- { sizeof(sha1_hmac1_key), sha1_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, sha1_hmac1 },
- { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, sha1_hmac2 },
- { sizeof(sha1_hmac3_key), sha1_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, sha1_hmac3 },
- { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, sha1_hmac4 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, sha1_hmac6 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, sha1_hmac7 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static struct hash_desc crypto_hasher_sha1 =
-{
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA,
- algo_next: NULL,
- hash_ctx_size: sizeof(SHA1_CTX),
- hash_block_size: SHA1_BLOCK_SIZE,
- hash_digest_size: SHA1_DIGEST_SIZE,
- hash_testvectors: sha1_hash_testvectors,
- hmac_testvectors: sha1_hmac_testvectors,
- hash_init: (void (*)(void *)) SHA1Init,
- hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update,
- hash_final: (void (*)(u_char *, void *)) SHA1Final
-};
-
-void
-init_crypto(void)
-{
- if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0
- || mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0
- || mpz_init_set_str(&modp1536_modulus, MODP1536_MODULUS, 16) != 0
- || mpz_init_set_str(&modp2048_modulus, MODP2048_MODULUS, 16) != 0
- || mpz_init_set_str(&modp3072_modulus, MODP3072_MODULUS, 16) != 0
- || mpz_init_set_str(&modp4096_modulus, MODP4096_MODULUS, 16) != 0
- || mpz_init_set_str(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
- || mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
- exit_log("mpz_init_set_str() failed in init_crypto()");
-
- ike_alg_add((struct ike_alg *) &crypto_encryptor_3des);
- ike_alg_add((struct ike_alg *) &crypto_hasher_sha1);
- ike_alg_add((struct ike_alg *) &crypto_hasher_md5);
- ike_alg_init();
- ike_alg_test();
-}
-
-/* Oakley group description
- *
- * See RFC2409 "The Internet key exchange (IKE)" 6.
- */
-
-const struct oakley_group_desc unset_group = {0, NULL, 0}; /* magic signifier */
-
-const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = {
-# define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE)
- { OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
- { OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
- { OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
- { OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
- { OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
- { OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
- { OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
-# undef BYTES
-};
-
-const struct oakley_group_desc *
-lookup_group(u_int16_t group)
-{
- int i;
-
- for (i = 0; i != elemsof(oakley_group); i++)
- if (group == oakley_group[i].group)
- return &oakley_group[i];
- return NULL;
-}
-
-/* Encryption Routines
- *
- * Each uses and updates the state object's st_new_iv.
- * This must already be initialized.
- */
-
-/* encrypt or decrypt part of an IKE message using DES
- * See RFC 2409 "IKE" Appendix B
- */
-static void __attribute__ ((unused))
-do_des(bool enc, void *buf, size_t buf_len, struct state *st)
-{
- des_key_schedule ks;
-
- (void) des_set_key((des_cblock *)st->st_enc_key.ptr, ks);
-
- passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE);
- st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */
-
- des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
- ks,
- (des_cblock *)st->st_new_iv, enc);
-}
-
-/* encrypt or decrypt part of an IKE message using 3DES
- * See RFC 2409 "IKE" Appendix B
- */
-static void
-do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- des_key_schedule ks[3];
-
- passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3)))
- (void) des_set_key((des_cblock *)key + 0, ks[0]);
- (void) des_set_key((des_cblock *)key + 1, ks[1]);
- (void) des_set_key((des_cblock *)key + 2, ks[2]);
-
- des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
- ks[0], ks[1], ks[2],
- (des_cblock *)iv, enc);
-}
-
-/* hash and prf routines */
-void
-crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st)
-{
- passert(st->st_new_iv_len >= e->enc_blocksize);
- st->st_new_iv_len = e->enc_blocksize; /* truncate */
-
- e->do_crypt(buf, size, st->st_enc_key.ptr, st->st_enc_key.len, st->st_new_iv, enc);
- /*
- e->set_key(&ctx, st->st_enc_key.ptr, st->st_enc_key.len);
- e->cbc_crypt(&ctx, buf, size, st->st_new_iv, enc);
- */
-}
-
-/* HMAC package
- * rfc2104.txt specifies how HMAC works.
- */
-
-void
-hmac_init(struct hmac_ctx *ctx,
- const struct hash_desc *h,
- const u_char *key, size_t key_len)
-{
- int k;
-
- ctx->h = h;
- ctx->hmac_digest_size = h->hash_digest_size;
-
- /* Prepare the two pads for the HMAC */
-
- memset(ctx->buf1, '\0', h->hash_block_size);
-
- if (key_len <= h->hash_block_size)
- {
- memcpy(ctx->buf1, key, key_len);
- }
- else
- {
- h->hash_init(&ctx->hash_ctx);
- h->hash_update(&ctx->hash_ctx, key, key_len);
- h->hash_final(ctx->buf1, &ctx->hash_ctx);
- }
-
- memcpy(ctx->buf2, ctx->buf1, h->hash_block_size);
-
- for (k = 0; k < h->hash_block_size; k++)
- {
- ctx->buf1[k] ^= HMAC_IPAD;
- ctx->buf2[k] ^= HMAC_OPAD;
- }
-
- hmac_reinit(ctx);
-}
-
-void
-hmac_reinit(struct hmac_ctx *ctx)
-{
- ctx->h->hash_init(&ctx->hash_ctx);
- ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size);
-}
-
-void
-hmac_update(struct hmac_ctx *ctx,
- const u_char *data, size_t data_len)
-{
- ctx->h->hash_update(&ctx->hash_ctx, data, data_len);
-}
-
-void
-hmac_final(u_char *output, struct hmac_ctx *ctx)
-{
- const struct hash_desc *h = ctx->h;
-
- h->hash_final(output, &ctx->hash_ctx);
-
- h->hash_init(&ctx->hash_ctx);
- h->hash_update(&ctx->hash_ctx, ctx->buf2, h->hash_block_size);
- h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size);
- h->hash_final(output, &ctx->hash_ctx);
-}
diff --git a/programs/pluto/crypto.h b/programs/pluto/crypto.h
deleted file mode 100644
index fa3af3a8b..000000000
--- a/programs/pluto/crypto.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* crypto interfaces
- * Copyright (C) 1998, 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: crypto.h,v 1.7 2007/02/21 14:21:48 as Exp $
- */
-
-#include <gmp.h> /* GNU MP library */
-
-#include "libsha2/sha2.h"
-#include "ike_alg.h"
-
-extern void init_crypto(void);
-
-/* Oakley group descriptions */
-
-extern MP_INT groupgenerator; /* MODP group generator (2) */
-
-struct oakley_group_desc {
- u_int16_t group;
- MP_INT *modulus;
- size_t bytes;
-};
-
-extern const struct oakley_group_desc unset_group; /* magic signifier */
-extern const struct oakley_group_desc *lookup_group(u_int16_t group);
-#define OAKLEY_GROUP_SIZE 7
-extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
-
-/* unification of cryptographic encoding/decoding algorithms
- * The IV is taken from and returned to st->st_new_iv.
- * This allows the old IV to be retained.
- * Use update_iv to commit to the new IV (for example, once a packet has
- * been validated).
- */
-
-#define MAX_OAKLEY_KEY_LEN0 (3 * DES_CBC_BLOCK_SIZE)
-#define MAX_OAKLEY_KEY_LEN (256/BITS_PER_BYTE)
-
-struct state; /* forward declaration, dammit */
-
-void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st);
-
-#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
- , (st)->st_iv_len = (st)->st_new_iv_len)
-
-#define set_ph1_iv(st, iv) \
- passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
- memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
-
-/* unification of cryptographic hashing mechanisms */
-
-#ifndef NO_HASH_CTX
-union hash_ctx {
- MD5_CTX ctx_md5;
- SHA1_CTX ctx_sha1;
- sha256_context ctx_sha256;
- sha512_context ctx_sha512;
- };
-
-/* HMAC package
- * Note that hmac_ctx can be (and is) copied since there are
- * no persistent pointers into it.
- */
-
-struct hmac_ctx {
- const struct hash_desc *h; /* underlying hash function */
- size_t hmac_digest_size; /* copy of h->hash_digest_size */
- union hash_ctx hash_ctx; /* ctx for hash function */
- u_char buf1[MAX_HASH_BLOCK_SIZE];
- u_char buf2[MAX_HASH_BLOCK_SIZE];
- };
-
-extern void hmac_init(
- struct hmac_ctx *ctx,
- const struct hash_desc *h,
- const u_char *key,
- size_t key_len);
-
-#define hmac_init_chunk(ctx, h, ch) hmac_init((ctx), (h), (ch).ptr, (ch).len)
-
-extern void hmac_reinit(struct hmac_ctx *ctx); /* saves recreating pads */
-
-extern void hmac_update(
- struct hmac_ctx *ctx,
- const u_char *data,
- size_t data_len);
-
-#define hmac_update_chunk(ctx, ch) hmac_update((ctx), (ch).ptr, (ch).len)
-
-extern void hmac_final(u_char *output, struct hmac_ctx *ctx);
-
-#define hmac_final_chunk(ch, name, ctx) { \
- pfreeany((ch).ptr); \
- (ch).len = (ctx)->hmac_digest_size; \
- (ch).ptr = alloc_bytes((ch).len, name); \
- hmac_final((ch).ptr, (ctx)); \
- }
-#endif
diff --git a/programs/pluto/db_ops.c b/programs/pluto/db_ops.c
deleted file mode 100644
index bbcd7918f..000000000
--- a/programs/pluto/db_ops.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* Dynamic db (proposal, transforms, attributes) handling.
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: db_ops.c,v 1.4 2005/04/07 20:13:44 as Exp $
- */
-
-/*
- * The stratedy is to have (full contained) struct db_prop in db_context
- * pointing to ONE dynamically sizable transform vector (trans0).
- * Each transform stores attrib. in ONE dyn. sizable attribute vector (attrs0)
- * in a "serialized" way (attributes storage is used in linear sequence for
- * subsecuent transforms).
- *
- * Resizing for both trans0 and attrs0 is supported:
- * - For trans0: quite simple, just allocate and copy trans. vector content
- * also update trans_cur (by offset)
- * - For attrs0: after allocating and copying attrs, I must rewrite each
- * trans->attrs present in trans0; to achieve this, calculate
- * attrs pointer offset (new minus old) and iterate over
- * each transform "adding" this difference.
- * also update attrs_cur (by offset)
- *
- * db_context structure:
- * +---------------------+
- * | prop |
- * | .protoid |
- * | .trans | --+
- * | .trans_cnt | |
- * +---------------------+ <-+
- * | trans0 | ----> { trans#1 | ... | trans#i | ... }
- * +---------------------+ ^
- * | trans_cur | ----------------------' current transf.
- * +---------------------+
- * | attrs0 | ----> { attr#1 | ... | attr#j | ... }
- * +---------------------+ ^
- * | attrs_cur | ---------------------' current attr.
- * +---------------------+
- * | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
- * +---------------------+
- *
- * See testing examples at end for interface usage.
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <malloc.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "packet.h"
-#include "spdb.h"
-#include "db_ops.h"
-#include "log.h"
-#include "whack.h"
-
-#include <assert.h>
-
-#ifndef NO_PLUTO
-#else
-#define passert(x) assert(x)
-extern int debug; /* eg: spi.c */
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define alloc_thing(thing, name) alloc_bytes(sizeof (thing), name)
-void * alloc_bytes(size_t size, const char *name) {
- void *p=malloc(size);
- if (p == NULL)
- fprintf(stderr, "unable to malloc %lu bytes for %s",
- (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-#define pfreeany(ptr) free(ptr)
-
-#endif
-
-#ifdef NOT_YET
-/*
- * Allocator cache:
- * Because of the single-threaded nature of pluto/spdb.c,
- * alloc()/free() is exercised many times with very small
- * lifetime objects.
- * Just caching last object (currently it will select the
- * largest) will avoid this allocation mas^Wperturbations
- *
- */
-struct db_ops_alloc_cache {
- void *ptr;
- int size;
-};
-#endif
-
-#ifndef NO_DB_OPS_STATS
-/*
- * stats: do account for allocations
- * displayed in db_ops_show_status()
- */
-struct db_ops_stats {
- int st_curr_cnt; /* current number of allocations */
- int st_total_cnt; /* total allocations so far */
- size_t st_maxsz; /* max. size requested */
-};
-#define DB_OPS_ZERO { 0, 0, 0};
-#define DB_OPS_STATS_DESC "{curr_cnt, total_cnt, maxsz}"
-#define DB_OPS_STATS_STR(name) name "={%d,%d,%d} "
-#define DB_OPS_STATS_F(st) (st).st_curr_cnt, (st).st_total_cnt, (int)(st).st_maxsz
-static struct db_ops_stats db_context_st = DB_OPS_ZERO;
-static struct db_ops_stats db_trans_st = DB_OPS_ZERO;
-static struct db_ops_stats db_attrs_st = DB_OPS_ZERO;
-static __inline__ void * alloc_bytes_st (size_t size, const char *str, struct db_ops_stats *st)
-{
- void *ptr = alloc_bytes(size, str);
- if (ptr) {
- st->st_curr_cnt++;
- st->st_total_cnt++;
- if (size > st->st_maxsz) st->st_maxsz=size;
- }
- return ptr;
-}
-#define ALLOC_BYTES_ST(z,s,st) alloc_bytes_st(z, s, &st);
-#define PFREE_ST(p,st) do { st.st_curr_cnt--; pfree(p); } while (0);
-
-#else
-
-#define ALLOC_BYTES_ST(z,s,n) alloc_bytes(z, s);
-#define PFREE_ST(p,n) pfree(p);
-
-#endif /* NO_DB_OPS_STATS */
-/* Initialize db object
- * max_trans and max_attrs can be 0, will be dynamically expanded
- * as a result of "add" operations
- */
-int
-db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs)
-{
- int ret=-1;
-
- ctx->trans0 = NULL;
- ctx->attrs0 = NULL;
-
- if (max_trans > 0) { /* quite silly if not */
- ctx->trans0 = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
- "db_context->trans", db_trans_st);
- if (!ctx->trans0) goto out;
- }
-
- if (max_attrs > 0) { /* quite silly if not */
- ctx->attrs0 = ALLOC_BYTES_ST (sizeof (struct db_attr) * max_attrs,
- "db_context->attrs", db_attrs_st);
- if (!ctx->attrs0) goto out;
- }
- ret = 0;
-out:
- if (ret < 0 && ctx->trans0) {
- PFREE_ST(ctx->trans0, db_trans_st);
- ctx->trans0 = NULL;
- }
- ctx->max_trans = max_trans;
- ctx->max_attrs = max_attrs;
- ctx->trans_cur = ctx->trans0;
- ctx->attrs_cur = ctx->attrs0;
- ctx->prop.protoid = protoid;
- ctx->prop.trans = ctx->trans0;
- ctx->prop.trans_cnt = 0;
- return ret;
-}
-
-/* Expand storage for transforms by number delta_trans */
-static int
-db_trans_expand(struct db_context *ctx, int delta_trans)
-{
- int ret = -1;
- struct db_trans *new_trans, *old_trans;
- int max_trans = ctx->max_trans + delta_trans;
- int offset;
-
- old_trans = ctx->trans0;
- new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
- "db_context->trans (expand)", db_trans_st);
- if (!new_trans)
- goto out;
- memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
-
- /* update trans0 (obviously) */
- ctx->trans0 = ctx->prop.trans = new_trans;
- /* update trans_cur (by offset) */
- offset = (char *)(new_trans) - (char *)(old_trans);
-
- {
- char *cctx = (char *)(ctx->trans_cur);
-
- cctx += offset;
- ctx->trans_cur = (struct db_trans *)cctx;
- }
- /* update elem count */
- ctx->max_trans = max_trans;
- PFREE_ST(old_trans, db_trans_st);
- ret = 0;
-out:
- return ret;
-}
-/*
- * Expand storage for attributes by delta_attrs number AND
- * rewrite trans->attr pointers
- */
-static int
-db_attrs_expand(struct db_context *ctx, int delta_attrs)
-{
- int ret = -1;
- struct db_attr *new_attrs, *old_attrs;
- struct db_trans *t;
- int ti;
- int max_attrs = ctx->max_attrs + delta_attrs;
- int offset;
-
- old_attrs = ctx->attrs0;
- new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
- "db_context->attrs (expand)", db_attrs_st);
- if (!new_attrs)
- goto out;
-
- memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
-
- /* update attrs0 and attrs_cur (obviously) */
- offset = (char *)(new_attrs) - (char *)(old_attrs);
-
- {
- char *actx = (char *)(ctx->attrs0);
-
- actx += offset;
- ctx->attrs0 = (struct db_attr *)actx;
-
- actx = (char *)ctx->attrs_cur;
- actx += offset;
- ctx->attrs_cur = (struct db_attr *)actx;
- }
-
- /* for each transform, rewrite attrs pointer by offsetting it */
- for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
- char *actx = (char *)(t->attrs);
-
- actx += offset;
- t->attrs = (struct db_attr *)actx;
- }
- /* update elem count */
- ctx->max_attrs = max_attrs;
- PFREE_ST(old_attrs, db_attrs_st);
- ret = 0;
-out:
- return ret;
-}
-/* Allocate a new db object */
-struct db_context *
-db_prop_new(u_int8_t protoid, int max_trans, int max_attrs)
-{
- struct db_context *ctx;
- ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), "db_context", db_context_st);
- if (!ctx) goto out;
-
- if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
- PFREE_ST(ctx, db_context_st);
- ctx=NULL;
- }
-out:
- return ctx;
-}
-/* Free a db object */
-void
-db_destroy(struct db_context *ctx)
-{
- if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
- if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
- PFREE_ST(ctx, db_context_st);
-}
-/* Start a new transform, expand trans0 is needed */
-int
-db_trans_add(struct db_context *ctx, u_int8_t transid)
-{
- /* skip incrementing current trans pointer the 1st time*/
- if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
- ctx->trans_cur++;
- /*
- * Strategy: if more space is needed, expand by
- * <current_size>/2 + 1
- *
- * This happens to produce a "reasonable" sequence
- * after few allocations, eg.:
- * 0,1,2,4,8,13,20,31,47
- */
- if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
- /* XXX:jjo if fails should shout and flag it */
- if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
- return -1;
- }
- ctx->trans_cur->transid = transid;
- ctx->trans_cur->attrs=ctx->attrs_cur;
- ctx->trans_cur->attr_cnt = 0;
- ctx->prop.trans_cnt++;
- return 0;
-}
-/* Add attr copy to current transform, expanding attrs0 if needed */
-int
-db_attr_add(struct db_context *ctx, const struct db_attr *a)
-{
- /*
- * Strategy: if more space is needed, expand by
- * <current_size>/2 + 1
- */
- if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
- /* XXX:jjo if fails should shout and flag it */
- if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
- return -1;
- }
- *ctx->attrs_cur++=*a;
- ctx->trans_cur->attr_cnt++;
- return 0;
-}
-/* Add attr copy (by value) to current transform,
- * expanding attrs0 if needed, just calls db_attr_add().
- */
-int
-db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val)
-{
- struct db_attr attr;
- attr.type = type;
- attr.val = val;
- return db_attr_add (ctx, &attr);
-}
-#ifndef NO_DB_OPS_STATS
-int
-db_ops_show_status(void)
-{
- whack_log(RC_COMMENT, "stats " __FILE__ ": "
- DB_OPS_STATS_DESC " :"
- DB_OPS_STATS_STR("context")
- DB_OPS_STATS_STR("trans")
- DB_OPS_STATS_STR("attrs"),
- DB_OPS_STATS_F(db_context_st),
- DB_OPS_STATS_F(db_trans_st),
- DB_OPS_STATS_F(db_attrs_st)
- );
- return 0;
-}
-#endif /* NO_DB_OPS_STATS */
-/*
- * From below to end just testing stuff ....
- */
-#ifdef TEST
-static void db_prop_print(struct db_prop *p)
-{
- struct db_trans *t;
- struct db_attr *a;
- int ti, ai;
- enum_names *n, *n_at, *n_av;
- printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
- for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
- switch( t->transid) {
- case PROTO_ISAKMP:
- n=&isakmp_transformid_names;break;
- case PROTO_IPSEC_ESP:
- n=&esp_transformid_names;break;
- default:
- continue;
- }
- printf(" transid=\"%s\"\n",
- enum_name(n, t->transid));
- for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
- int i;
- switch( t->transid) {
- case PROTO_ISAKMP:
- n_at=&oakley_attr_names;
- i=a->type|ISAKMP_ATTR_AF_TV;
- n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
- break;
- case PROTO_IPSEC_ESP:
- n_at=&ipsec_attr_names;
- i=a->type|ISAKMP_ATTR_AF_TV;
- n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
- break;
- default:
- continue;
- }
- printf(" type=\"%s\" value=\"%s\"\n",
- enum_name(n_at, i),
- enum_name(n_av, a->val));
- }
- }
-
-}
-static void db_print(struct db_context *ctx)
-{
- printf("trans_cur diff=%d, attrs_cur diff=%d\n",
- ctx->trans_cur - ctx->trans0,
- ctx->attrs_cur - ctx->attrs0);
- db_prop_print(&ctx->prop);
-}
-
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no);
-void abort(void);
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
-{
- fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- abort(); /* exiting correctly doesn't always work */
-}
-int main(void) {
- struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
- db_trans_add(ctx, KEY_IKE);
- db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC);
- db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
- db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
- db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
- db_trans_add(ctx, KEY_IKE);
- db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC);
- db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
- db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
- db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
- db_trans_add(ctx, ESP_3DES);
- db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
- db_print(ctx);
- db_destroy(ctx);
- return 0;
-}
-#endif
diff --git a/programs/pluto/db_ops.h b/programs/pluto/db_ops.h
deleted file mode 100644
index 433e75280..000000000
--- a/programs/pluto/db_ops.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Dynamic db (proposal, transforms, attributes) handling.
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: db_ops.h,v 1.3 2004/09/17 12:37:37 as Exp $
- */
-
-#ifndef _DB_OPS_H
-#define _DB_OPS_H
-
-/*
- * Main db object, (quite proposal "oriented")
- */
-#ifndef NO_DB_CONTEXT
-struct db_context {
- struct db_prop prop; /* proposal buffer (not pointer) */
- struct db_trans *trans0; /* transf. list, dynamically sized */
- struct db_trans *trans_cur; /* current transform ptr */
- struct db_attr *attrs0; /* attr. list, dynamically sized */
- struct db_attr *attrs_cur; /* current attribute ptr */
- int max_trans; /* size of trans list */
- int max_attrs; /* size of attrs list */
-};
-/*
- * Allocate a new db object
- */
-struct db_context * db_prop_new(u_int8_t protoid, int max_trans, int max_attrs);
-/* Initialize object for proposal building */
-int db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs);
-/* Free all resourses for this db */
-void db_destroy(struct db_context *ctx);
-
-/* Start a new transform */
-int db_trans_add(struct db_context *ctx, u_int8_t transid);
-/* Add a new attribute by copying db_attr content */
-int db_attr_add(struct db_context *db_ctx, const struct db_attr *attr);
-/* Add a new attribute by value */
-int db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val);
-
-/* Get proposal from db object */
-static __inline__ struct db_prop *db_prop_get(struct db_context *ctx) {
- return &ctx->prop;
-}
-/* Show stats (allocation, etc) */
-#endif /* NO_DB_CONTEXT */
-int db_ops_show_status(void);
-#endif /* _DB_OPS_H */
diff --git a/programs/pluto/defs.c b/programs/pluto/defs.c
deleted file mode 100644
index 16f6a3949..000000000
--- a/programs/pluto/defs.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/* misc. universal things
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: defs.c,v 1.9 2006/01/04 21:00:43 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-const chunk_t empty_chunk = { NULL, 0 };
-
-bool
-all_zero(const unsigned char *m, size_t len)
-{
- size_t i;
-
- for (i = 0; i != len; i++)
- if (m[i] != '\0')
- return FALSE;
- return TRUE;
-}
-
-/* memory allocation
- *
- * LEAK_DETECTIVE puts a wrapper around each allocation and maintains
- * a list of live ones. If a dead one is freed, an assertion MIGHT fail.
- * If the live list is currupted, that will often be detected.
- * In the end, report_leaks() is called, and the names of remaining
- * live allocations are printed. At the moment, it is hoped, not that
- * the list is empty, but that there will be no surprises.
- *
- * Accepted Leaks:
- * - "struct iface" and "device name" (for "discovered" net interfaces)
- * - "struct event in event_schedule()" (events not associated with states)
- * - "Pluto lock name" (one only, needed until end -- why bother?)
- */
-
-#ifdef LEAK_DETECTIVE
-
-/* this magic number is 3671129837 decimal (623837458 complemented) */
-#define LEAK_MAGIC 0xDAD0FEEDul
-
-union mhdr {
- struct {
- const char *name;
- union mhdr *older, *newer;
- unsigned long magic;
- } i; /* info */
- unsigned long junk; /* force maximal alignment */
-};
-
-static union mhdr *allocs = NULL;
-
-void *alloc_bytes(size_t size, const char *name)
-{
- union mhdr *p = malloc(sizeof(union mhdr) + size);
-
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- p->i.name = name;
- p->i.older = allocs;
- if (allocs != NULL)
- allocs->i.newer = p;
- allocs = p;
- p->i.newer = NULL;
- p->i.magic = LEAK_MAGIC;
-
- memset(p+1, '\0', size);
- return p+1;
-}
-
-void *
-clone_bytes(const void *orig, size_t size, const char *name)
-{
- void *p = alloc_bytes(size, name);
-
- memcpy(p, orig, size);
- return p;
-}
-
-void
-pfree(void *ptr)
-{
- union mhdr *p;
-
- passert(ptr != NULL);
- p = ((union mhdr *)ptr) - 1;
- passert(p->i.magic == LEAK_MAGIC);
- if (p->i.older != NULL)
- {
- passert(p->i.older->i.newer == p);
- p->i.older->i.newer = p->i.newer;
- }
- if (p->i.newer == NULL)
- {
- passert(p == allocs);
- allocs = p->i.older;
- }
- else
- {
- passert(p->i.newer->i.older == p);
- p->i.newer->i.older = p->i.older;
- }
- p->i.magic = ~LEAK_MAGIC;
- free(p);
-}
-
-void
-report_leaks(void)
-{
- union mhdr
- *p = allocs,
- *pprev = NULL;
- unsigned long n = 0;
-
- while (p != NULL)
- {
- passert(p->i.magic == LEAK_MAGIC);
- passert(pprev == p->i.newer);
- pprev = p;
- p = p->i.older;
- n++;
- if (p == NULL || pprev->i.name != p->i.name)
- {
- if (n != 1)
- plog("leak: %lu * %s", n, pprev->i.name);
- else
- plog("leak: %s", pprev->i.name);
- n = 0;
- }
- }
-}
-
-#else /* !LEAK_DETECTIVE */
-
-void *alloc_bytes(size_t size, const char *name)
-{
- void *p = malloc(size);
-
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-
-void *clone_bytes(const void *orig, size_t size, const char *name)
-{
- void *p = malloc(size);
-
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- memcpy(p, orig, size);
- return p;
-}
-#endif /* !LEAK_DETECTIVE */
-
-/* Note that there may be as many as six IDs that are temporary at
- * one time before unsharing the two ends of a connection. So we need
- * at least six temporary buffers for DER_ASN1_DN IDs.
- * We rotate them. Be careful!
- */
-#define MAX_BUF 10
-
-char*
-temporary_cyclic_buffer(void)
-{
- static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
- static int counter = 0; /* cyclic counter */
-
- if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
- return buf[counter]; /* assign temporary buffer */
-}
-
-/* concatenates two sub paths into a string with a maximum size of BUF_LEN
- * use for temporary storage only
- */
-const char*
-concatenate_paths(const char *a, const char *b)
-{
- char *c;
-
- if (*b == '/' || *b == '.')
- return b;
-
- c = temporary_cyclic_buffer();
- snprintf(c, BUF_LEN, "%s/%s", a, b);
- return c;
-}
-
-/* compare two chunks, returns zero if a equals b
- * negative/positive if a is earlier/later in the alphabet than b
- */
-bool
-cmp_chunk(chunk_t a, chunk_t b)
-{
- int cmp_len, len, cmp_value;
-
- cmp_len = a.len - b.len;
- len = (cmp_len < 0)? a.len : b.len;
- cmp_value = memcmp(a.ptr, b.ptr, len);
-
- return (cmp_value == 0)? cmp_len : cmp_value;
-};
-
-/* moves a chunk to a memory position, chunk is freed afterwards
- * position pointer is advanced after the insertion point
- */
-void
-mv_chunk(u_char **pos, chunk_t content)
-{
- if (content.len > 0)
- {
- chunkcpy(*pos, content);
- freeanychunk(content);
- }
-}
-
-/*
- * write the binary contents of a chunk_t to a file
- */
-bool
-write_chunk(const char *filename, const char *label, chunk_t ch
-, mode_t mask, bool force)
-{
- mode_t oldmask;
- FILE *fd;
-
- if (!force)
- {
- fd = fopen(filename, "r");
- if (fd)
- {
- fclose(fd);
- plog(" %s file '%s' already exists", label, filename);
- return FALSE;
- }
- }
-
- /* set umask */
- oldmask = umask(mask);
-
- fd = fopen(filename, "w");
-
- if (fd)
- {
- fwrite(ch.ptr, sizeof(u_char), ch.len, fd);
- fclose(fd);
- plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
- umask(oldmask);
- return TRUE;
- }
- else
- {
- plog(" could not open %s file '%s' for writing", label, filename);
- umask(oldmask);
- return FALSE;
- }
-}
-
-/* Names of the months */
-
-static const char* months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-
-/*
- * Display a date either in local or UTC time
- */
-char*
-timetoa(const time_t *time, bool utc)
-{
- static char buf[TIMETOA_BUF];
-
- if (*time == UNDEFINED_TIME)
- sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
- else
- {
- struct tm *t = (utc)? gmtime(time) : localtime(time);
-
- sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
- months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
- (utc)?" UTC ":" ", t->tm_year + 1900
- );
- }
- return buf;
-}
-
-/* checks if the expiration date has been reached and
- * warns during the warning_interval of the imminent
- * expiry. strict=TRUE declares a fatal error,
- * strict=FALSE issues a warning upon expiry.
- */
-const char*
-check_expiry(time_t expiration_date, int warning_interval, bool strict)
-{
- time_t now;
- int time_left;
-
- if (expiration_date == UNDEFINED_TIME)
- return "ok (expires never)";
-
- /* determine the current time */
- time(&now);
-
- time_left = (expiration_date - now);
- if (time_left < 0)
- return strict? "fatal (expired)" : "warning (expired)";
-
- if (time_left > 86400*warning_interval)
- return "ok";
- {
- static char buf[35]; /* temporary storage */
- const char* unit = "second";
-
- if (time_left > 172800)
- {
- time_left /= 86400;
- unit = "day";
- }
- else if (time_left > 7200)
- {
- time_left /= 3600;
- unit = "hour";
- }
- else if (time_left > 120)
- {
- time_left /= 60;
- unit = "minute";
- }
- snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
- unit, (time_left == 1)?"":"s");
- return buf;
- }
-}
-
-
-/*
- * Filter eliminating the directory entries '.' and '..'
- */
-int
-file_select(const struct dirent *entry)
-{
- return strcmp(entry->d_name, "." ) &&
- strcmp(entry->d_name, "..");
-}
-
-
diff --git a/programs/pluto/defs.h b/programs/pluto/defs.h
deleted file mode 100644
index 3fe5053d1..000000000
--- a/programs/pluto/defs.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* misc. universal things
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: defs.h,v 1.11 2007/01/09 21:59:06 as Exp $
- */
-
-#ifndef _DEFS_H
-#define _DEFS_H
-
-#include <sys/types.h>
-
-#ifdef KLIPS
-# define USED_BY_KLIPS /* ignore */
-#else
-# define USED_BY_KLIPS UNUSED
-#endif
-
-#ifdef DEBUG
-# define USED_BY_DEBUG /* ignore */
-#else
-# define USED_BY_DEBUG UNUSED
-#endif
-
-/* Length of temporary buffers */
-
-#define BUF_LEN 512
-
-/* type of serial number of a state object
- * Needed in connections.h and state.h; here to simplify dependencies.
- */
-typedef unsigned long so_serial_t;
-#define SOS_NOBODY 0 /* null serial number */
-#define SOS_FIRST 1 /* first normal serial number */
-
-/* memory allocation */
-
-extern void *alloc_bytes(size_t size, const char *name);
-#define alloc_thing(thing, name) (alloc_bytes(sizeof(thing), (name)))
-
-extern void *clone_bytes(const void *orig, size_t size, const char *name);
-#define clone_thing(orig, name) clone_bytes((const void *)&(orig), sizeof(orig), (name))
-#define clone_str(str, name) \
- ((str) == NULL? NULL : clone_bytes((str), strlen((str))+1, (name)))
-
-#ifdef LEAK_DETECTIVE
- extern void pfree(void *ptr);
- extern void report_leaks(void);
-#else
-# define pfree(ptr) free(ptr) /* ordinary stdc free */
-#endif
-#define pfreeany(p) { if ((p) != NULL) pfree(p); }
-#define replace(p, q) { pfreeany(p); (p) = (q); }
-
-
-/* chunk is a simple pointer-and-size abstraction */
-
-struct chunk {
- u_char *ptr;
- size_t len;
- };
-typedef struct chunk chunk_t;
-
-#define setchunk(ch, addr, size) { (ch).ptr = (addr); (ch).len = (size); }
-#define strchunk(str) { str, sizeof(str) }
-/* NOTE: freeanychunk, unlike pfreeany, NULLs .ptr */
-#define freeanychunk(ch) { pfreeany((ch).ptr); (ch).ptr = NULL; }
-#define clonetochunk(ch, addr, size, name) \
- { (ch).ptr = clone_bytes((addr), (ch).len = (size), name); }
-#define clonereplacechunk(ch, addr, size, name) \
- { pfreeany((ch).ptr); clonetochunk(ch, addr, size, name); }
-#define chunkcpy(dst, chunk) \
- { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
-#define same_chunk(a, b) \
- ( (a).len == (b).len && memcmp((a).ptr, (b).ptr, (b).len) == 0 )
-
-extern char* temporary_cyclic_buffer(void);
-extern const char* concatenate_paths(const char *a, const char *b);
-
-extern const chunk_t empty_chunk;
-
-/* compare two chunks */
-extern bool cmp_chunk(chunk_t a, chunk_t b);
-
-/* move a chunk to a memory position and free it after insertion */
-extern void mv_chunk(u_char **pos, chunk_t content);
-
-/* write the binary contents of a chunk_t to a file */
-extern bool write_chunk(const char *filename, const char *label, chunk_t ch
- ,mode_t mask, bool force);
-
-/* display a date either in local or UTC time */
-extern char* timetoa(const time_t *time, bool utc);
-
-/* warns a predefined interval before expiry */
-extern const char* check_expiry(time_t expiration_date,
- int warning_interval, bool strict);
-
-#define MAX_PROMPT_PASS_TRIALS 5
-#define PROMPT_PASS_LEN 64
-
-/* struct used to prompt for a secret passphrase
- * from a console with file descriptor fd
- */
-typedef struct {
- char secret[PROMPT_PASS_LEN+1];
- bool prompt;
- int fd;
-} prompt_pass_t;
-
-/* no time defined in time_t */
-#define UNDEFINED_TIME 0
-
-/* size of timetoa string buffer */
-#define TIMETOA_BUF 30
-
-/* filter eliminating the directory entries '.' and '..' */
-typedef struct dirent dirent_t;
-extern int file_select(const dirent_t *entry);
-
-/* cleanly exit Pluto */
-
-extern void exit_pluto(int /*status*/) NEVER_RETURNS;
-
-
-/* zero all bytes */
-#define zero(x) memset((x), '\0', sizeof(*(x)))
-
-/* are all bytes 0? */
-extern bool all_zero(const unsigned char *m, size_t len);
-
-/* pad_up(n, m) is the amount to add to n to make it a multiple of m */
-#define pad_up(n, m) (((m) - 1) - (((n) + (m) - 1) % (m)))
-
-#endif /* _DEFS_H */
diff --git a/programs/pluto/demux.c b/programs/pluto/demux.c
deleted file mode 100644
index 71aa771c7..000000000
--- a/programs/pluto/demux.c
+++ /dev/null
@@ -1,2526 +0,0 @@
-/* demultiplex incoming IKE messages
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: demux.c,v 1.18 2007/01/29 08:27:53 as Exp $
- */
-
-/* Ordering Constraints on Payloads
- *
- * rfc2409: The Internet Key Exchange (IKE)
- *
- * 5 Exchanges:
- * "The SA payload MUST precede all other payloads in a phase 1 exchange."
- *
- * "Except where otherwise noted, there are no requirements for ISAKMP
- * payloads in any message to be in any particular order."
- *
- * 5.3 Phase 1 Authenticated With a Revised Mode of Public Key Encryption:
- *
- * "If the HASH payload is sent it MUST be the first payload of the
- * second message exchange and MUST be followed by the encrypted
- * nonce. If the HASH payload is not sent, the first payload of the
- * second message exchange MUST be the encrypted nonce."
- *
- * "Save the requirements on the location of the optional HASH payload
- * and the mandatory nonce payload there are no further payload
- * requirements. All payloads-- in whatever order-- following the
- * encrypted nonce MUST be encrypted with Ke_i or Ke_r depending on the
- * direction."
- *
- * 5.5 Phase 2 - Quick Mode
- *
- * "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
- * header and a SA payload MUST immediately follow the HASH."
- * [NOTE: there may be more than one SA payload, so this is not
- * totally reasonable. Probably all SAs should be so constrained.]
- *
- * "If ISAKMP is acting as a client negotiator on behalf of another
- * party, the identities of the parties MUST be passed as IDci and
- * then IDcr."
- *
- * "With the exception of the HASH, SA, and the optional ID payloads,
- * there are no payload ordering restrictions on Quick Mode."
- */
-
-/* Unfolding of Identity -- a central mystery
- *
- * This concerns Phase 1 identities, those of the IKE hosts.
- * These are the only ones that are authenticated. Phase 2
- * identities are for IPsec SAs.
- *
- * There are three case of interest:
- *
- * (1) We initiate, based on a whack command specifying a Connection.
- * We know the identity of the peer from the Connection.
- *
- * (2) (to be implemented) we initiate based on a flow from our client
- * to some IP address.
- * We immediately know one of the peer's client IP addresses from
- * the flow. We must use this to figure out the peer's IP address
- * and Id. To be solved.
- *
- * (3) We respond to an IKE negotiation.
- * We immediately know the peer's IP address.
- * We get an ID Payload in Main I2.
- *
- * Unfortunately, this is too late for a number of things:
- * - the ISAKMP SA proposals have already been made (Main I1)
- * AND one accepted (Main R1)
- * - the SA includes a specification of the type of ID
- * authentication so this is negotiated without being told the ID.
- * - with Preshared Key authentication, Main I2 is encrypted
- * using the key, so it cannot be decoded to reveal the ID
- * without knowing (or guessing) which key to use.
- *
- * There are three reasonable choices here for the responder:
- * + assume that the initiator is making wise offers since it
- * knows the IDs involved. We can balk later (but not gracefully)
- * when we find the actual initiator ID
- * + attempt to infer identity by IP address. Again, we can balk
- * when the true identity is revealed. Actually, it is enough
- * to infer properties of the identity (eg. SA properties and
- * PSK, if needed).
- * + make all properties universal so discrimination based on
- * identity isn't required. For example, always accept the same
- * kinds of encryption. Accept Public Key Id authentication
- * since the Initiator presumably has our public key and thinks
- * we must have / can find his. This approach is weakest
- * for preshared key since the actual key must be known to
- * decrypt the Initiator's ID Payload.
- * These choices can be blended. For example, a class of Identities
- * can be inferred, sufficient to select a preshared key but not
- * sufficient to infer a unique identity.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/time.h> /* only used for belt-and-suspenders select call */
-#include <sys/poll.h> /* only used for forensic poll call */
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-# include <asm/types.h> /* for __u8, __u32 */
-# include <linux/errqueue.h>
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "cookie.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-#include "ike_alg.h"
-#include "log.h"
-#include "demux.h" /* needs packet.h */
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "timer.h"
-#include "whack.h" /* requires connections.h */
-#include "server.h"
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-#include "vendor.h"
-#include "modecfg.h"
-
-/* This file does basic header checking and demux of
- * incoming packets.
- */
-
-/* forward declarations */
-static bool read_packet(struct msg_digest *md);
-static void process_packet(struct msg_digest **mdp);
-
-/* Reply messages are built in this buffer.
- * Only one state transition function can be using it at a time
- * so suspended STFs must save and restore it.
- * It could be an auto variable of complete_state_transition except for the fact
- * that when a suspended STF resumes, its reply message buffer
- * must be at the same location -- there are pointers into it.
- */
-u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
-
-/* state_microcode is a tuple of information parameterizing certain
- * centralized processing of a packet. For example, it roughly
- * specifies what payloads are expected in this message.
- * The microcode is selected primarily based on the state.
- * In Phase 1, the payload structure often depends on the
- * authentication technique, so that too plays a part in selecting
- * the state_microcode to use.
- */
-
-struct state_microcode {
- enum state_kind state, next_state;
- lset_t flags;
- lset_t req_payloads; /* required payloads (allows just one) */
- lset_t opt_payloads; /* optional payloads (any mumber) */
- /* if not ISAKMP_NEXT_NONE, process_packet will emit HDR with this as np */
- u_int8_t first_out_payload;
- enum event_type timeout_event;
- state_transition_fn *processor;
-};
-
-/* State Microcode Flags, in several groups */
-
-/* Oakley Auth values: to which auth values does this entry apply?
- * Most entries will use SMF_ALL_AUTH because they apply to all.
- * Note: SMF_ALL_AUTH matches 0 for those circumstances when no auth
- * has been set.
- */
-#define SMF_ALL_AUTH LRANGE(0, OAKLEY_AUTH_ROOF-1)
-#define SMF_PSK_AUTH LELEM(OAKLEY_PRESHARED_KEY)
-#define SMF_DS_AUTH (LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG))
-#define SMF_PKE_AUTH (LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC))
-#define SMF_RPKE_AUTH (LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV))
-
-/* misc flags */
-
-#define SMF_INITIATOR LELEM(OAKLEY_AUTH_ROOF + 0)
-#define SMF_FIRST_ENCRYPTED_INPUT LELEM(OAKLEY_AUTH_ROOF + 1)
-#define SMF_INPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 2)
-#define SMF_OUTPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 3)
-#define SMF_RETRANSMIT_ON_DUPLICATE LELEM(OAKLEY_AUTH_ROOF + 4)
-
-#define SMF_ENCRYPTED (SMF_INPUT_ENCRYPTED | SMF_OUTPUT_ENCRYPTED)
-
-/* this state generates a reply message */
-#define SMF_REPLY LELEM(OAKLEY_AUTH_ROOF + 5)
-
-/* this state completes P1, so any pending P2 negotiations should start */
-#define SMF_RELEASE_PENDING_P2 LELEM(OAKLEY_AUTH_ROOF + 6)
-
-/* end of flags */
-
-
-static state_transition_fn /* forward declaration */
- unexpected,
- informational;
-
-/* state_microcode_table is a table of all state_microcode tuples.
- * It must be in order of state (the first element).
- * After initialization, ike_microcode_index[s] points to the
- * first entry in state_microcode_table for state s.
- * Remember that each state name in Main or Quick Mode describes
- * what has happened in the past, not what this message is.
- */
-
-static const struct state_microcode
- *ike_microcode_index[STATE_IKE_ROOF - STATE_IKE_FLOOR];
-
-static const struct state_microcode state_microcode_table[] = {
-#define PT(n) ISAKMP_NEXT_##n
-#define P(n) LELEM(PT(n))
-
- /***** Phase 1 Main Mode *****/
-
- /* No state for main_outI1: --> HDR, SA */
-
- /* STATE_MAIN_R0: I1 --> R1
- * HDR, SA --> HDR, SA
- */
- { STATE_MAIN_R0, STATE_MAIN_R1
- , SMF_ALL_AUTH | SMF_REPLY
- , P(SA), P(VID) | P(CR), PT(NONE)
- , EVENT_RETRANSMIT, main_inI1_outR1},
-
- /* STATE_MAIN_I1: R1 --> I2
- * HDR, SA --> auth dependent
- * SMF_PSK_AUTH, SMF_DS_AUTH: --> HDR, KE, Ni
- * SMF_PKE_AUTH:
- * --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * SMF_RPKE_AUTH:
- * --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * Note: since we don't know auth at start, we cannot differentiate
- * microcode entries based on it.
- */
- { STATE_MAIN_I1, STATE_MAIN_I2
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY
- , P(SA), P(VID) | P(CR), PT(NONE) /* don't know yet */
- , EVENT_RETRANSMIT, main_inR1_outI2 },
-
- /* STATE_MAIN_R1: I2 --> R2
- * SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
- * SMF_PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * SMF_RPKE_AUTH:
- * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- */
- { STATE_MAIN_R1, STATE_MAIN_R2
- , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY
-#ifdef NAT_TRAVERSAL
- , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(KE)
-#else
- , P(KE) | P(NONCE), P(VID) | P(CR), PT(KE)
-#endif
- , EVENT_RETRANSMIT, main_inI2_outR2 },
-
- { STATE_MAIN_R1, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_REPLY
- , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH), PT(KE)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- { STATE_MAIN_R1, STATE_UNDEFINED
- , SMF_RPKE_AUTH | SMF_REPLY
- , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT), PT(NONCE)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- /* for states from here on, output message must be encrypted */
-
- /* STATE_MAIN_I2: R2 --> I3
- * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
- * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
- * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * --> HDR*, HASH_I
- * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- * --> HDR*, HASH_I
- */
- { STATE_MAIN_I2, STATE_MAIN_I3
- , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
-#ifdef NAT_TRAVERSAL
- , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(ID)
-#else
- , P(KE) | P(NONCE), P(VID) | P(CR), PT(ID)
-#endif
- , EVENT_RETRANSMIT, main_inR2_outI3 },
-
- { STATE_MAIN_I2, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
- , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR), PT(HASH)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- { STATE_MAIN_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
- , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR), PT(HASH)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- /* for states from here on, input message must be encrypted */
-
- /* STATE_MAIN_R2: I3 --> R3
- * SMF_PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
- * SMF_DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
- * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
- */
- { STATE_MAIN_R2, STATE_MAIN_R3
- , SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, main_inI3_outR3 },
-
- { STATE_MAIN_R2, STATE_MAIN_R3
- , SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
- , EVENT_SA_REPLACE, main_inI3_outR3 },
-
- { STATE_MAIN_R2, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
- /* STATE_MAIN_I3: R3 --> done
- * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done
- * SMF_DS_AUTH: HDR*, IDr1, [ CERT, ] SIG_R --> done
- * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_R --> done
- * May initiate quick mode by calling quick_outI1
- */
- { STATE_MAIN_I3, STATE_MAIN_I4
- , SMF_PSK_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, main_inR3 },
-
- { STATE_MAIN_I3, STATE_MAIN_I4
- , SMF_DS_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
- , EVENT_SA_REPLACE, main_inR3 },
-
- { STATE_MAIN_I3, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
- /* STATE_MAIN_R3: can only get here due to packet loss */
- { STATE_MAIN_R3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
- , LEMPTY, LEMPTY
- , PT(NONE), EVENT_NULL, unexpected },
-
- /* STATE_MAIN_I4: can only get here due to packet loss */
- { STATE_MAIN_I4, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED
- , LEMPTY, LEMPTY
- , PT(NONE), EVENT_NULL, unexpected },
-
-
- /***** Phase 2 Quick Mode *****/
-
- /* No state for quick_outI1:
- * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
- */
-
- /* STATE_QUICK_R0:
- * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
- * Installs inbound IPsec SAs.
- * Because it may suspend for asynchronous DNS, first_out_payload
- * is set to NONE to suppress early emission of HDR*.
- * ??? it is legal to have multiple SAs, but we don't support it yet.
- */
- { STATE_QUICK_R0, STATE_QUICK_R1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
-#ifdef NAT_TRAVERSAL
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(NONE)
-#else
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID), PT(NONE)
-#endif
- , EVENT_RETRANSMIT, quick_inI1_outR1 },
-
- /* STATE_QUICK_I1:
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(3)
- * Installs inbound and outbound IPsec SAs, routing, etc.
- * ??? it is legal to have multiple SAs, but we don't support it yet.
- */
- { STATE_QUICK_I1, STATE_QUICK_I2
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY
-#ifdef NAT_TRAVERSAL
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(HASH)
-#else
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID), PT(HASH)
-#endif
- , EVENT_SA_REPLACE, quick_inR1_outI2 },
-
- /* STATE_QUICK_R1: HDR*, HASH(3) --> done
- * Installs outbound IPsec SAs, routing, etc.
- */
- { STATE_QUICK_R1, STATE_QUICK_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(HASH), LEMPTY, PT(NONE)
- , EVENT_SA_REPLACE, quick_inI2 },
-
- /* STATE_QUICK_I2: can only happen due to lost packet */
- { STATE_QUICK_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- /* STATE_QUICK_R2: can only happen due to lost packet */
- { STATE_QUICK_R2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
-
- /***** informational messages *****/
-
- /* STATE_INFO: */
- { STATE_INFO, STATE_UNDEFINED
- , SMF_ALL_AUTH
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, informational },
-
- /* STATE_INFO_PROTECTED: */
- { STATE_INFO_PROTECTED, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(HASH), LEMPTY, PT(NONE)
- , EVENT_NULL, informational },
-
- /* XAUTH state transitions */
- { STATE_XAUTH_I0, STATE_XAUTH_I1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_RETRANSMIT, xauth_inI0 },
-
- { STATE_XAUTH_R1, STATE_XAUTH_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_RETRANSMIT, xauth_inR1 },
-
- { STATE_XAUTH_I1, STATE_XAUTH_I2
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, xauth_inI1 },
-
- { STATE_XAUTH_R2, STATE_XAUTH_R3
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(NONE)
- , EVENT_SA_REPLACE, xauth_inR2 },
-
- { STATE_XAUTH_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- { STATE_XAUTH_R3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- /* ModeCfg pull mode state transitions */
-
- { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR0 },
-
- { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI1 },
-
- { STATE_MODE_CFG_R1, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- { STATE_MODE_CFG_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- /* ModeCfg push mode state transitions */
-
- { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI0 },
-
- { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR3 },
-
- { STATE_MODE_CFG_I3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- { STATE_MODE_CFG_R4, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
-#undef P
-#undef PT
-};
-
-void
-init_demux(void)
-{
- /* fill ike_microcode_index:
- * make ike_microcode_index[s] point to first entry in
- * state_microcode_table for state s (backward scan makes this easier).
- * Check that table is in order -- catch coding errors.
- * For what it's worth, this routine is idempotent.
- */
- const struct state_microcode *t;
-
- for (t = &state_microcode_table[elemsof(state_microcode_table) - 1];;)
- {
- passert(STATE_IKE_FLOOR <= t->state && t->state < STATE_IKE_ROOF);
- ike_microcode_index[t->state - STATE_IKE_FLOOR] = t;
- if (t == state_microcode_table)
- break;
- t--;
- passert(t[0].state <= t[1].state);
- }
-}
-
-/* Process any message on the MSG_ERRQUEUE
- *
- * This information is generated because of the IP_RECVERR socket option.
- * The API is sparsely documented, and may be LINUX-only, and only on
- * fairly recent versions at that (hence the conditional compilation).
- *
- * - ip(7) describes IP_RECVERR
- * - recvmsg(2) describes MSG_ERRQUEUE
- * - readv(2) describes iovec
- * - cmsg(3) describes how to process auxilliary messages
- *
- * ??? we should link this message with one we've sent
- * so that the diagnostic can refer to that negotiation.
- *
- * ??? how long can the messge be?
- *
- * ??? poll(2) has a very incomplete description of the POLL* events.
- * We assume that POLLIN, POLLOUT, and POLLERR are all we need to deal with
- * and that POLLERR will be on iff there is a MSG_ERRQUEUE message.
- *
- * We have to code around a couple of surprises:
- *
- * - Select can say that a socket is ready to read from, and
- * yet a read will hang. It turns out that a message available on the
- * MSG_ERRQUEUE will cause select to say something is pending, but
- * a normal read will hang. poll(2) can tell when a MSG_ERRQUEUE
- * message is pending.
- *
- * This is dealt with by calling check_msg_errqueue after select
- * has indicated that there is something to read, but before the
- * read is performed. check_msg_errqueue will return TRUE if there
- * is something left to read.
- *
- * - A write to a socket may fail because there is a pending MSG_ERRQUEUE
- * message, without there being anything wrong with the write. This
- * makes for confusing diagnostics.
- *
- * To avoid this, we call check_msg_errqueue before a write. True,
- * there is a race condition (a MSG_ERRQUEUE message might arrive
- * between the check and the write), but we should eliminate many
- * of the problematic events. To narrow the window, the poll(2)
- * will await until an event happens (in the case or a write,
- * POLLOUT; this should be benign for POLLIN).
- */
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-static bool
-check_msg_errqueue(const struct iface *ifp, short interest)
-{
- struct pollfd pfd;
-
- pfd.fd = ifp->fd;
- pfd.events = interest | POLLPRI | POLLOUT;
-
- while (pfd.revents = 0
- , poll(&pfd, 1, -1) > 0 && (pfd.revents & POLLERR))
- {
- u_int8_t buffer[3000]; /* hope that this is big enough */
- union
- {
- struct sockaddr sa;
- struct sockaddr_in sa_in4;
- struct sockaddr_in6 sa_in6;
- } from;
-
- int from_len = sizeof(from);
-
- int packet_len;
-
- struct msghdr emh;
- struct iovec eiov;
- union {
- /* force alignment (not documented as necessary) */
- struct cmsghdr ecms;
-
- /* how much space is enough? */
- unsigned char space[256];
- } ecms_buf;
-
- struct cmsghdr *cm;
- char fromstr[sizeof(" for message to port 65536") + INET6_ADDRSTRLEN];
- struct state *sender = NULL;
-
- zero(&from.sa);
- from_len = sizeof(from);
-
- emh.msg_name = &from.sa; /* ??? filled in? */
- emh.msg_namelen = sizeof(from);
- emh.msg_iov = &eiov;
- emh.msg_iovlen = 1;
- emh.msg_control = &ecms_buf;
- emh.msg_controllen = sizeof(ecms_buf);
- emh.msg_flags = 0;
-
- eiov.iov_base = buffer; /* see readv(2) */
- eiov.iov_len = sizeof(buffer);
-
- packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUE);
-
- if (packet_len == -1)
- {
- log_errno((e, "recvmsg(,, MSG_ERRQUEUE) on %s failed in comm_handle"
- , ifp->rname));
- break;
- }
- else if (packet_len == sizeof(buffer))
- {
- plog("MSG_ERRQUEUE message longer than %lu bytes; truncated"
- , (unsigned long) sizeof(buffer));
- }
- else
- {
- sender = find_sender((size_t) packet_len, buffer);
- }
-
- DBG_cond_dump(DBG_ALL, "rejected packet:\n", buffer, packet_len);
- DBG_cond_dump(DBG_ALL, "control:\n", emh.msg_control, emh.msg_controllen);
- /* ??? Andi Kleen <ak@suse.de> and misc documentation
- * suggests that name will have the original destination
- * of the packet. We seem to see msg_namelen == 0.
- * Andi says that this is a kernel bug and has fixed it.
- * Perhaps in 2.2.18/2.4.0.
- */
- passert(emh.msg_name == &from.sa);
- DBG_cond_dump(DBG_ALL, "name:\n", emh.msg_name
- , emh.msg_namelen);
-
- fromstr[0] = '\0'; /* usual case :-( */
- switch (from.sa.sa_family)
- {
- char as[INET6_ADDRSTRLEN];
-
- case AF_INET:
- if (emh.msg_namelen == sizeof(struct sockaddr_in))
- snprintf(fromstr, sizeof(fromstr)
- , " for message to %s port %u"
- , inet_ntop(from.sa.sa_family
- , &from.sa_in4.sin_addr, as, sizeof(as))
- , ntohs(from.sa_in4.sin_port));
- break;
- case AF_INET6:
- if (emh.msg_namelen == sizeof(struct sockaddr_in6))
- snprintf(fromstr, sizeof(fromstr)
- , " for message to %s port %u"
- , inet_ntop(from.sa.sa_family
- , &from.sa_in6.sin6_addr, as, sizeof(as))
- , ntohs(from.sa_in6.sin6_port));
- break;
- }
-
- for (cm = CMSG_FIRSTHDR(&emh)
- ; cm != NULL
- ; cm = CMSG_NXTHDR(&emh,cm))
- {
- if (cm->cmsg_level == SOL_IP
- && cm->cmsg_type == IP_RECVERR)
- {
- /* ip(7) and recvmsg(2) specify:
- * ee_origin is SO_EE_ORIGIN_ICMP for ICMP
- * or SO_EE_ORIGIN_LOCAL for locally generated errors.
- * ee_type and ee_code are from the ICMP header.
- * ee_info is the discovered MTU for EMSGSIZE errors
- * ee_data is not used.
- *
- * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but
- * means "SO_EE_OFFENDER". The OFFENDER is really
- * the router that complained. As such, the port
- * is meaningless.
- */
-
- /* ??? cmsg(3) claims that CMSG_DATA returns
- * void *, but RFC 2292 and /usr/include/bits/socket.h
- * say unsigned char *. The manual is being fixed.
- */
- struct sock_extended_err *ee = (void *)CMSG_DATA(cm);
- const char *offstr = "unspecified";
- char offstrspace[INET6_ADDRSTRLEN];
- char orname[50];
-
- if (cm->cmsg_len > CMSG_LEN(sizeof(struct sock_extended_err)))
- {
- const struct sockaddr *offender = SO_EE_OFFENDER(ee);
-
- switch (offender->sa_family)
- {
- case AF_INET:
- offstr = inet_ntop(offender->sa_family
- , &((const struct sockaddr_in *)offender)->sin_addr
- , offstrspace, sizeof(offstrspace));
- break;
- case AF_INET6:
- offstr = inet_ntop(offender->sa_family
- , &((const struct sockaddr_in6 *)offender)->sin6_addr
- , offstrspace, sizeof(offstrspace));
- break;
- default:
- offstr = "unknown";
- break;
- }
- }
-
- switch (ee->ee_origin)
- {
- case SO_EE_ORIGIN_NONE:
- snprintf(orname, sizeof(orname), "none");
- break;
- case SO_EE_ORIGIN_LOCAL:
- snprintf(orname, sizeof(orname), "local");
- break;
- case SO_EE_ORIGIN_ICMP:
- snprintf(orname, sizeof(orname)
- , "ICMP type %d code %d (not authenticated)"
- , ee->ee_type, ee->ee_code
- );
- break;
- case SO_EE_ORIGIN_ICMP6:
- snprintf(orname, sizeof(orname)
- , "ICMP6 type %d code %d (not authenticated)"
- , ee->ee_type, ee->ee_code
- );
- break;
- default:
- snprintf(orname, sizeof(orname), "invalid origin %lu"
- , (unsigned long) ee->ee_origin);
- break;
- }
-
- {
- struct state *old_state = cur_state;
-
- cur_state = sender;
-
- /* note dirty trick to suppress ~ at start of format
- * if we know what state to blame.
- */
-#ifdef NAT_TRAVERSAL
- if ((packet_len == 1) && (buffer[0] = 0xff)
-#ifdef DEBUG
- && ((cur_debugging & DBG_NATT) == 0)
-#endif
- ) {
- /* don't log NAT-T keepalive related errors unless NATT debug is
- * enabled
- */
- }
- else
-#endif
- plog((sender != NULL) + "~"
- "ERROR: asynchronous network error report on %s"
- "%s"
- ", complainant %s"
- ": %s"
- " [errno %lu, origin %s"
- /* ", pad %d, info %ld" */
- /* ", data %ld" */
- "]"
- , ifp->rname
- , fromstr
- , offstr
- , strerror(ee->ee_errno)
- , (unsigned long) ee->ee_errno
- , orname
- /* , ee->ee_pad, (unsigned long)ee->ee_info */
- /* , (unsigned long)ee->ee_data */
- );
- cur_state = old_state;
- }
- }
- else
- {
- /* .cmsg_len is a kernel_size_t(!), but the value
- * certainly ought to fit in an unsigned long.
- */
- plog("unknown cmsg: level %d, type %d, len %lu"
- , cm->cmsg_level, cm->cmsg_type
- , (unsigned long) cm->cmsg_len);
- }
- }
- }
- return (pfd.revents & interest) != 0;
-}
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
-bool
-#ifdef NAT_TRAVERSAL
-_send_packet(struct state *st, const char *where, bool verbose)
-#else
-send_packet(struct state *st, const char *where)
-#endif
-{
- struct connection *c = st->st_connection;
- int port_buf;
- bool err;
-
-#ifdef NAT_TRAVERSAL
- u_int8_t ike_pkt[MAX_OUTPUT_UDP_SIZE];
- u_int8_t *ptr;
- unsigned long len;
-
- if ((c->interface->ike_float == TRUE) && (st->st_tpacket.len != 1)) {
- if ((unsigned long) st->st_tpacket.len >
- (MAX_OUTPUT_UDP_SIZE-sizeof(u_int32_t))) {
- DBG_log("send_packet(): really too big");
- return FALSE;
- }
- ptr = ike_pkt;
- /** Add Non-ESP marker **/
- memset(ike_pkt, 0, sizeof(u_int32_t));
- memcpy(ike_pkt + sizeof(u_int32_t), st->st_tpacket.ptr,
- (unsigned long)st->st_tpacket.len);
- len = (unsigned long) st->st_tpacket.len + sizeof(u_int32_t);
- }
- else {
- ptr = st->st_tpacket.ptr;
- len = (unsigned long) st->st_tpacket.len;
- }
-#endif
-
- DBG(DBG_RAW,
- {
- DBG_log("sending %lu bytes for %s through %s to %s:%u:"
- , (unsigned long) st->st_tpacket.len
- , where
- , c->interface->rname
- , ip_str(&c->spd.that.host_addr)
- , (unsigned)c->spd.that.host_port);
- DBG_dump_chunk(NULL, st->st_tpacket);
- });
-
- /* XXX: Not very clean. We manipulate the port of the ip_address to
- * have a port in the sockaddr*, but we retain the original port
- * and restore it afterwards.
- */
-
- port_buf = portof(&c->spd.that.host_addr);
- setportof(htons(c->spd.that.host_port), &c->spd.that.host_addr);
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- (void) check_msg_errqueue(c->interface, POLLOUT);
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
-#ifdef NAT_TRAVERSAL
- err = sendto(c->interface->fd
- , ptr, len, 0
- , sockaddrof(&c->spd.that.host_addr)
- , sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)len;
-#else
- err = sendto(c->interface->fd
- , st->st_tpacket.ptr, st->st_tpacket.len, 0
- , sockaddrof(&c->spd.that.host_addr)
- , sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)st->st_tpacket.len;
-#endif
-
- /* restore port */
- setportof(port_buf, &c->spd.that.host_addr);
-
- if (err)
- {
-#ifdef NAT_TRAVERSAL
- /* do not log NAT-T Keep Alive packets */
- if (!verbose)
- return FALSE;
-#endif
- log_errno((e, "sendto on %s to %s:%u failed in %s"
- , c->interface->rname
- , ip_str(&c->spd.that.host_addr)
- , (unsigned)c->spd.that.host_port
- , where));
- return FALSE;
- }
- else
- {
- return TRUE;
- }
-}
-
-static stf_status
-unexpected(struct msg_digest *md)
-{
- loglog(RC_LOG_SERIOUS, "unexpected message received in state %s"
- , enum_name(&state_names, md->st->st_state));
- return STF_IGNORE;
-}
-
-static stf_status
-informational(struct msg_digest *md UNUSED)
-{
- struct payload_digest *const n_pld = md->chain[ISAKMP_NEXT_N];
-
- /* If the Notification Payload is not null... */
- if (n_pld != NULL)
- {
- pb_stream *const n_pbs = &n_pld->pbs;
- struct isakmp_notification *const n = &n_pld->payload.notification;
- int disp_len;
- char disp_buf[200];
-
- /* Switch on Notification Type (enum) */
- switch (n->isan_type)
- {
- case R_U_THERE:
- return dpd_inI_outR(md->st, n, n_pbs);
-
- case R_U_THERE_ACK:
- return dpd_inR(md->st, n, n_pbs);
- default:
- if (pbs_left(n_pbs) >= sizeof(disp_buf)-1)
- disp_len = sizeof(disp_buf)-1;
- else
- disp_len = pbs_left(n_pbs);
- memcpy(disp_buf, n_pbs->cur, disp_len);
- disp_buf[disp_len] = '\0';
- break;
- }
- }
- return STF_IGNORE;
-}
-
-/* message digest allocation and deallocation */
-
-static struct msg_digest *md_pool = NULL;
-
-/* free_md_pool is only used to avoid leak reports */
-void
-free_md_pool(void)
-{
- for (;;)
- {
- struct msg_digest *md = md_pool;
-
- if (md == NULL)
- break;
- md_pool = md->next;
- pfree(md);
- }
-}
-
-static struct msg_digest *
-alloc_md(void)
-{
- struct msg_digest *md = md_pool;
-
- /* convenient initializer:
- * - all pointers NULL
- * - .note = NOTHING_WRONG
- * - .encrypted = FALSE
- */
- static const struct msg_digest blank_md;
-
- if (md == NULL)
- md = alloc_thing(struct msg_digest, "msg_digest");
- else
- md_pool = md->next;
-
- *md = blank_md;
- md->digest_roof = md->digest;
-
- /* note: although there may be multiple msg_digests at once
- * (due to suspended state transitions), there is a single
- * global reply_buffer. It will need to be saved and restored.
- */
- init_pbs(&md->reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
- return md;
-}
-
-void
-release_md(struct msg_digest *md)
-{
- freeanychunk(md->raw_packet);
- pfreeany(md->packet_pbs.start);
- md->packet_pbs.start = NULL;
- md->next = md_pool;
- md_pool = md;
-}
-
-/* wrapper for read_packet and process_packet
- *
- * The main purpose of this wrapper is to factor out teardown code
- * from the many return points in process_packet. This amounts to
- * releasing the msg_digest and resetting global variables.
- *
- * When processing of a packet is suspended (STF_SUSPEND),
- * process_packet sets md to NULL to prevent the msg_digest being freed.
- * Someone else must ensure that msg_digest is freed eventually.
- *
- * read_packet is broken out to minimize the lifetime of the
- * enormous input packet buffer, an auto.
- */
-void
-comm_handle(const struct iface *ifp)
-{
- static struct msg_digest *md;
-
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- /* Even though select(2) says that there is a message,
- * it might only be a MSG_ERRQUEUE message. At least
- * sometimes that leads to a hanging recvfrom. To avoid
- * what appears to be a kernel bug, check_msg_errqueue
- * uses poll(2) and tells us if there is anything for us
- * to read.
- *
- * This is early enough that teardown isn't required:
- * just return on failure.
- */
- if (!check_msg_errqueue(ifp, POLLIN))
- return; /* no normal message to read */
-#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
-
- md = alloc_md();
- md->iface = ifp;
-
- if (read_packet(md))
- process_packet(&md);
-
- if (md != NULL)
- release_md(md);
-
- cur_state = NULL;
- reset_cur_connection();
- cur_from = NULL;
-}
-
-/* read the message.
- * Since we don't know its size, we read it into
- * an overly large buffer and then copy it to a
- * new, properly sized buffer.
- */
-static bool
-read_packet(struct msg_digest *md)
-{
- const struct iface *ifp = md->iface;
- int packet_len;
- u_int8_t *buffer;
- u_int8_t *buffer_nat;
- union
- {
- struct sockaddr sa;
- struct sockaddr_in sa_in4;
- struct sockaddr_in6 sa_in6;
- } from;
- int from_len = sizeof(from);
- err_t from_ugh = NULL;
- static const char undisclosed[] = "unknown source";
-
- happy(anyaddr(addrtypeof(&ifp->addr), &md->sender));
- zero(&from.sa);
- ioctl(ifp->fd, FIONREAD, &packet_len);
- buffer = alloc_bytes(packet_len, "buffer read packet");
- packet_len = recvfrom(ifp->fd, buffer, packet_len, 0
- , &from.sa, &from_len);
-
- /* First: digest the from address.
- * We presume that nothing here disturbs errno.
- */
- if (packet_len == -1
- && from_len == sizeof(from)
- && all_zero((const void *)&from.sa, sizeof(from)))
- {
- /* "from" is untouched -- not set by recvfrom */
- from_ugh = undisclosed;
- }
- else if (from_len
- < (int) (offsetof(struct sockaddr, sa_family) + sizeof(from.sa.sa_family)))
- {
- from_ugh = "truncated";
- }
- else
- {
- const struct af_info *afi = aftoinfo(from.sa.sa_family);
-
- if (afi == NULL)
- {
- from_ugh = "unexpected Address Family";
- }
- else if (from_len != (int)afi->sa_sz)
- {
- from_ugh = "wrong length";
- }
- else
- {
- switch (from.sa.sa_family)
- {
- case AF_INET:
- from_ugh = initaddr((void *) &from.sa_in4.sin_addr
- , sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender);
- md->sender_port = ntohs(from.sa_in4.sin_port);
- break;
- case AF_INET6:
- from_ugh = initaddr((void *) &from.sa_in6.sin6_addr
- , sizeof(from.sa_in6.sin6_addr), AF_INET6, &md->sender);
- md->sender_port = ntohs(from.sa_in6.sin6_port);
- break;
- }
- }
- }
-
- /* now we report any actual I/O error */
- if (packet_len == -1)
- {
- if (from_ugh == undisclosed
- && errno == ECONNREFUSED)
- {
- /* Tone down scary message for vague event:
- * We get "connection refused" in response to some
- * datagram we sent, but we cannot tell which one.
- */
- plog("some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)");
- }
- else if (from_ugh != NULL)
- {
- log_errno((e, "recvfrom on %s failed; Pluto cannot decode source sockaddr in rejection: %s"
- , ifp->rname, from_ugh));
- }
- else
- {
- log_errno((e, "recvfrom on %s from %s:%u failed"
- , ifp->rname
- , ip_str(&md->sender), (unsigned)md->sender_port));
- }
-
- return FALSE;
- }
- else if (from_ugh != NULL)
- {
- plog("recvfrom on %s returned misformed source sockaddr: %s"
- , ifp->rname, from_ugh);
- return FALSE;
- }
- cur_from = &md->sender;
- cur_from_port = md->sender_port;
-
-#ifdef NAT_TRAVERSAL
- if (ifp->ike_float == TRUE) {
- u_int32_t non_esp;
- if (packet_len < (int)sizeof(u_int32_t)) {
- plog("recvfrom %s:%u too small packet (%d)"
- , ip_str(cur_from), (unsigned) cur_from_port, packet_len);
- return FALSE;
- }
- memcpy(&non_esp, buffer, sizeof(u_int32_t));
- if (non_esp != 0) {
- plog("recvfrom %s:%u has no Non-ESP marker"
- , ip_str(cur_from), (unsigned) cur_from_port);
- return FALSE;
- }
- packet_len -= sizeof(u_int32_t);
- buffer_nat = alloc_bytes(packet_len, "buffer read packet");
- memcpy(buffer_nat, buffer + sizeof(u_int32_t), packet_len);
- pfree(buffer);
- buffer = buffer_nat;
- }
-#endif
-
- /* Clone actual message contents
- * and set up md->packet_pbs to describe it.
- */
- init_pbs(&md->packet_pbs, buffer, packet_len, "packet");
-
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL,
- {
- DBG_log(BLANK_FORMAT);
- DBG_log("*received %d bytes from %s:%u on %s"
- , (int) pbs_room(&md->packet_pbs)
- , ip_str(cur_from), (unsigned) cur_from_port
- , ifp->rname);
- });
-
- DBG(DBG_RAW,
- DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)));
-
-#ifdef NAT_TRAVERSAL
- if ((pbs_room(&md->packet_pbs)==1) && (md->packet_pbs.start[0]==0xff)) {
- /**
- * NAT-T Keep-alive packets should be discared by kernel ESPinUDP
- * layer. But boggus keep-alive packets (sent with a non-esp marker)
- * can reach this point. Complain and discard them.
- */
- DBG(DBG_NATT,
- DBG_log("NAT-T keep-alive (boggus ?) should not reach this point. "
- "Ignored. Sender: %s:%u", ip_str(cur_from),
- (unsigned) cur_from_port);
- );
- return FALSE;
- }
-#endif
-
- return TRUE;
-}
-
-/* process an input packet, possibly generating a reply.
- *
- * If all goes well, this routine eventually calls a state-specific
- * transition function.
- */
-static void
-process_packet(struct msg_digest **mdp)
-{
- struct msg_digest *md = *mdp;
- const struct state_microcode *smc;
- bool new_iv_set = FALSE;
- bool restore_iv = FALSE;
- u_char new_iv[MAX_DIGEST_LEN];
- u_int new_iv_len = 0;
-
- struct state *st = NULL;
- enum state_kind from_state = STATE_UNDEFINED; /* state we started in */
-
-#define SEND_NOTIFICATION(t) { \
- if (st) send_notification_from_state(st, from_state, t); \
- else send_notification_from_md(md, t); }
-
- if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs, &md->message_pbs))
- {
- /* Identify specific failures:
- * - bad ISAKMP major/minor version numbers
- */
- if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size)
- {
- struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur;
- if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION)
- {
- SEND_NOTIFICATION(INVALID_MAJOR_VERSION);
- return;
- }
- else if ((hdr->isa_version & ISA_MIN_MASK) != ISAKMP_MINOR_VERSION)
- {
- SEND_NOTIFICATION(INVALID_MINOR_VERSION);
- return;
- }
- }
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- if (md->packet_pbs.roof != md->message_pbs.roof)
- {
- plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
- , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
-#ifdef CISCO_QUIRKS
- if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
- plog("Cisco VPN client appends 16 surplus NULL bytes");
- else
-#endif
- return;
- }
-
- switch (md->hdr.isa_xchg)
- {
-#ifdef NOTYET
- case ISAKMP_XCHG_NONE:
- case ISAKMP_XCHG_BASE:
-#endif
-
- case ISAKMP_XCHG_IDPROT: /* part of a Main Mode exchange */
- if (md->hdr.isa_msgid != MAINMODE_MSGID)
- {
- plog("Message ID was 0x%08lx but should be zero in Main Mode",
- (unsigned long) md->hdr.isa_msgid);
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
-
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("Initiator Cookie must not be zero in Main Mode message");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
-
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- /* initial message from initiator
- * ??? what if this is a duplicate of another message?
- */
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- plog("initial Main Mode message is invalid:"
- " its Encrypted Flag is on");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
- }
-
- /* don't build a state until the message looks tasty */
- from_state = STATE_MAIN_R0;
- }
- else
- {
- /* not an initial message */
-
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
-
- if (st == NULL)
- {
- /* perhaps this is a first message from the responder
- * and contains a responder cookie that we've not yet seen.
- */
- st = find_state(md->hdr.isa_icookie, zero_cookie
- , &md->sender, md->hdr.isa_msgid);
-
- if (st == NULL)
- {
- plog("Main Mode message is part of an unknown exchange");
- /* XXX Could send notification back */
- return;
- }
- }
- set_cur_state(st);
- from_state = st->st_state;
- }
- break;
-
-#ifdef NOTYET
- case ISAKMP_XCHG_AO:
- case ISAKMP_XCHG_AGGR:
-#endif
-
- case ISAKMP_XCHG_INFO: /* an informational exchange */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, MAINMODE_MSGID);
-
- if (st != NULL)
- set_cur_state(st);
-
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- if (st == NULL)
- {
- plog("Informational Exchange is for an unknown (expired?) SA");
- /* XXX Could send notification back */
- return;
- }
-
- if (!IS_ISAKMP_ENCRYPTED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "encrypted Informational Exchange message is invalid"
- " because no key is known");
- /* XXX Could send notification back */
- return;
- }
-
- if (md->hdr.isa_msgid == MAINMODE_MSGID)
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
- " it has a Message ID of 0");
- /* XXX Could send notification back */
- return;
- }
-
- if (!reserve_msgid(st, md->hdr.isa_msgid))
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
- " it has a previously used Message ID (0x%08lx)"
- , (unsigned long)md->hdr.isa_msgid);
- /* XXX Could send notification back */
- return;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- memcpy(st->st_ph1_iv, st->st_new_iv, st->st_new_iv_len);
- st->st_ph1_iv_len = st->st_new_iv_len;
-
- /* backup new_iv */
- new_iv_len = st->st_new_iv_len;
- passert(new_iv_len <= MAX_DIGEST_LEN)
- memcpy(new_iv, st->st_new_iv, new_iv_len);
- restore_iv = TRUE;
- }
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
-
- from_state = STATE_INFO_PROTECTED;
- }
- else
- {
- if (st != NULL && IS_ISAKMP_ENCRYPTED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message"
- " must be encrypted");
- /* XXX Could send notification back */
- return;
- }
- from_state = STATE_INFO;
- }
- break;
-
- case ISAKMP_XCHG_QUICK: /* part of a Quick Mode exchange */
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("Quick Mode message is invalid because"
- " it has an Initiator Cookie of 0");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
-
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- plog("Quick Mode message is invalid because"
- " it has a Responder Cookie of 0");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
-
- if (md->hdr.isa_msgid == MAINMODE_MSGID)
- {
- plog("Quick Mode message is invalid because"
- " it has a Message ID of 0");
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
-
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
-
- if (st == NULL)
- {
- /* No appropriate Quick Mode state.
- * See if we have a Main Mode state.
- * ??? what if this is a duplicate of another message?
- */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, MAINMODE_MSGID);
-
- if (st == NULL)
- {
- plog("Quick Mode message is for a non-existent (expired?)"
- " ISAKMP SA");
- /* XXX Could send notification back */
- return;
- }
-
- set_cur_state(st);
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "Quick Mode message is unacceptable because"
- " it is for an incomplete ISAKMP SA");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
- return;
- }
-
- /* only accept this new Quick Mode exchange if it has a unique message ID */
- if (!reserve_msgid(st, md->hdr.isa_msgid))
- {
- loglog(RC_LOG_SERIOUS, "Quick Mode I1 message is unacceptable because"
- " it uses a previously used Message ID 0x%08lx"
- " (perhaps this is a duplicated packet)"
- , (unsigned long) md->hdr.isa_msgid);
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
-
- /* Quick Mode Initial IV */
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
-
- from_state = STATE_QUICK_R0;
- }
- else
- {
- set_cur_state(st);
- from_state = st->st_state;
- }
-
- break;
-
- case ISAKMP_XCHG_MODE_CFG:
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("ModeCfg message is invalid because"
- " it has an Initiator Cookie of 0");
- /* XXX Could send notification back */
- return;
- }
-
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- plog("ModeCfg message is invalid because"
- " it has a Responder Cookie of 0");
- /* XXX Could send notification back */
- return;
- }
-
- if (md->hdr.isa_msgid == 0)
- {
- plog("ModeCfg message is invalid because"
- " it has a Message ID of 0");
- /* XXX Could send notification back */
- return;
- }
-
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
-
- if (st == NULL)
- {
- bool has_xauth_policy;
-
- /* No appropriate ModeCfg state.
- * See if we have a Main Mode state.
- * ??? what if this is a duplicate of another message?
- */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, 0);
-
- if (st == NULL)
- {
- plog("ModeCfg message is for a non-existent (expired?)"
- " ISAKMP SA");
- /* XXX Could send notification back */
- return;
- }
-
- set_cur_state(st);
-
- /* the XAUTH_STATUS message might have a new msgid */
- if (st->st_state == STATE_XAUTH_I1)
- {
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
- from_state = st->st_state;
- break;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
- " it is for an incomplete ISAKMP SA (state=%s)"
- , enum_name(&state_names, st->st_state));
- /* XXX Could send notification back */
- return;
- }
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
-
- /*
- * okay, now we have to figure out if we are receiving a bogus
- * new message in an oustanding XAUTH server conversation
- * (i.e. a reply to our challenge)
- * (this occurs with some broken other implementations).
- *
- * or if receiving for the first time, an XAUTH challenge.
- *
- * or if we are getting a MODECFG request.
- *
- * we distinguish these states because we can not both be an
- * XAUTH server and client, and our policy tells us which
- * one we are.
- *
- * to complicate further, it is normal to start a new msgid
- * when going from one state to another, or when restarting
- * the challenge.
- *
- */
-
- has_xauth_policy = (st->st_connection->policy
- & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
- != LEMPTY;
-
- if (has_xauth_policy && !st->st_xauth.started
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_XAUTH_I0;
- }
- else if (st->st_connection->spd.that.modecfg
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_MODE_CFG_R0;
- }
- else if (st->st_connection->spd.this.modecfg
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_MODE_CFG_I0;
- }
- else
- {
- /* XXX check if we are being a mode config server here */
- plog("received ModeCfg message when in state %s, and we aren't mode config client"
- , enum_name(&state_names, st->st_state));
- return;
- }
- }
- else
- {
- set_cur_state(st);
- from_state = st->st_state;
- }
- break;
-
-#ifdef NOTYET
- case ISAKMP_XCHG_NGRP:
- case ISAKMP_XCHG_ACK_INFO:
-#endif
-
- default:
- plog("unsupported exchange type %s in message"
- , enum_show(&exchange_names, md->hdr.isa_xchg));
- SEND_NOTIFICATION(UNSUPPORTED_EXCHANGE_TYPE);
- return;
- }
-
- /* We have found a from_state, and perhaps a state object.
- * If we need to build a new state object,
- * we wait until the packet has been sanity checked.
- */
-
- /* We don't support the Commit Flag. It is such a bad feature.
- * It isn't protected -- neither encrypted nor authenticated.
- * A man in the middle turns it on, leading to DoS.
- * We just ignore it, with a warning.
- * By placing the check here, we could easily add a policy bit
- * to a connection to suppress the warning. This might be useful
- * because the Commit Flag is expected from some peers.
- */
- if (md->hdr.isa_flags & ISAKMP_FLAG_COMMIT)
- {
- plog("IKE message has the Commit Flag set but Pluto doesn't implement this feature; ignoring flag");
- }
-
- /* Set smc to describe this state's properties.
- * Look up the appropriate microcode based on state and
- * possibly Oakley Auth type.
- */
- passert(STATE_IKE_FLOOR <= from_state && from_state <= STATE_IKE_ROOF);
- smc = ike_microcode_index[from_state - STATE_IKE_FLOOR];
-
- if (st != NULL)
- {
- u_int16_t auth;
-
- switch (st->st_oakley.auth)
- {
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- auth = OAKLEY_PRESHARED_KEY;
- break;
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- auth = OAKLEY_RSA_SIG;
- break;
- default:
- auth = st->st_oakley.auth;
- }
-
- while (!LHAS(smc->flags, auth))
- {
- smc++;
- passert(smc->state == from_state);
- }
- }
-
- /* Ignore a packet if the state has a suspended state transition
- * Probably a duplicated packet but the original packet is not yet
- * recorded in st->st_rpacket, so duplicate checking won't catch.
- * ??? Should the packet be recorded earlier to improve diagnosis?
- */
- if (st != NULL && st->st_suspended_md != NULL)
- {
- loglog(RC_LOG, "discarding packet received during DNS lookup in %s"
- , enum_name(&state_names, st->st_state));
- return;
- }
-
- /* Detect and handle duplicated packets.
- * This won't work for the initial packet of an exchange
- * because we won't have a state object to remember it.
- * If we are in a non-receiving state (terminal), and the preceding
- * state did transmit, then the duplicate may indicate that that
- * transmission wasn't received -- retransmit it.
- * Otherwise, just discard it.
- * ??? Notification packets are like exchanges -- I hope that
- * they are idempotent!
- */
- if (st != NULL
- && st->st_rpacket.ptr != NULL
- && st->st_rpacket.len == pbs_room(&md->packet_pbs)
- && memcmp(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len) == 0)
- {
- if (smc->flags & SMF_RETRANSMIT_ON_DUPLICATE)
- {
- if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
- {
- st->st_retransmit++;
- loglog(RC_RETRANSMISSION
- , "retransmitting in response to duplicate packet; already %s"
- , enum_name(&state_names, st->st_state));
- send_packet(st, "retransmit in response to duplicate");
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "discarding duplicate packet -- exhausted retransmission; already %s"
- , enum_name(&state_names, st->st_state));
- }
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "discarding duplicate packet; already %s"
- , enum_name(&state_names, st->st_state));
- }
- return;
- }
-
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- DBG(DBG_CRYPT, DBG_log("received encrypted packet from %s:%u"
- , ip_str(&md->sender), (unsigned)md->sender_port));
-
- if (st == NULL)
- {
- plog("discarding encrypted message for an unknown ISAKMP SA");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
- return;
- }
- if (st->st_skeyid_e.ptr == (u_char *) NULL)
- {
- loglog(RC_LOG_SERIOUS, "discarding encrypted message"
- " because we haven't yet negotiated keying materiel");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
- }
-
- /* Mark as encrypted */
- md->encrypted = TRUE;
-
- DBG(DBG_CRYPT, DBG_log("decrypting %u bytes using algorithm %s"
- , (unsigned) pbs_left(&md->message_pbs)
- , enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
-
- /* do the specified decryption
- *
- * IV is from st->st_iv or (if new_iv_set) st->st_new_iv.
- * The new IV is placed in st->st_new_iv
- *
- * See RFC 2409 "IKE" Appendix B
- *
- * XXX The IV should only be updated really if the packet
- * is successfully processed.
- * We should keep this value, check for a success return
- * value from the parsing routines and then replace.
- *
- * Each post phase 1 exchange generates IVs from
- * the last phase 1 block, not the last block sent.
- */
- {
- const struct encrypt_desc *e = st->st_oakley.encrypter;
-
- if (pbs_left(&md->message_pbs) % e->enc_blocksize != 0)
- {
- loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- /* XXX Detect weak keys */
-
- /* grab a copy of raw packet (for duplicate packet detection) */
- clonetochunk(md->raw_packet, md->packet_pbs.start
- , pbs_room(&md->packet_pbs), "raw packet");
-
- /* Decrypt everything after header */
- if (!new_iv_set)
- {
- /* use old IV */
- passert(st->st_iv_len <= sizeof(st->st_new_iv));
- st->st_new_iv_len = st->st_iv_len;
- memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
- }
- crypto_cbc_encrypt(e, FALSE, md->message_pbs.cur,
- pbs_left(&md->message_pbs) , st);
- if (restore_iv)
- {
- memcpy(st->st_new_iv, new_iv, new_iv_len);
- st->st_new_iv_len = new_iv_len;
- }
- }
-
- DBG_cond_dump(DBG_CRYPT, "decrypted:\n", md->message_pbs.cur
- , md->message_pbs.roof - md->message_pbs.cur);
-
- DBG_cond_dump(DBG_CRYPT, "next IV:"
- , st->st_new_iv, st->st_new_iv_len);
- }
- else
- {
- /* packet was not encryped -- should it have been? */
-
- if (smc->flags & SMF_INPUT_ENCRYPTED)
- {
- loglog(RC_LOG_SERIOUS, "packet rejected: should have been encrypted");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
- }
- }
-
- /* Digest the message.
- * Padding must be removed to make hashing work.
- * Padding comes from encryption (so this code must be after decryption).
- * Padding rules are described before the definition of
- * struct isakmp_hdr in packet.h.
- */
- {
- struct payload_digest *pd = md->digest;
- int np = md->hdr.isa_np;
- lset_t needed = smc->req_payloads;
- const char *excuse
- = LIN(SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT, smc->flags)
- ? "probable authentication failure (mismatch of preshared secrets?): "
- : "";
-
- while (np != ISAKMP_NEXT_NONE)
- {
- struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL;
-
- if (pd == &md->digest[PAYLIMIT])
- {
- loglog(RC_LOG_SERIOUS, "more than %d payloads in message; ignored", PAYLIMIT);
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
-#ifdef NAT_TRAVERSAL
- switch (np)
- {
- case ISAKMP_NEXT_NATD_RFC:
- case ISAKMP_NEXT_NATOA_RFC:
- if ((!st) || (!(st->nat_traversal & NAT_T_WITH_RFC_VALUES))) {
- /*
- * don't accept NAT-D/NAT-OA reloc directly in message, unless
- * we're using NAT-T RFC
- */
- sd = NULL;
- }
- break;
- }
-#endif
-
- if (sd == NULL)
- {
- /* payload type is out of range or requires special handling */
- switch (np)
- {
- case ISAKMP_NEXT_ID:
- sd = IS_PHASE1(from_state)
- ? &isakmp_identification_desc : &isakmp_ipsec_identification_desc;
- break;
-#ifdef NAT_TRAVERSAL
- case ISAKMP_NEXT_NATD_DRAFTS:
- np = ISAKMP_NEXT_NATD_RFC; /* NAT-D relocated */
- sd = payload_descs[np];
- break;
- case ISAKMP_NEXT_NATOA_DRAFTS:
- np = ISAKMP_NEXT_NATOA_RFC; /* NAT-OA relocated */
- sd = payload_descs[np];
- break;
-#endif
- default:
- loglog(RC_LOG_SERIOUS, "%smessage ignored because it contains an unknown or"
- " unexpected payload type (%s) at the outermost level"
- , excuse, enum_show(&payload_names, np));
- SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
- return;
- }
- }
-
- {
- lset_t s = LELEM(np);
-
- if (LDISJOINT(s
- , needed | smc->opt_payloads| LELEM(ISAKMP_NEXT_N) | LELEM(ISAKMP_NEXT_D)))
- {
- loglog(RC_LOG_SERIOUS, "%smessage ignored because it "
- "contains an unexpected payload type (%s)"
- , excuse, enum_show(&payload_names, np));
- SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
- return;
- }
- needed &= ~s;
- }
-
- if (!in_struct(&pd->payload, sd, &md->message_pbs, &pd->pbs))
- {
- loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse);
- if (md->hdr.isa_xchg != ISAKMP_XCHG_INFO)
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- /* place this payload at the end of the chain for this type */
- {
- struct payload_digest **p;
-
- for (p = &md->chain[np]; *p != NULL; p = &(*p)->next)
- ;
- *p = pd;
- pd->next = NULL;
- }
-
- np = pd->payload.generic.isag_np;
- pd++;
-
- /* since we've digested one payload happily, it is probably
- * the case that any decryption worked. So we will not suggest
- * encryption failure as an excuse for subsequent payload
- * problems.
- */
- excuse = "";
- }
-
- md->digest_roof = pd;
-
- DBG(DBG_PARSING,
- if (pbs_left(&md->message_pbs) != 0)
- DBG_log("removing %d bytes of padding", (int) pbs_left(&md->message_pbs)));
-
- md->message_pbs.roof = md->message_pbs.cur;
-
- /* check that all mandatory payloads appeared */
-
- if (needed != 0)
- {
- loglog(RC_LOG_SERIOUS, "message for %s is missing payloads %s"
- , enum_show(&state_names, from_state)
- , bitnamesof(payload_name, needed));
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
- }
-
- /* more sanity checking: enforce most ordering constraints */
-
- if (IS_PHASE1(from_state))
- {
- /* rfc2409: The Internet Key Exchange (IKE), 5 Exchanges:
- * "The SA payload MUST precede all other payloads in a phase 1 exchange."
- */
- if (md->chain[ISAKMP_NEXT_SA] != NULL
- && md->hdr.isa_np != ISAKMP_NEXT_SA)
- {
- loglog(RC_LOG_SERIOUS, "malformed Phase 1 message: does not start with an SA payload");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
- }
- else if (IS_QUICK(from_state))
- {
- /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode
- *
- * "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
- * header and a SA payload MUST immediately follow the HASH."
- * [NOTE: there may be more than one SA payload, so this is not
- * totally reasonable. Probably all SAs should be so constrained.]
- *
- * "If ISAKMP is acting as a client negotiator on behalf of another
- * party, the identities of the parties MUST be passed as IDci and
- * then IDcr."
- *
- * "With the exception of the HASH, SA, and the optional ID payloads,
- * there are no payload ordering restrictions on Quick Mode."
- */
-
- if (md->hdr.isa_np != ISAKMP_NEXT_HASH)
- {
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: does not start with a HASH payload");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- {
- struct payload_digest *p;
- int i;
-
- for (p = md->chain[ISAKMP_NEXT_SA], i = 1; p != NULL
- ; p = p->next, i++)
- {
- if (p != &md->digest[i])
- {
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: SA payload is in wrong position");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
- }
- }
-
- /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode:
- * "If ISAKMP is acting as a client negotiator on behalf of another
- * party, the identities of the parties MUST be passed as IDci and
- * then IDcr."
- */
- {
- struct payload_digest *id = md->chain[ISAKMP_NEXT_ID];
-
- if (id != NULL)
- {
- if (id->next == NULL || id->next->next != NULL)
- {
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
- " if any ID payload is present,"
- " there must be exactly two");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
- if (id+1 != id->next)
- {
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
- " the ID payloads are not adjacent");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
- }
- }
- }
-
- /* Ignore payloads that we don't handle:
- * Delete, Notification, VendorID
- */
- /* XXX Handle deletions */
- /* XXX Handle Notifications */
- /* XXX Handle VID payloads */
- {
- struct payload_digest *p;
-
- for (p = md->chain[ISAKMP_NEXT_N]; p != NULL; p = p->next)
- {
- if (p->payload.notification.isan_type != R_U_THERE
- && p->payload.notification.isan_type != R_U_THERE_ACK)
- {
- loglog(RC_LOG_SERIOUS, "ignoring informational payload, type %s"
- , enum_show(&notification_names, p->payload.notification.isan_type));
- }
- DBG_cond_dump(DBG_PARSING, "info:", p->pbs.cur, pbs_left(&p->pbs));
- }
-
- for (p = md->chain[ISAKMP_NEXT_D]; p != NULL; p = p->next)
- {
- accept_delete(st, md, p);
- DBG_cond_dump(DBG_PARSING, "del:", p->pbs.cur, pbs_left(&p->pbs));
- }
-
- for (p = md->chain[ISAKMP_NEXT_VID]; p != NULL; p = p->next)
- {
- handle_vendorid(md, p->pbs.cur, pbs_left(&p->pbs));
- }
- }
- md->from_state = from_state;
- md->smc = smc;
- md->st = st;
-
- /* possibly fill in hdr */
- if (smc->first_out_payload != ISAKMP_NEXT_NONE)
- echo_hdr(md, (smc->flags & SMF_OUTPUT_ENCRYPTED) != 0
- , smc->first_out_payload);
-
- complete_state_transition(mdp, smc->processor(md));
-}
-
-/* complete job started by the state-specific state transition function */
-
-void
-complete_state_transition(struct msg_digest **mdp, stf_status result)
-{
- bool has_xauth_policy;
- bool is_xauth_server;
- struct msg_digest *md = *mdp;
- const struct state_microcode *smc = md->smc;
- enum state_kind from_state = md->from_state;
- struct state *st;
-
- cur_state = st = md->st; /* might have changed */
-
- /* If state has DPD support, import it */
- if (st && md->dpd)
- st->st_dpd = TRUE;
-
- switch (result)
- {
- case STF_IGNORE:
- break;
-
- case STF_SUSPEND:
- /* the stf didn't complete its job: don't relase md */
- *mdp = NULL;
- break;
-
- case STF_OK:
- /* advance the state */
- st->st_state = smc->next_state;
-
- /* Delete previous retransmission event.
- * New event will be scheduled below.
- */
- delete_event(st);
-
- /* replace previous receive packet with latest */
-
- pfreeany(st->st_rpacket.ptr);
-
- if (md->encrypted)
- {
- /* if encrypted, duplication already done */
- st->st_rpacket = md->raw_packet;
- md->raw_packet.ptr = NULL;
- }
- else
- {
- clonetochunk(st->st_rpacket
- , md->packet_pbs.start
- , pbs_room(&md->packet_pbs), "raw packet");
- }
-
- /* free previous transmit packet */
- freeanychunk(st->st_tpacket);
-
- /* if requested, send the new reply packet */
- if (smc->flags & SMF_REPLY)
- {
- close_output_pbs(&md->reply); /* good form, but actually a no-op */
-
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "reply packet");
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, md->st);
-#endif
-
- /* actually send the packet
- * Note: this is a great place to implement "impairments"
- * for testing purposes. Suppress or duplicate the
- * send_packet call depending on st->st_state.
- */
- send_packet(st, enum_name(&state_names, from_state));
- }
-
- /* Schedule for whatever timeout is specified */
- {
- time_t delay;
- enum event_type kind = smc->timeout_event;
- bool agreed_time = FALSE;
- struct connection *c = st->st_connection;
-
- switch (kind)
- {
- case EVENT_RETRANSMIT: /* Retransmit packet */
- delay = EVENT_RETRANSMIT_DELAY_0;
- break;
-
- case EVENT_SA_REPLACE: /* SA replacement event */
- if (IS_PHASE1(st->st_state))
- {
- /* Note: we will defer to the "negotiated" (dictated)
- * lifetime if we are POLICY_DONT_REKEY.
- * This allows the other side to dictate
- * a time we would not otherwise accept
- * but it prevents us from having to initiate
- * rekeying. The negative consequences seem
- * minor.
- */
- delay = c->sa_ike_life_seconds;
- if ((c->policy & POLICY_DONT_REKEY)
- || delay >= st->st_oakley.life_seconds)
- {
- agreed_time = TRUE;
- delay = st->st_oakley.life_seconds;
- }
- }
- else
- {
- /* Delay is min of up to four things:
- * each can limit the lifetime.
- */
- delay = c->sa_ipsec_life_seconds;
- if (st->st_ah.present
- && delay >= st->st_ah.attrs.life_seconds)
- {
- agreed_time = TRUE;
- delay = st->st_ah.attrs.life_seconds;
- }
- if (st->st_esp.present
- && delay >= st->st_esp.attrs.life_seconds)
- {
- agreed_time = TRUE;
- delay = st->st_esp.attrs.life_seconds;
- }
- if (st->st_ipcomp.present
- && delay >= st->st_ipcomp.attrs.life_seconds)
- {
- agreed_time = TRUE;
- delay = st->st_ipcomp.attrs.life_seconds;
- }
- }
-
- /* By default, we plan to rekey.
- *
- * If there isn't enough time to rekey, plan to
- * expire.
- *
- * If we are --dontrekey, a lot more rules apply.
- * If we are the Initiator, use REPLACE_IF_USED.
- * If we are the Responder, and the dictated time
- * was unacceptable (too large), plan to REPLACE
- * (the only way to ratchet down the time).
- * If we are the Responder, and the dictated time
- * is acceptable, plan to EXPIRE.
- *
- * Important policy lies buried here.
- * For example, we favour the initiator over the
- * responder by making the initiator start rekeying
- * sooner. Also, fuzz is only added to the
- * initiator's margin.
- *
- * Note: for ISAKMP SA, we let the negotiated
- * time stand (implemented by earlier logic).
- */
- if (agreed_time
- && (c->policy & POLICY_DONT_REKEY))
- {
- kind = (smc->flags & SMF_INITIATOR)
- ? EVENT_SA_REPLACE_IF_USED
- : EVENT_SA_EXPIRE;
- }
- if (kind != EVENT_SA_EXPIRE)
- {
- unsigned long marg = c->sa_rekey_margin;
-
- if (smc->flags & SMF_INITIATOR)
- marg += marg
- * c->sa_rekey_fuzz / 100.E0
- * (rand() / (RAND_MAX + 1.E0));
- else
- marg /= 2;
-
- if ((unsigned long)delay > marg)
- {
- delay -= marg;
- st->st_margin = marg;
- }
- else
- {
- kind = EVENT_SA_EXPIRE;
- }
- }
- break;
-
- case EVENT_NULL: /* non-event */
- case EVENT_REINIT_SECRET: /* Refresh cookie secret */
- default:
- bad_case(kind);
- }
- event_schedule(kind, delay, st);
- }
-
- /* tell whack and log of progress */
- {
- const char *story = state_story[st->st_state - STATE_MAIN_R0];
- enum rc_type w = RC_NEW_STATE + st->st_state;
- char sadetails[128];
-
- sadetails[0]='\0';
-
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- char *b = sadetails;
- const char *ini = " {";
- const char *fin = "";
-
- /* -1 is to leave space for "fin" */
-
- if (st->st_esp.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sESP=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_esp.attrs.spi)
- , ntohl(st->st_esp.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_ah.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sAH=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_ah.attrs.spi)
- , ntohl(st->st_ah.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_ipcomp.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sIPCOMP=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_ipcomp.attrs.spi)
- , ntohl(st->st_ipcomp.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
-#ifdef NAT_TRAVERSAL
- if (st->nat_traversal)
- {
- char oa[ADDRTOT_BUF];
- addrtot(&st->nat_oa, 0, oa, sizeof(oa));
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sNATOA=%s"
- , ini, oa);
- ini = " ";
- fin = "}";
- }
-#endif
-
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_dpd)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sDPD"
- , ini);
- ini = " ";
- fin = "}";
- }
-
- strcat(b, fin);
- }
-
- if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- /* log our success */
- plog("%s%s", story, sadetails);
- w = RC_SUCCESS;
- }
-
- /* tell whack our progress */
- whack_log(w
- , "%s: %s%s"
- , enum_name(&state_names, st->st_state)
- , story, sadetails);
- }
-
- has_xauth_policy = (st->st_connection->policy
- & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
- != LEMPTY;
- is_xauth_server = (st->st_connection->policy
- & POLICY_XAUTH_SERVER)
- != LEMPTY;
-
- /* Should we start XAUTH as a server */
- if (has_xauth_policy && is_xauth_server
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_xauth.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("starting XAUTH server")
- )
- xauth_send_request(st);
- break;
- }
-
- /* Wait for XAUTH request from server */
- if (has_xauth_policy && !is_xauth_server
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_xauth.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("waiting for XAUTH request from server")
- )
- break;
- }
-
- /* Should we start ModeConfig as a client? */
- if (st->st_connection->spd.this.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !(st->st_connection->policy & POLICY_MODECFG_PUSH)
- && !st->st_modecfg.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("starting ModeCfg client in pull mode")
- )
- modecfg_send_request(st);
- break;
- }
-
- /* Should we start ModeConfig as a server? */
- if (st->st_connection->spd.that.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_modecfg.started
- && (st->st_connection->policy & POLICY_MODECFG_PUSH))
- {
- DBG(DBG_CONTROL,
- DBG_log("starting ModeCfg server in push mode")
- )
- modecfg_send_set(st);
- break;
- }
-
- /* Wait for ModeConfig set from server */
- if (st->st_connection->spd.this.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_modecfg.vars_set)
- {
- DBG(DBG_CONTROL,
- DBG_log("waiting for ModeCfg set from server")
- )
- break;
- }
-
- if (smc->flags & SMF_RELEASE_PENDING_P2)
- {
- /* Initiate any Quick Mode negotiations that
- * were waiting to piggyback on this Keying Channel.
- *
- * ??? there is a potential race condition
- * if we are the responder: the initial Phase 2
- * message might outrun the final Phase 1 message.
- * I think that retransmission will recover.
- */
- unpend(st);
- }
-
- if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
- release_whack(st);
- break;
-
- case STF_INTERNAL_ERROR:
- whack_log(RC_INTERNALERR + md->note
- , "%s: internal error"
- , enum_name(&state_names, st->st_state));
-
- DBG(DBG_CONTROL,
- DBG_log("state transition function for %s had internal error"
- , enum_name(&state_names, from_state)));
- break;
-
- default: /* a shortcut to STF_FAIL, setting md->note */
- passert(result > STF_FAIL);
- md->note = result - STF_FAIL;
- result = STF_FAIL;
- /* FALL THROUGH ... */
- case STF_FAIL:
- /* As it is, we act as if this message never happened:
- * whatever retrying was in place, remains in place.
- */
- whack_log(RC_NOTIFICATION + md->note
- , "%s: %s"
- , enum_name(&state_names, (st == NULL)? STATE_MAIN_R0:st->st_state)
- , enum_name(&notification_names, md->note));
-
- SEND_NOTIFICATION(md->note);
-
- DBG(DBG_CONTROL,
- DBG_log("state transition function for %s failed: %s"
- , enum_name(&state_names, from_state)
- , enum_name(&notification_names, md->note)));
- break;
- }
-}
diff --git a/programs/pluto/demux.h b/programs/pluto/demux.h
deleted file mode 100644
index dc38e4cfc..000000000
--- a/programs/pluto/demux.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* demultiplex incoming IKE messages
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: demux.h,v 1.5 2007/01/11 05:44:02 as Exp $
- */
-
-#include "packet.h"
-
-struct state; /* forward declaration of tag */
-extern void init_demux(void);
-#ifdef NAT_TRAVERSAL
-#define send_packet(st,wh) _send_packet(st,wh,TRUE)
-extern bool _send_packet(struct state *st, const char *where, bool verbose);
-#else
-extern bool send_packet(struct state *st, const char *where);
-#endif
-extern void comm_handle(const struct iface *ifp);
-
-extern u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
-
-/* State transition function infrastructure
- *
- * com_handle parses a message, decides what state object it applies to,
- * and calls the appropriate state transition function (STF).
- * These declarations define the interface to these functions.
- *
- * Each STF must be able to be restarted up to any failure point:
- * a later message will cause the state to be re-entered. This
- * explains the use of the replace macro and the care in handling
- * MP_INT members of struct state.
- */
-
-struct payload_digest {
- pb_stream pbs;
- union payload payload;
- struct payload_digest *next; /* of same kind */
-};
-
-/* message digest
- * Note: raw_packet and packet_pbs are "owners" of space on heap.
- */
-
-struct msg_digest {
- struct msg_digest *next; /* for free list */
- chunk_t raw_packet; /* if encrypted, received packet before decryption */
- const struct iface *iface; /* interface on which message arrived */
- ip_address sender; /* where message came from */
- u_int16_t sender_port; /* host order */
- pb_stream packet_pbs; /* whole packet */
- pb_stream message_pbs; /* message to be processed */
- struct isakmp_hdr hdr; /* message's header */
- bool encrypted; /* was it encrypted? */
- enum state_kind from_state; /* state we started in */
- const struct state_microcode *smc; /* microcode for initial state */
- struct state *st; /* current state object */
- pb_stream reply; /* room for reply */
- pb_stream rbody; /* room for reply body (after header) */
- notification_t note; /* reason for failure */
- bool dpd; /* peer supports RFC 3706 DPD */
- bool openpgp; /* peer supports OpenPGP certificates */
-
-# define PAYLIMIT 40
- struct payload_digest
- digest[PAYLIMIT],
- *digest_roof,
- *chain[ISAKMP_NEXT_ROOF];
-#ifdef NAT_TRAVERSAL
- unsigned short nat_traversal_vid;
-#endif
-};
-
-extern void release_md(struct msg_digest *md);
-
-/* status for state-transition-function
- * Note: STF_FAIL + notification_t means fail with that notification
- */
-
-typedef enum {
- STF_IGNORE, /* don't respond */
- STF_SUSPEND, /* unfinished -- don't release resources */
- STF_OK, /* success */
- STF_INTERNAL_ERROR, /* discard everything, we failed */
- STF_FAIL /* discard everything, something failed. notification_t added. */
-} stf_status;
-
-typedef stf_status state_transition_fn(struct msg_digest *md);
-
-extern void complete_state_transition(struct msg_digest **mdp, stf_status result);
-
-extern void free_md_pool(void);
diff --git a/programs/pluto/dnskey.c b/programs/pluto/dnskey.c
deleted file mode 100644
index 9aca1938d..000000000
--- a/programs/pluto/dnskey.c
+++ /dev/null
@@ -1,1962 +0,0 @@
-/* Find public key in DNS
- * Copyright (C) 2000-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: dnskey.c,v 1.5 2005/09/08 16:26:30 as Exp $
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h> /* ??? for h_errno */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "defs.h"
-#include "log.h"
-#include "id.h"
-#include "connections.h"
-#include "keys.h" /* needs connections.h */
-#include "dnskey.h"
-#include "packet.h"
-#include "timer.h"
-
-/* somebody has to decide */
-#define MAX_TXT_RDATA ((MAX_KEY_BYTES * 8 / 6) + 40) /* somewhat arbitrary overkill */
-
-/* ADNS stuff */
-
-int adns_qfd = NULL_FD, /* file descriptor for sending queries to adns (O_NONBLOCK) */
- adns_afd = NULL_FD; /* file descriptor for receiving answers from adns */
-static pid_t adns_pid = 0;
-const char *pluto_adns_option = NULL; /* path from --pluto_adns */
-
-int adns_restart_count;
-#define ADNS_RESTART_MAX 20
-
-void
-init_adns(void)
-{
- const char *adns_path = pluto_adns_option;
-#ifndef USE_LWRES
- static const char adns_name[] = "_pluto_adns";
- const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
-#else /* USE_LWRES */
- static const char adns_name[] = "lwdnsq";
- const char *helper_bin_dir = getenv("IPSEC_EXECDIR");
-#endif /* USE_LWRES */
- char adns_path_space[4096]; /* plenty long? */
- int qfds[2];
- int afds[2];
-
- /* find a pathname to the ADNS program */
- if (adns_path == NULL)
- {
- /* pathname was not specified as an option: build it.
- * First, figure out the directory to be used.
- */
- ssize_t n;
-
- if (helper_bin_dir != NULL)
- {
- n = strlen(helper_bin_dir);
- if ((size_t)n <= sizeof(adns_path_space) - sizeof(adns_name))
- {
- strcpy(adns_path_space, helper_bin_dir);
- if (n > 0 && adns_path_space[n -1] != '/')
- adns_path_space[n++] = '/';
- }
- }
- else
- {
- /* The program will be in the same directory as Pluto,
- * so we use the sympolic link /proc/self/exe to
- * tell us of the path prefix.
- */
- n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
-
- if (n < 0)
- exit_log_errno((e
- , "readlink(\"/proc/self/exe\") failed in init_adns()"));
-
- }
-
- if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
- exit_log("path to %s is too long", adns_name);
-
- while (n > 0 && adns_path_space[n - 1] != '/')
- n--;
-
- strcpy(adns_path_space + n, adns_name);
- adns_path = adns_path_space;
- }
- if (access(adns_path, X_OK) < 0)
- exit_log_errno((e, "%s missing or not executable", adns_path));
-
- if (pipe(qfds) != 0 || pipe(afds) != 0)
- exit_log_errno((e, "pipe(2) failed in init_adns()"));
-
- adns_pid = fork();
- switch (adns_pid)
- {
- case -1:
- exit_log_errno((e, "fork() failed in init_adns()"));
-
- case 0:
- /* child */
- {
- /* Make stdin and stdout our pipes.
- * Take care to handle case where pipes already use these fds.
- */
- if (afds[1] == 0)
- afds[1] = dup(afds[1]); /* avoid being overwritten */
- if (qfds[0] != 0)
- {
- dup2(qfds[0], 0);
- close(qfds[0]);
- }
- if (afds[1] != 1)
- {
- dup2(afds[1], 1);
- close(qfds[1]);
- }
- if (afds[0] > 1)
- close(afds[0]);
- if (afds[1] > 1)
- close(afds[1]);
-
- DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
-
- execlp(adns_path, adns_name, NULL);
- exit_log_errno((e, "execlp of %s failed", adns_path));
- }
-
- default:
- /* parent */
- close(qfds[0]);
- adns_qfd = qfds[1];
- adns_afd = afds[0];
- close(afds[1]);
- fcntl(adns_qfd, F_SETFD, FD_CLOEXEC);
- fcntl(adns_afd, F_SETFD, FD_CLOEXEC);
- fcntl(adns_qfd, F_SETFL, O_NONBLOCK);
- break;
- }
-}
-
-void
-stop_adns(void)
-{
- close_any(adns_qfd);
- adns_qfd = NULL_FD;
- close_any(adns_afd);
- adns_afd = NULL_FD;
-
- if (adns_pid != 0)
- {
- int status;
- pid_t p = waitpid(adns_pid, &status, 0);
-
- if (p == -1)
- {
- log_errno((e, "waitpid for ADNS process failed"));
- }
- else if (WIFEXITED(status))
- {
- if (WEXITSTATUS(status) != 0)
- plog("ADNS process exited with status %d"
- , (int) WEXITSTATUS(status));
- }
- else if (WIFSIGNALED(status))
- {
- plog("ADNS process terminated by signal %d", (int)WTERMSIG(status));
- }
- else
- {
- plog("wait for end of ADNS process returned odd status 0x%x\n"
- , status);
- }
- }
-}
-
-
-
-/* tricky macro to pass any hot potato */
-#define TRY(x) { err_t ugh = x; if (ugh != NULL) return ugh; }
-
-
-/* Process TXT X-IPsec-Server record, accumulating relevant ones
- * in cr->gateways_from_dns, a list sorted by "preference".
- *
- * Format of TXT record body: X-IPsec-Server ( nnn ) = iii kkk
- * nnn is a 16-bit unsigned integer preference
- * iii is @FQDN or dotted-decimal IPv4 address or colon-hex IPv6 address
- * kkk is an optional RSA public signing key in base 64.
- *
- * NOTE: we've got to be very wary of anything we find -- bad guys
- * might have prepared it.
- */
-
-#define our_TXT_attr_string "X-IPsec-Server"
-static const char our_TXT_attr[] = our_TXT_attr_string;
-
-static err_t
-decode_iii(u_char **pp, struct id *gw_id)
-{
- u_char *p = *pp + strspn(*pp, " \t");
- u_char *e = p + strcspn(p, " \t");
- u_char under = *e;
-
- if (p == e)
- return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
-
- *e = '\0';
- if (*p == '@')
- {
- /* gateway specification in this record is @FQDN */
- err_t ugh = atoid(p, gw_id, FALSE);
-
- if (ugh != NULL)
- return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
- , ugh);
- }
- else
- {
- /* gateway specification is numeric */
- ip_address ip;
- err_t ugh = tnatoaddr(p, e-p
- , strchr(p, ':') == NULL? AF_INET : AF_INET6
- , &ip);
-
- if (ugh != NULL)
- return builddiag("malformed IP address in TXT " our_TXT_attr_string ": %s"
- , ugh);
-
- if (isanyaddr(&ip))
- return "gateway address must not be 0.0.0.0 or 0::0";
-
- iptoid(&ip, gw_id);
- }
-
- *e = under;
- *pp = e + strspn(e, " \t");
-
- return NULL;
-}
-
-static err_t
-process_txt_rr_body(u_char *str
-, bool doit /* should we capture information? */
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
- const struct id *client_id = &cr->id; /* subject of query */
- u_char *p = str;
- unsigned long pref = 0;
- struct gw_info gi;
-
- p += strspn(p, " \t"); /* ignore leading whitespace */
-
- /* is this for us? */
- if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
- return NULL; /* neither interesting nor bad */
-
- p += sizeof(our_TXT_attr) - 1; /* ignore our attribute name */
- p += strspn(p, " \t"); /* ignore leading whitespace */
-
- /* decode '(' nnn ')' */
- if (*p != '(')
- return "X-IPsec-Server missing '('";
-
- {
- char *e;
-
- p++;
- pref = strtoul(p, &e, 0);
- if ((u_char *)e == p)
- return "malformed X-IPsec-Server priority";
-
- p = e + strspn(e, " \t");
-
- if (*p != ')')
- return "X-IPsec-Server priority missing ')'";
-
- p++;
- p += strspn(p, " \t");
-
- if (pref > 0xFFFF)
- return "X-IPsec-Server priority larger than 0xFFFF";
- }
-
- /* time for '=' */
-
- if (*p != '=')
- return "X-IPsec-Server priority missing '='";
-
- p++;
- p += strspn(p, " \t");
-
- /* Decode iii (Security Gateway ID). */
-
- zero(&gi); /* before first use */
-
- TRY(decode_iii(&p, &gi.gw_id)); /* will need to unshare_id_content */
-
- if (!cr->sgw_specified)
- {
- /* we don't know the peer's ID (because we are initiating
- * and we don't know who to initiate with.
- * So we're looking for gateway specs with an IP address
- */
- if (!id_is_ipaddr(&gi.gw_id))
- {
- DBG(DBG_DNS,
- {
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
-
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
- DBG_log("TXT %s record for %s: security gateway %s;"
- " ignored because gateway's IP is unspecified"
- , our_TXT_attr, cidb, gwidb);
- });
- return NULL; /* we cannot use this record, but it isn't wrong */
- }
- }
- else
- {
- /* We do know the peer's ID (because we are responding)
- * So we're looking for gateway specs specifying this known ID.
- */
- const struct id *peer_id = &cr->sgw_id;
-
- if (!same_id(peer_id, &gi.gw_id))
- {
- DBG(DBG_DNS,
- {
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
- char pidb[BUF_LEN];
-
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
- idtoa(peer_id, pidb, sizeof(pidb));
- DBG_log("TXT %s record for %s: security gateway %s;"
- " ignored -- looking to confirm %s as gateway"
- , our_TXT_attr, cidb, gwidb, pidb);
- });
- return NULL; /* we cannot use this record, but it isn't wrong */
- }
- }
-
- if (doit)
- {
- /* really accept gateway */
- struct gw_info **gwip; /* gateway insertion point */
-
- gi.client_id = *client_id; /* will need to unshare_id_content */
-
- /* decode optional kkk: base 64 encoding of key */
-
- gi.gw_key_present = *p != '\0';
- if (gi.gw_key_present)
- {
- /* Decode base 64 encoding of key.
- * Similar code is in process_lwdnsq_key.
- */
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- struct RSA_public_key r;
-
- err_t ugh = ttodatav(p, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-
- if (ugh != NULL)
- return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- ugh = unpack_RSA_public_key(&r, &kbc);
- if (ugh != NULL)
- return builddiag("invalid key data: %s", ugh);
-
- /* now find a key entry to put it in */
- gi.key = public_key_from_rsa(&r);
-
- free_RSA_public_content(&r);
-
- unreference_key(&cr->last_info);
- cr->last_info = reference_key(gi.key);
- }
-
- /* we're home free! Allocate everything and add to gateways list. */
- gi.refcnt = 1;
- gi.pref = pref;
- gi.key->dns_auth_level = dns_auth_level;
- gi.key->last_tried_time = gi.key->last_worked_time = NO_TIME;
-
- /* find insertion point */
- for (gwip = &cr->gateways_from_dns; *gwip != NULL && (*gwip)->pref < pref; gwip = &(*gwip)->next)
- ;
-
- DBG(DBG_DNS,
- {
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
-
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
- if (gi.gw_key_present)
- {
- DBG_log("gateway for %s is %s with key %s"
- , cidb, gwidb, gi.key->u.rsa.keyid);
- }
- else
- {
- DBG_log("gateway for %s is %s; no key specified"
- , cidb, gwidb);
- }
- });
-
- gi.next = *gwip;
- *gwip = clone_thing(gi, "gateway info");
- unshare_id_content(&(*gwip)->gw_id);
- unshare_id_content(&(*gwip)->client_id);
- }
-
- return NULL;
-}
-
-static const char *
-rr_typename(int type)
-{
- switch (type)
- {
- case T_TXT:
- return "TXT";
- case T_KEY:
- return "KEY";
- default:
- return "???";
- }
-}
-
-
-#ifdef USE_LWRES
-
-# ifdef USE_KEYRR
-static err_t
-process_lwdnsq_key(u_char *str
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
- /* fields of KEY record. See RFC 2535 3.1 KEY RDATA format. */
- unsigned long flags /* 16 bits */
- , protocol /* 8 bits */
- , algorithm; /* 8 bits */
-
- char *rest = str
- , *p
- , *endofnumber;
-
- /* flags */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing flags";
-
- flags = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed flags";
-
- /* protocol */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing protocol";
-
- protocol = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed protocol";
-
- /* algorithm */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing algorithm";
-
- algorithm = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed algorithm";
-
- /* is this key interesting? */
- if (protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
- && algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
- && (flags & 0x8000ul) == 0 /* use for authentication (3.1.2) */
- && (flags & 0x2CF0ul) == 0) /* must be zero */
- {
- /* Decode base 64 encoding of key.
- * Similar code is in process_txt_rr_body.
- */
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- err_t ugh = ttodatav(rest, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_IGNORESPACE);
-
- if (ugh != NULL)
- return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &kbc
- , &cr->keys_from_dns));
-
- /* keep a reference to last one */
- unreference_key(&cr->last_info);
- cr->last_info = reference_key(cr->keys_from_dns->key);
- }
- return NULL;
-}
-# endif /* USE_KEYRR */
-
-#else /* ! USE_LWRES */
-
-/* structure of Query Reply (RFC 1035 4.1.1):
- *
- * +---------------------+
- * | Header |
- * +---------------------+
- * | Question | the question for the name server
- * +---------------------+
- * | Answer | RRs answering the question
- * +---------------------+
- * | Authority | RRs pointing toward an authority
- * +---------------------+
- * | Additional | RRs holding additional information
- * +---------------------+
- */
-
-/* Header section format (as modified by RFC 2535 6.1):
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ID |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QDCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ANCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | NSCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | ARCOUNT |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-struct qr_header {
- u_int16_t id; /* 16-bit identifier to match query */
-
- u_int16_t stuff; /* packed crud: */
-
-#define QRS_QR 0x8000 /* QR: on if this is a response */
-
-#define QRS_OPCODE_SHIFT 11 /* OPCODE field */
-#define QRS_OPCODE_MASK 0xF
-#define QRSO_QUERY 0 /* standard query */
-#define QRSO_IQUERY 1 /* inverse query */
-#define QRSO_STATUS 2 /* server status request query */
-
-#define QRS_AA 0x0400 /* AA: on if Authoritative Answer */
-#define QRS_TC 0x0200 /* TC: on if truncation happened */
-#define QRS_RD 0x0100 /* RD: on if recursion desired */
-#define QRS_RA 0x0080 /* RA: on if recursion available */
-#define QRS_Z 0x0040 /* Z: reserved; must be zero */
-#define QRS_AD 0x0020 /* AD: on if authentic data (RFC 2535) */
-#define QRS_CD 0x0010 /* AD: on if checking disabled (RFC 2535) */
-
-#define QRS_RCODE_SHIFT 0 /* RCODE field: response code */
-#define QRS_RCODE_MASK 0xF
-#define QRSR_OK 0
-
-
- u_int16_t qdcount; /* number of entries in question section */
- u_int16_t ancount; /* number of resource records in answer section */
- u_int16_t nscount; /* number of name server resource records in authority section */
- u_int16_t arcount; /* number of resource records in additional records section */
-};
-
-static field_desc qr_header_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "ID", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "stuff", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "QD Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Answer Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Authority Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Additional Count", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc qr_header_desc = {
- "Query Response Header",
- qr_header_fields,
- sizeof(struct qr_header)
-};
-
-/* Messages for codes in RCODE (see RFC 1035 4.1.1) */
-static const err_t rcode_text[QRS_RCODE_MASK + 1] = {
- NULL, /* not an error */
- "Format error - The name server was unable to interpret the query",
- "Server failure - The name server was unable to process this query"
- " due to a problem with the name server",
- "Name Error - Meaningful only for responses from an authoritative name"
- " server, this code signifies that the domain name referenced in"
- " the query does not exist",
- "Not Implemented - The name server does not support the requested"
- " kind of query",
- "Refused - The name server refuses to perform the specified operation"
- " for policy reasons",
- /* the rest are reserved for future use */
- };
-
-/* throw away a possibly compressed domain name */
-
-static err_t
-eat_name(pb_stream *pbs)
-{
- u_char name_buf[NS_MAXDNAME + 2];
- u_char *ip = pbs->cur;
- unsigned oi = 0;
- unsigned jump_count = 0;
-
- for (;;)
- {
- u_int8_t b;
-
- if (ip >= pbs->roof)
- return "ran out of message while skipping domain name";
-
- b = *ip++;
- if (jump_count == 0)
- pbs->cur = ip;
-
- if (b == 0)
- break;
-
- switch (b & 0xC0)
- {
- case 0x00:
- /* we grab the next b characters */
- if (oi + b > NS_MAXDNAME)
- return "domain name too long";
-
- if (pbs->roof - ip <= b)
- return "domain name falls off end of message";
-
- if (oi != 0)
- name_buf[oi++] = '.';
-
- memcpy(name_buf + oi, ip, b);
- oi += b;
- ip += b;
- if (jump_count == 0)
- pbs->cur = ip;
- break;
-
- case 0xC0:
- {
- unsigned ix;
-
- if (ip >= pbs->roof)
- return "ran out of message in middle of compressed domain name";
-
- ix = ((b & ~0xC0u) << 8) | *ip++;
- if (jump_count == 0)
- pbs->cur = ip;
-
- if (ix >= pbs_room(pbs))
- return "impossible compressed domain name";
-
- /* Avoid infinite loop.
- * There can be no more jumps than there are bytes
- * in the packet. Not a tight limit, but good enough.
- */
- jump_count++;
- if (jump_count > pbs_room(pbs))
- return "loop in compressed domain name";
-
- ip = pbs->start + ix;
- }
- break;
-
- default:
- return "invalid code in label";
- }
- }
-
- name_buf[oi++] = '\0';
-
- DBG(DBG_DNS, DBG_log("skipping name %s", name_buf));
-
- return NULL;
-}
-
-static err_t
-eat_name_helpfully(pb_stream *pbs, const char *context)
-{
- err_t ugh = eat_name(pbs);
-
- return ugh == NULL? ugh
- : builddiag("malformed name within DNS record of %s: %s", context, ugh);
-}
-
-/* non-variable part of 4.1.2 Question Section entry:
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | |
- * / QNAME /
- * / /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QTYPE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QCLASS |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
-struct qs_fixed {
- u_int16_t qtype;
- u_int16_t qclass;
-};
-
-static field_desc qs_fixed_fields[] = {
- { ft_loose_enum, 16/BITS_PER_BYTE, "QTYPE", &rr_qtype_names },
- { ft_loose_enum, 16/BITS_PER_BYTE, "QCLASS", &rr_class_names },
- { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc qs_fixed_desc = {
- "Question Section entry fixed part",
- qs_fixed_fields,
- sizeof(struct qs_fixed)
-};
-
-/* 4.1.3. Resource record format:
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | |
- * / /
- * / NAME /
- * | |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | TYPE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | CLASS |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | TTL |
- * | |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | RDLENGTH |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
- * / RDATA /
- * / /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
-struct rr_fixed {
- u_int16_t type;
- u_int16_t class;
- u_int32_t ttl; /* actually signed */
- u_int16_t rdlength;
-};
-
-
-static field_desc rr_fixed_fields[] = {
- { ft_loose_enum, 16/BITS_PER_BYTE, "type", &rr_type_names },
- { ft_loose_enum, 16/BITS_PER_BYTE, "class", &rr_class_names },
- { ft_nat, 32/BITS_PER_BYTE, "TTL", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "RD length", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc rr_fixed_desc = {
- "Resource Record fixed part",
- rr_fixed_fields,
- /* note: following is tricky: avoids padding problems */
- offsetof(struct rr_fixed, rdlength) + sizeof(u_int16_t)
-};
-
-/* RFC 1035 3.3.14: TXT RRs have text in the RDATA field.
- * It is in the form of a sequence of <character-string>s as described in 3.3.
- * unpack_txt_rdata() deals with this peculiar representation.
- */
-
-/* RFC 2535 3.1 KEY RDATA format:
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | flags | protocol | algorithm |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | /
- * / public key /
- * / /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
- */
-
-struct key_rdata {
- u_int16_t flags;
- u_int8_t protocol;
- u_int8_t algorithm;
-};
-
-static field_desc key_rdata_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "flags", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "protocol", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc key_rdata_desc = {
- "KEY RR RData fixed part",
- key_rdata_fields,
- sizeof(struct key_rdata)
-};
-
-/* RFC 2535 4.1 SIG RDATA format:
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | type covered | algorithm | labels |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | original TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | signature expiration |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | signature inception |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | key tag | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ signer's name +
- * | /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-/
- * / /
- * / signature /
- * / /
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-struct sig_rdata {
- u_int16_t type_covered;
- u_int8_t algorithm;
- u_int8_t labels;
- u_int32_t original_ttl;
- u_int32_t sig_expiration;
- u_int32_t sig_inception;
- u_int16_t key_tag;
-};
-
-static field_desc sig_rdata_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "type_covered", NULL},
- { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL},
- { ft_nat, 8/BITS_PER_BYTE, "labels", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "original ttl", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "sig expiration", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "sig inception", NULL},
- { ft_nat, 16/BITS_PER_BYTE, "key tag", NULL},
- { ft_end, 0, NULL, NULL }
-};
-
-static struct_desc sig_rdata_desc = {
- "SIG RR RData fixed part",
- sig_rdata_fields,
- sizeof(struct sig_rdata)
-};
-
-/* handle a KEY Resource Record. */
-
-#ifdef USE_KEYRR
-static err_t
-process_key_rr(u_char *ptr, size_t len
-, bool doit /* should we capture information? */
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
- pb_stream pbs;
- struct key_rdata kr;
-
- if (len < sizeof(struct key_rdata))
- return "KEY Resource Record's RD Length is too small";
-
- init_pbs(&pbs, ptr, len, "KEY RR");
-
- if (!in_struct(&kr, &key_rdata_desc, &pbs, NULL))
- return "failed to get fixed part of KEY Resource Record RDATA";
-
- if (kr.protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
- && kr.algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
- && (kr.flags & 0x8000) == 0 /* use for authentication (3.1.2) */
- && (kr.flags & 0x2CF0) == 0) /* must be zero */
- {
- /* we have what seems to be a tasty key */
-
- if (doit)
- {
- chunk_t k;
-
- setchunk(k, pbs.cur, pbs_left(&pbs));
- TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &k
- , &cr->keys_from_dns));
- }
- }
- return NULL;
-}
-#endif /* USE_KEYRR */
-
-
-/* unpack TXT rr RDATA into C string.
- * A sequence of <character-string>s as described in RFC 1035 3.3.
- * We concatenate them.
- */
-static err_t
-unpack_txt_rdata(u_char *d, size_t dlen, const u_char *s, size_t slen)
-{
- size_t i = 0
- , o = 0;
-
- while (i < slen)
- {
- size_t cl = s[i++];
-
- if (i + cl > slen)
- return "TXT rr RDATA representation malformed";
-
- if (o + cl >= dlen)
- return "TXT rr RDATA too large";
-
- memcpy(d + o, s + i, cl);
- i += cl;
- o += cl;
- }
- d[o] = '\0';
- if (strlen(d) != o)
- return "TXT rr RDATA contains a NUL";
-
- return NULL;
-}
-
-static err_t
-process_txt_rr(u_char *rdata, size_t rdlen
-, bool doit /* should we capture information? */
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
- u_char str[RSA_MAX_ENCODING_BYTES * 8 / 6 + 20]; /* space for unpacked RDATA */
-
- TRY(unpack_txt_rdata(str, sizeof(str), rdata, rdlen));
- return process_txt_rr_body(str, doit, dns_auth_level, cr);
-}
-
-static err_t
-process_answer_section(pb_stream *pbs
-, bool doit /* should we capture information? */
-, enum dns_auth_level *dns_auth_level
-, u_int16_t ancount /* number of RRs in the answer section */
-, struct adns_continuation *const cr)
-{
- const int type = cr->query.type; /* type of RR of interest */
- unsigned c;
-
- DBG(DBG_DNS, DBG_log("*Answer Section:"));
-
- for (c = 0; c != ancount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
-
- /* ??? do we need to match the name? */
-
- TRY(eat_name_helpfully(pbs, "Answer Section"));
-
- if (!in_struct(&rrf, &rr_fixed_desc, pbs, NULL))
- return "failed to get fixed part of Answer Section Resource Record";
-
- if (rrf.rdlength > pbs_left(pbs))
- return "RD Length extends beyond end of message";
-
- /* ??? should we care about ttl? */
-
- tail = rrf.rdlength;
-
- if (rrf.type == type && rrf.class == C_IN)
- {
- err_t ugh = NULL;
-
- switch (type)
- {
-#ifdef USE_KEYRR
- case T_KEY:
- ugh = process_key_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
- break;
-#endif /* USE_KEYRR */
- case T_TXT:
- ugh = process_txt_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
- break;
- case T_SIG:
- /* Check if SIG RR authenticates what we are learning.
- * The RRset covered by a SIG must have the same owner,
- * class, and type.
- * For us, the class is always C_IN, so that matches.
- * We decode the SIG RR's fixed part to check
- * that the type_covered field matches our query type
- * (this may be redundant).
- * We don't check the owner (apparently this is the
- * name on the record) -- we assume that it matches
- * or we would not have been given this SIG in the
- * Answer Section.
- *
- * We only look on first pass, and only if we've something
- * to learn. This cuts down on useless decoding.
- */
- if (!doit && *dns_auth_level == DAL_UNSIGNED)
- {
- struct sig_rdata sr;
-
- if (!in_struct(&sr, &sig_rdata_desc, pbs, NULL))
- ugh = "failed to get fixed part of SIG Resource Record RDATA";
- else if (sr.type_covered == type)
- *dns_auth_level = DAL_SIGNED;
- }
- break;
- default:
- ugh = builddiag("unexpected RR type %d", type);
- break;
- }
- if (ugh != NULL)
- return ugh;
- }
- in_raw(NULL, tail, pbs, "RR RDATA");
- }
-
- return doit
- && cr->gateways_from_dns == NULL
-#ifdef USE_KEYRR
- && cr->keys_from_dns == NULL
-#endif /* USE_KEYRR */
- ? builddiag("no suitable %s record found in DNS", rr_typename(type))
- : NULL;
-}
-
-/* process DNS answer -- TXT or KEY query */
-
-static err_t
-process_dns_answer(struct adns_continuation *const cr
-, u_char ans[], int anslen)
-{
- const int type = cr->query.type; /* type of record being sought */
- int r; /* all-purpose return value holder */
- u_int16_t c; /* number of current RR in current answer section */
- pb_stream pbs;
- u_int8_t *ans_start; /* saved position of answer section */
- struct qr_header qr_header;
- enum dns_auth_level dns_auth_level;
-
- init_pbs(&pbs, ans, anslen, "Query Response Message");
-
- /* decode and check header */
-
- if (!in_struct(&qr_header, &qr_header_desc, &pbs, NULL))
- return "malformed header";
-
- /* ID: nothing to do with us */
-
- /* stuff -- lots of things */
- if ((qr_header.stuff & QRS_QR) == 0)
- return "not a response?!?";
-
- if (((qr_header.stuff >> QRS_OPCODE_SHIFT) & QRS_OPCODE_MASK) != QRSO_QUERY)
- return "unexpected opcode";
-
- /* I don't think we care about AA */
-
- if (qr_header.stuff & QRS_TC)
- return "response truncated";
-
- /* I don't think we care about RD, RA, or CD */
-
- /* AD means "authentic data" */
- dns_auth_level = qr_header.stuff & QRS_AD? DAL_UNSIGNED : DAL_NOTSEC;
-
- if (qr_header.stuff & QRS_Z)
- return "Z bit is not zero";
-
- r = (qr_header.stuff >> QRS_RCODE_SHIFT) & QRS_RCODE_MASK;
- if (r != 0)
- return r < (int)elemsof(rcode_text)? rcode_text[r] : "unknown rcode";
-
- if (qr_header.ancount == 0)
- return builddiag("no %s RR found by DNS", rr_typename(type));
-
- /* end of header checking */
-
- /* Question Section processing */
-
- /* 4.1.2. Question section format:
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | |
- * / QNAME /
- * / /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QTYPE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QCLASS |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
- DBG(DBG_DNS, DBG_log("*Question Section:"));
-
- for (c = 0; c != qr_header.qdcount; c++)
- {
- struct qs_fixed qsf;
-
- TRY(eat_name_helpfully(&pbs, "Question Section"));
-
- if (!in_struct(&qsf, &qs_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Question Section";
-
- if (qsf.qtype != type)
- return "unexpected QTYPE in Question Section";
-
- if (qsf.qclass != C_IN)
- return "unexpected QCLASS in Question Section";
- }
-
- /* rest of sections are made up of Resource Records */
-
- /* Answer Section processing -- error checking, noting T_SIG */
-
- ans_start = pbs.cur; /* remember start of answer section */
-
- TRY(process_answer_section(&pbs, FALSE, &dns_auth_level
- , qr_header.ancount, cr));
-
- /* Authority Section processing (just sanity checking) */
-
- DBG(DBG_DNS, DBG_log("*Authority Section:"));
-
- for (c = 0; c != qr_header.nscount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
-
- TRY(eat_name_helpfully(&pbs, "Authority Section"));
-
- if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Authority Section Resource Record";
-
- if (rrf.rdlength > pbs_left(&pbs))
- return "RD Length extends beyond end of message";
-
- /* ??? should we care about ttl? */
-
- tail = rrf.rdlength;
-
- in_raw(NULL, tail, &pbs, "RR RDATA");
- }
-
- /* Additional Section processing (just sanity checking) */
-
- DBG(DBG_DNS, DBG_log("*Additional Section:"));
-
- for (c = 0; c != qr_header.arcount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
-
- TRY(eat_name_helpfully(&pbs, "Additional Section"));
-
- if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Additional Section Resource Record";
-
- if (rrf.rdlength > pbs_left(&pbs))
- return "RD Length extends beyond end of message";
-
- /* ??? should we care about ttl? */
-
- tail = rrf.rdlength;
-
- in_raw(NULL, tail, &pbs, "RR RDATA");
- }
-
- /* done all sections */
-
- /* ??? is padding legal, or can we complain if more left in record? */
-
- /* process Answer Section again -- accept contents */
-
- pbs.cur = ans_start; /* go back to start of answer section */
-
- return process_answer_section(&pbs, TRUE, &dns_auth_level
- , qr_header.ancount, cr);
-}
-
-#endif /* ! USE_LWRES */
-
-
-/****************************************************************/
-
-static err_t
-build_dns_name(u_char name_buf[NS_MAXDNAME + 2]
-, unsigned long serial USED_BY_DEBUG
-, const struct id *id
-, const char *typename USED_BY_DEBUG
-, const char *gwname USED_BY_DEBUG)
-{
- /* note: all end in "." to suppress relative searches */
- id = resolve_myid(id);
- switch (id->kind)
- {
- case ID_IPV4_ADDR:
- {
- /* XXX: this is really ugly and only temporary until addrtot can
- * generate the correct format
- */
- const unsigned char *b;
- size_t bl USED_BY_DEBUG = addrbytesptr(&id->ip_addr, &b);
-
- passert(bl == 4);
- snprintf(name_buf, NS_MAXDNAME + 2, "%d.%d.%d.%d.in-addr.arpa."
- , b[3], b[2], b[1], b[0]);
- break;
- }
-
- case ID_IPV6_ADDR:
- {
- /* ??? is this correct? */
- const unsigned char *b;
- size_t bl;
- u_char *op = name_buf;
- static const char suffix[] = "IP6.INT.";
-
- for (bl = addrbytesptr(&id->ip_addr, &b); bl-- != 0; )
- {
- if (op + 4 + sizeof(suffix) >= name_buf + NS_MAXDNAME + 1)
- return "IPv6 reverse name too long";
- op += sprintf(op, "%x.%x.", b[bl] & 0xF, b[bl] >> 4);
- }
- strcpy(op, suffix);
- break;
- }
-
- case ID_FQDN:
- /* strip trailing "." characters, then add one */
- {
- size_t il = id->name.len;
-
- while (il > 0 && id->name.ptr[il - 1] == '.')
- il--;
- if (il > NS_MAXDNAME)
- return "FQDN too long for domain name";
-
- memcpy(name_buf, id->name.ptr, il);
- strcpy(name_buf + il, ".");
- }
- break;
-
- default:
- return "can only query DNS for key for ID that is a FQDN, IPV4_ADDR, or IPV6_ADDR";
- }
-
- DBG(DBG_CONTROL | DBG_DNS, DBG_log("DNS query %lu for %s for %s (gw: %s)"
- , serial, typename, name_buf, gwname));
- return NULL;
-}
-
-void
-gw_addref(struct gw_info *gw)
-{
- if (gw != NULL)
- {
- DBG(DBG_DNS, DBG_log("gw_addref: %p refcnt: %d++", gw, gw->refcnt))
- gw->refcnt++;
- }
-}
-
-void
-gw_delref(struct gw_info **gwp)
-{
- struct gw_info *gw = *gwp;
-
- if (gw != NULL)
- {
- DBG(DBG_DNS, DBG_log("gw_delref: %p refcnt: %d--", gw, gw->refcnt));
-
- passert(gw->refcnt != 0);
- gw->refcnt--;
- if (gw->refcnt == 0)
- {
- free_id_content(&gw->client_id);
- free_id_content(&gw->gw_id);
- if (gw->gw_key_present)
- unreference_key(&gw->key);
- gw_delref(&gw->next);
- pfree(gw); /* trickery could make this a tail-call */
- }
- *gwp = NULL;
- }
-}
-
-static int adns_in_flight = 0; /* queries outstanding */
-
-/* Start an asynchronous DNS query.
- *
- * For KEY record, the result will be a list in cr->keys_from_dns.
- * For TXT records, the result will be a list in cr->gateways_from_dns.
- *
- * If sgw_id is null, only consider TXT records that specify an
- * IP address for the gatway: we need this in the initiation case.
- *
- * If sgw_id is non-null, only consider TXT records that specify
- * this id as the security gatway; this is useful to the Responder
- * for confirming claims of gateways.
- *
- * Continuation cr gives information for continuing when the result shows up.
- *
- * Two kinds of errors must be handled: synchronous (immediate)
- * and asynchronous. Synchronous errors are indicated by the returned
- * value of start_adns_query; in this case, the continuation will
- * have been freed and the continuation routine will not be called.
- * Asynchronous errors are indicated by the ugh parameter passed to the
- * continuation routine.
- *
- * After the continuation routine has completed, handle_adns_answer
- * will free the continuation. The continuation routine should have
- * freed any axiliary resources.
- *
- * Note: in the synchronous error case, start_adns_query will have
- * freed the continuation; this means that the caller will have to
- * be very careful to release any auxiliary resources that were in
- * the continuation record without using the continuation record.
- *
- * Either there will be an error result passed to the continuation routine,
- * or the results will be in cr->keys_from_dns or cr->gateways_from_dns.
- * The result variables must by left NULL by the continutation routine.
- * The continuation routine is responsible for establishing and
- * disestablishing any logging context (whack_log_fd, cur_*).
- */
-
-static struct adns_continuation *continuations = NULL; /* newest of queue */
-static struct adns_continuation *next_query = NULL; /* oldest not sent */
-
-static struct adns_continuation *
-continuation_for_qtid(unsigned long qtid)
-{
- struct adns_continuation *cr = NULL;
-
- if (qtid != 0)
- for (cr = continuations; cr != NULL && cr->qtid != qtid; cr = cr->previous)
- ;
- return cr;
-}
-
-static void
-release_adns_continuation(struct adns_continuation *cr)
-{
- passert(cr != next_query);
- gw_delref(&cr->gateways_from_dns);
-#ifdef USE_KEYRR
- free_public_keys(&cr->keys_from_dns);
-#endif /* USE_KEYRR */
- unshare_id_content(&cr->id);
- unshare_id_content(&cr->sgw_id);
-
- /* unlink from doubly-linked list */
- if (cr->next == NULL)
- {
- passert(continuations == cr);
- continuations = cr->previous;
- }
- else
- {
- passert(cr->next->previous == cr);
- cr->next->previous = cr->previous;
- }
-
- if (cr->previous != NULL)
- {
- passert(cr->previous->next == cr);
- cr->previous->next = cr->next;
- }
-
- pfree(cr);
-}
-
-err_t
-start_adns_query(const struct id *id /* domain to query */
-, const struct id *sgw_id /* if non-null, any accepted gw_info must match */
-, int type /* T_TXT or T_KEY, selecting rr type of interest */
-, cont_fn_t cont_fn
-, struct adns_continuation *cr)
-{
- static unsigned long qtid = 1; /* query transaction id; NOTE: static */
- const char *typename = rr_typename(type);
- char gwidb[BUF_LEN];
-
- if(adns_pid == 0
- && adns_restart_count < ADNS_RESTART_MAX)
- {
- plog("ADNS helper was not running. Restarting attempt %d",adns_restart_count);
- init_adns();
- }
-
-
- /* Splice this in at head of doubly-linked list of continuations.
- * Note: this must be done before any release_adns_continuation().
- */
- cr->next = NULL;
- cr->previous = continuations;
- if (continuations != NULL)
- {
- passert(continuations->next == NULL);
- continuations->next = cr;
- }
- continuations = cr;
-
- cr->qtid = qtid++;
- cr->type = type;
- cr->cont_fn = cont_fn;
- cr->id = *id;
- unshare_id_content(&cr->id);
- cr->sgw_specified = sgw_id != NULL;
- cr->sgw_id = cr->sgw_specified? *sgw_id : empty_id;
- unshare_id_content(&cr->sgw_id);
- cr->gateways_from_dns = NULL;
-#ifdef USE_KEYRR
- cr->keys_from_dns = NULL;
-#endif /* USE_KEYRR */
-
-#ifdef DEBUG
- cr->debugging = cur_debugging;
-#else
- cr->debugging = LEMPTY;
-#endif
-
- idtoa(&cr->sgw_id, gwidb, sizeof(gwidb));
-
- zero(&cr->query);
-
- {
- err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid
- , id, typename, gwidb);
-
- if (ugh != NULL)
- {
- release_adns_continuation(cr);
- return ugh;
- }
- }
-
- if (next_query == NULL)
- next_query = cr;
-
- unsent_ADNS_queries = TRUE;
-
- return NULL;
-}
-
-/* send remaining ADNS queries (until pipe full or none left)
- *
- * This is a co-routine, so it uses static variables to
- * preserve state across calls.
- */
-bool unsent_ADNS_queries = FALSE;
-
-void
-send_unsent_ADNS_queries(void)
-{
- static const unsigned char *buf_end = NULL; /* NOTE STATIC */
- static const unsigned char *buf_cur = NULL; /* NOTE STATIC */
-
- if (adns_qfd == NULL_FD)
- return; /* nothing useful to do */
-
- for (;;)
- {
- if (buf_cur != buf_end)
- {
- static int try = 0; /* NOTE STATIC */
- size_t n = buf_end - buf_cur;
- ssize_t r = write(adns_qfd, buf_cur, n);
-
- if (r == -1)
- {
- switch (errno)
- {
- case EINTR:
- continue; /* try again now */
- case EAGAIN:
- DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));
- break; /* try again later */
- default:
- try++;
- log_errno((e, "error %d writing DNS query", try));
- break; /* try again later */
- }
- unsent_ADNS_queries = TRUE;
- break; /* done! */
- }
- else
- {
- passert(r >= 0);
- try = 0;
- buf_cur += r;
- }
- }
- else
- {
- if (next_query == NULL)
- {
- unsent_ADNS_queries = FALSE;
- break; /* done! */
- }
-
-#ifdef USE_LWRES
- next_query->used = FALSE;
- {
- /* NOTE STATIC: */
- static unsigned char qbuf[LWDNSQ_CMDBUF_LEN + 1]; /* room for NUL */
-
- snprintf(qbuf, sizeof(qbuf), "%s %lu %s\n"
- , rr_typename(next_query->type)
- , next_query->qtid
- , next_query->query.name_buf);
- DBG(DBG_DNS, DBG_log("lwdnsq query: %.*s", (int)(strlen(qbuf) - 1), qbuf));
- buf_cur = qbuf;
- buf_end = qbuf + strlen(qbuf);
- }
-#else /* !USE_LWRES */
- next_query->query.debugging = next_query->debugging;
- next_query->query.serial = next_query->qtid;
- next_query->query.len = sizeof(next_query->query);
- next_query->query.qmagic = ADNS_Q_MAGIC;
- next_query->query.type = next_query->type;
- buf_cur = (const void *)&next_query->query;
- buf_end = buf_cur + sizeof(next_query->query);
-#endif /* !USE_LWRES */
- next_query = next_query->next;
- adns_in_flight++;
- }
- }
-}
-
-#ifdef USE_LWRES
-/* Process a line of lwdnsq answer.
- * Returns with error message iff lwdnsq result is malformed.
- * Most errors will be in DNS data and will be handled by cr->cont_fn.
- */
-static err_t
-process_lwdnsq_answer(char *ts)
-{
- err_t ugh = NULL;
- char *rest;
- char *p;
- char *endofnumber;
- struct adns_continuation *cr = NULL;
- unsigned long qtid;
- time_t anstime; /* time of answer */
- char *atype; /* type of answer */
- long ttl; /* ttl of answer; int, but long for conversion */
- bool AuthenticatedData = FALSE;
- static char scratch_null_str[] = ""; /* cannot be const, but isn't written */
-
- /* query transaction id */
- rest = ts;
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: answer missing query transaction ID";
-
- qtid = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed query transaction ID";
-
- cr = continuation_for_qtid(qtid);
- if (qtid != 0 && cr == NULL)
- return "lwdnsq: unrecognized qtid"; /* can't happen! */
-
- /* time */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing time";
-
- anstime = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed time";
-
- /* TTL */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing TTL";
-
- ttl = strtol(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed TTL";
-
- /* type */
- atype = strsep(&rest, " \t");
- if (atype == NULL)
- return "lwdnsq: missing type";
-
- /* if rest is NULL, make it "", otherwise eat whitespace after type */
- rest = rest == NULL? scratch_null_str : rest + strspn(rest, " \t");
-
- if (strncasecmp(atype, "AD-", 3) == 0)
- {
- AuthenticatedData = TRUE;
- atype += 3;
- }
-
- /* deal with each type */
-
- if (cr == NULL)
- {
- /* we don't actually know which this applies to */
- return builddiag("lwdnsq: 0 qtid invalid with %s", atype);
- }
- else if (strcaseeq(atype, "START"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "DONE"))
- {
- if (!cr->used)
- {
- /* "no results returned by lwdnsq" should not happen */
- cr->cont_fn(cr
- , cr->gateways_from_dns == NULL
-#ifdef USE_KEYRR
- && cr->keys_from_dns == NULL
-#endif /* USE_KEYRR */
- ? "no results returned by lwdnsq" : NULL);
- cr->used = TRUE;
- }
- reset_globals();
- release_adns_continuation(cr);
- adns_in_flight--;
- }
- else if (strcaseeq(atype, "RETRY"))
- {
- if (!cr->used)
- {
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "FATAL"))
- {
- if (!cr->used)
- {
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "DNSSEC"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "NAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "TXT"))
- {
- char *end = rest + strlen(rest);
- err_t txt_ugh;
-
- if (*rest == '"' && end[-1] == '"')
- {
- /* strip those pesky quotes */
- rest++;
- *--end = '\0';
- }
-
- txt_ugh = process_txt_rr_body(rest
- , TRUE
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
-
- if (txt_ugh != NULL)
- {
- DBG(DBG_DNS,
- DBG_log("error processing TXT resource record (%s) while processing: %s"
- , txt_ugh, rest));
- cr->cont_fn(cr, txt_ugh);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "SIG"))
- {
- /* record the SIG records for posterity */
- if (cr->last_info != NULL)
- {
- pfreeany(cr->last_info->dns_sig);
- cr->last_info->dns_sig = clone_str(rest, "sigrecord");
- }
- }
- else if (strcaseeq(atype, "A"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "AAAA"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAMEFROM"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "PTR"))
- {
- /* ignore */
- }
-#ifdef USE_KEYRR
- else if (strcaseeq(atype, "KEY"))
- {
- err_t key_ugh = process_lwdnsq_key(rest
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
-
- if (key_ugh != NULL)
- {
- DBG(DBG_DNS,
- DBG_log("error processing KEY resource record (%s) while processing: %s"
- , key_ugh, rest));
- cr->cont_fn(cr, key_ugh);
- cr->used = TRUE;
- }
- }
-#endif /* USE_KEYRR */
- else
- {
- ugh = "lwdnsq: unrecognized type";
- }
- return ugh;
-}
-#endif /* USE_LWRES */
-
-static void
-recover_adns_die(void)
-{
- struct adns_continuation *cr = NULL;
-
- adns_pid = 0;
- if(adns_restart_count < ADNS_RESTART_MAX) {
- adns_restart_count++;
-
- /* next DNS query will restart it */
-
- /* we have to walk the list of the outstanding requests,
- * and redo them!
- */
-
- cr = continuations;
-
- /* find the head of the list */
- if(continuations != NULL) {
- for (; cr->previous != NULL; cr = cr->previous);
- }
-
- next_query = cr;
-
- if(next_query != NULL) {
- unsent_ADNS_queries = TRUE;
- }
- }
-}
-
-void reset_adns_restart_count(void)
-{
- adns_restart_count=0;
-}
-
-void
-handle_adns_answer(void)
-{
- /* These are retained across calls to handle_adns_answer. */
- static size_t buflen = 0; /* bytes in answer buffer */
-#ifndef USE_LWRES
- static struct adns_answer buf;
-#else /* USE_LWRES */
- static char buf[LWDNSQ_RESULT_LEN_MAX];
- static char buf_copy[LWDNSQ_RESULT_LEN_MAX];
-#endif /* USE_LWRES */
-
- ssize_t n;
-
- passert(buflen < sizeof(buf));
- n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);
-
- if (n < 0)
- {
- if (errno != EINTR)
- {
- log_errno((e, "error reading answer from adns"));
- /* ??? how can we recover? */
- }
- n = 0; /* now n reflects amount read */
- }
- else if (n == 0)
- {
- /* EOF */
- if (adns_in_flight != 0)
- {
- plog("EOF from ADNS with %d queries outstanding (restarts %d)"
- , adns_in_flight, adns_restart_count);
- recover_adns_die();
- }
- if (buflen != 0)
- {
- plog("EOF from ADNS with %lu bytes of a partial answer outstanding"
- "(restarts %d)"
- , (unsigned long)buflen
- , adns_restart_count);
- recover_adns_die();
- }
- stop_adns();
- return;
- }
- else
- {
- passert(adns_in_flight > 0);
- }
-
- buflen += n;
-#ifndef USE_LWRES
- while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
- {
- /* we've got a tasty answer -- process it */
- err_t ugh;
- struct adns_continuation *cr = continuation_for_qtid(buf.serial); /* assume it works */
- const char *typename = rr_typename(cr->query.type);
- const char *name_buf = cr->query.name_buf;
-
-#ifdef USE_KEYRR
- passert(cr->keys_from_dns == NULL);
-#endif /* USE_KEYRR */
- passert(cr->gateways_from_dns == NULL);
- adns_in_flight--;
- if (buf.result == -1)
- {
- /* newer resolvers support statp->res_h_errno as well as h_errno.
- * That might be better, but older resolvers don't.
- * See resolver(3), if you have it.
- * The undocumented(!) h_errno values are defined in
- * /usr/include/netdb.h.
- */
- switch (buf.h_errno_val)
- {
- case NO_DATA:
- ugh = builddiag("no %s record for %s", typename, name_buf);
- break;
- case HOST_NOT_FOUND:
- ugh = builddiag("no host %s for %s record", name_buf, typename);
- break;
- default:
- ugh = builddiag("failure querying DNS for %s of %s: %s"
- , typename, name_buf, hstrerror(buf.h_errno_val));
- break;
- }
- }
- else if (buf.result > (int) sizeof(buf.ans))
- {
- ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"
- , (long)buf.result);
- }
- else
- {
- ugh = process_dns_answer(cr, buf.ans, buf.result);
- if (ugh != NULL)
- ugh = builddiag("failure processing %s record of DNS answer for %s: %s"
- , typename, name_buf, ugh);
- }
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,
- DBG_log(BLANK_FORMAT);
- if (ugh == NULL)
- DBG_log("asynch DNS answer %lu for %s of %s"
- , cr->query.serial, typename, name_buf);
- else
- DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);
- );
-
- passert(GLOBALS_ARE_RESET());
- cr->cont_fn(cr, ugh);
- reset_globals();
- release_adns_continuation(cr);
-
- /* shift out answer that we've consumed */
- buflen -= buf.len;
- memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
- }
-#else /* USE_LWRES */
- for (;;)
- {
- err_t ugh;
- char *nlp = memchr(buf, '\n', buflen);
-
- if (nlp == NULL)
- break;
-
- /* we've got a line */
- *nlp++ = '\0';
-
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS
- , DBG_log("lwdns: %s", buf));
-
- /* process lwdnsq_answer may modify buf, so make a copy. */
- buf_copy[0]='\0';
- strncat(buf_copy, buf, sizeof(buf_copy));
-
- ugh = process_lwdnsq_answer(buf_copy);
- if (ugh != NULL)
- plog("failure processing lwdnsq output: %s; record: %s"
- , ugh, buf);
-
- passert(GLOBALS_ARE_RESET());
- reset_globals();
-
- /* shift out answer that we've consumed */
- buflen -= nlp - buf;
- memmove(buf, nlp, buflen);
- }
-#endif /* USE_LWRES */
-}
diff --git a/programs/pluto/dnskey.h b/programs/pluto/dnskey.h
deleted file mode 100644
index 0b9f0ee33..000000000
--- a/programs/pluto/dnskey.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Find public key in DNS
- * Copyright (C) 2000-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: dnskey.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-extern int
- adns_qfd, /* file descriptor for sending queries to adns */
- adns_afd; /* file descriptor for receiving answers from adns */
-extern const char *pluto_adns_option; /* path from --pluto_adns */
-extern void init_adns(void);
-extern void stop_adns(void);
-extern void handle_adns_answer(void);
-
-extern bool unsent_ADNS_queries;
-extern void send_unsent_ADNS_queries(void);
-
-/* (common prefix of) stuff remembered between async query and answer.
- * Filled in by start_adns_query.
- * Freed by call to release_adns_continuation.
- */
-
-struct adns_continuation; /* forward declaration (not far!) */
-
-typedef void (*cont_fn_t)(struct adns_continuation *cr, err_t ugh);
-
-struct adns_continuation {
- unsigned long qtid; /* query transaction id number */
- int type; /* T_TXT or T_KEY, selecting rr type of interest */
- cont_fn_t cont_fn; /* function to carry on suspended work */
- struct id id; /* subject of query */
- bool sgw_specified;
- struct id sgw_id; /* peer, if constrained */
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
- struct gw_info *gateways_from_dns; /* answer, if looking for our TXT rrs */
-#ifdef USE_KEYRR
- struct pubkey_list *keys_from_dns; /* answer, if looking for KEY rrs */
-#endif
- struct adns_continuation *previous, *next;
- struct pubkey *last_info; /* the last structure we accumulated */
-#ifdef USE_LWRES
- bool used; /* have we called the cont_fn yet? */
- struct {
- u_char name_buf[NS_MAXDNAME + 2];
- } query;
-#else /* ! USE_LWRES */
- struct adns_query query;
-#endif /* ! USE_LWRES */
-};
-
-extern err_t start_adns_query(const struct id *id /* domain to query */
- , const struct id *sgw_id /* if non-null, any accepted gw_info must match */
- , int type /* T_TXT or T_KEY, selecting rr type of interest */
- , cont_fn_t cont_fn /* continuation function */
- , struct adns_continuation *cr);
-
-
-/* Gateway info gleaned from reverse DNS of client */
-struct gw_info {
- unsigned refcnt; /* reference counted! */
- unsigned pref; /* preference: lower is better */
-#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
- struct id client_id; /* id of client of peer */
- struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
- bool gw_key_present;
- struct pubkey *key;
- struct gw_info *next;
-};
-
-extern void gw_addref(struct gw_info *gw)
- , gw_delref(struct gw_info **gwp);
-
-extern void reset_adns_restart_count(void);
-
diff --git a/programs/pluto/dsa.c b/programs/pluto/dsa.c
deleted file mode 100644
index c5982fbf4..000000000
--- a/programs/pluto/dsa.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/* dsa.c - DSA signature scheme
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <config.h> */
-#endif /* !PLUTO */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PLUTO
-/* #include <assert.h> */
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif
-
-#include "dsa.h"
-
-typedef struct {
- MPI p; /* prime */
- MPI q; /* group order */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
-} DSA_public_key;
-
-
-typedef struct {
- MPI p; /* prime */
- MPI q; /* group order */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
- MPI x; /* secret exponent */
-} DSA_secret_key;
-
-
-static MPI gen_k( MPI q );
-static void test_keys( DSA_secret_key *sk, unsigned qbits );
-static int check_secret_key( DSA_secret_key *sk );
-static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
-static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
-static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-/****************
- * Generate a random secret exponent k less than q
- */
-static MPI
-gen_k( MPI q )
-{
- MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
- unsigned int nbits = mpi_get_nbits(q);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
-
- if( DBG_CIPHER )
- log_debug("choosing a random k ");
- for(;;) {
- if( DBG_CIPHER )
- progress('.');
-
- if( !rndbuf || nbits < 32 ) {
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 1, 1 );
- }
- else { /* change only some of the higher bits */
- /* we could imporove this by directly requesting more memory
- * at the first call to get_random_bits() and use this the here
- * maybe it is easier to do this directly in random.c */
- char *pp = get_random_bits( 32, 1, 1 );
- memcpy( rndbuf,pp, 4 );
- m_free(pp);
- }
- mpi_set_buffer( k, rndbuf, nbytes, 0 );
- if( mpi_test_bit( k, nbits-1 ) )
- mpi_set_highbit( k, nbits-1 );
- else {
- mpi_set_highbit( k, nbits-1 );
- mpi_clear_bit( k, nbits-1 );
- }
-
- if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
- if( DBG_CIPHER )
- progress('+');
- continue; /* no */
- }
- if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
- if( DBG_CIPHER )
- progress('-');
- continue; /* no */
- }
- break; /* okay */
- }
- m_free(rndbuf);
- if( DBG_CIPHER )
- progress('\n');
-
- return k;
-}
-
-
-static void
-test_keys( DSA_secret_key *sk, unsigned qbits )
-{
- DSA_public_key pk;
- MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
- MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
- MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
-
- pk.p = sk->p;
- pk.q = sk->q;
- pk.g = sk->g;
- pk.y = sk->y;
- /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
- { char *p = get_random_bits( qbits, 0, 0 );
- mpi_set_buffer( test, p, (qbits+7)/8, 0 );
- m_free(p);
- }
-
- sign( out1_a, out1_b, test, sk );
- if( !verify( out1_a, out1_b, test, &pk ) )
- log_fatal("DSA:: sign, verify failed\n");
-
- mpi_free( test );
- mpi_free( out1_a );
- mpi_free( out1_b );
-}
-
-
-
-/****************
- * Generate a DSA key pair with a key of size NBITS
- * Returns: 2 structures filled with all needed values
- * and an array with the n-1 factors of (p-1)
- */
-static void
-generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
-{
- MPI p; /* the prime */
- MPI q; /* the 160 bit prime factor */
- MPI g; /* the generator */
- MPI y; /* g^x mod p */
- MPI x; /* the secret exponent */
- MPI h, e; /* helper */
- unsigned qbits;
- byte *rndbuf;
-
- assert( nbits >= 512 && nbits <= 1024 );
-
- qbits = 160;
- p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
- /* get q out of factors */
- q = mpi_copy((*ret_factors)[0]);
- if( mpi_get_nbits(q) != qbits )
- BUG();
-
- /* find a generator g (h and e are helpers)*/
- /* e = (p-1)/q */
- e = mpi_alloc( mpi_get_nlimbs(p) );
- mpi_sub_ui( e, p, 1 );
- mpi_fdiv_q( e, e, q );
- g = mpi_alloc( mpi_get_nlimbs(p) );
- h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
- do {
- mpi_add_ui( h, h, 1 );
- /* g = h^e mod p */
- mpi_powm( g, h, e, p );
- } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
-
- /* select a random number which has these properties:
- * 0 < x < q-1
- * This must be a very good random number because this
- * is the secret part. */
- if( DBG_CIPHER )
- log_debug("choosing a random x ");
- assert( qbits >= 160 );
- x = mpi_alloc_secure( mpi_get_nlimbs(q) );
- mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
- rndbuf = NULL;
- do {
- if( DBG_CIPHER )
- progress('.');
- if( !rndbuf )
- rndbuf = get_random_bits( qbits, 2, 1 );
- else { /* change only some of the higher bits (= 2 bytes)*/
- char *r = get_random_bits( 16, 2, 1 );
- memcpy(rndbuf, r, 16/8 );
- m_free(r);
- }
- mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
- mpi_clear_highbit( x, qbits+1 );
- } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
- m_free(rndbuf);
- mpi_free( e );
- mpi_free( h );
-
- /* y = g^x mod p */
- y = mpi_alloc( mpi_get_nlimbs(p) );
- mpi_powm( y, g, x, p );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump("dsa p= ", p );
- log_mpidump("dsa q= ", q );
- log_mpidump("dsa g= ", g );
- log_mpidump("dsa y= ", y );
- log_mpidump("dsa x= ", x );
- }
-
- /* copy the stuff to the key structures */
- sk->p = p;
- sk->q = q;
- sk->g = g;
- sk->y = y;
- sk->x = x;
-
- /* now we can test our keys (this should never fail!) */
- test_keys( sk, qbits );
-}
-
-
-
-/****************
- * Test whether the secret key is valid.
- * Returns: if this is a valid key.
- */
-static int
-check_secret_key( DSA_secret_key *sk )
-{
- int rc;
- MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
- mpi_powm( y, sk->g, sk->x, sk->p );
- rc = !mpi_cmp( y, sk->y );
- mpi_free( y );
- return rc;
-}
-
-
-
-/****************
- * Make a DSA signature from HASH and put it into r and s.
- */
-
-static void
-sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
-{
- MPI k;
- MPI kinv;
- MPI tmp;
-
- /* select a random k with 0 < k < q */
- k = gen_k( skey->q );
-
- /* r = (a^k mod p) mod q */
- mpi_powm( r, skey->g, k, skey->p );
- mpi_fdiv_r( r, r, skey->q );
-
- /* kinv = k^(-1) mod q */
- kinv = mpi_alloc( mpi_get_nlimbs(k) );
- mpi_invm(kinv, k, skey->q );
-
- /* s = (kinv * ( hash + x * r)) mod q */
- tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
- mpi_mul( tmp, skey->x, r );
- mpi_add( tmp, tmp, hash );
- mpi_mulm( s , kinv, tmp, skey->q );
-
- mpi_free(k);
- mpi_free(kinv);
- mpi_free(tmp);
-}
-
-
-/****************
- * Returns true if the signature composed from R and S is valid.
- */
-static int
-verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
-{
- int rc;
- MPI w, u1, u2, v;
- MPI base[3];
- MPI exp[3];
-
-
- if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
- return 0; /* assertion 0 < r < q failed */
- if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
- return 0; /* assertion 0 < s < q failed */
-
- w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
-
- /* w = s^(-1) mod q */
- mpi_invm( w, s, pkey->q );
-
- /* u1 = (hash * w) mod q */
- mpi_mulm( u1, hash, w, pkey->q );
-
- /* u2 = r * w mod q */
- mpi_mulm( u2, r, w, pkey->q );
-
- /* v = g^u1 * y^u2 mod p mod q */
- base[0] = pkey->g; exp[0] = u1;
- base[1] = pkey->y; exp[1] = u2;
- base[2] = NULL; exp[2] = NULL;
- mpi_mulpowm( v, base, exp, pkey->p );
- mpi_fdiv_r( v, v, pkey->q );
-
- rc = !mpi_cmp( v, r );
-
- mpi_free(w);
- mpi_free(u1);
- mpi_free(u2);
- mpi_free(v);
- return rc;
-}
-
-
-/*********************************************
- ************** interface ******************
- *********************************************/
-
-int
-dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
-
- generate( &sk, nbits, retfactors );
- skey[0] = sk.p;
- skey[1] = sk.q;
- skey[2] = sk.g;
- skey[3] = sk.y;
- skey[4] = sk.x;
- return 0;
-}
-
-
-int
-dsa_check_secret_key( int algo, MPI *skey )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- if( !check_secret_key( &sk ) )
- return G10ERR_BAD_SECKEY;
-
- return 0;
-}
-
-
-
-int
-dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- sign( resarr[0], resarr[1], data, &sk );
- return 0;
-}
-
-int
-dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
-{
- DSA_public_key pk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1] || !hash
- || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.q = pkey[1];
- pk.g = pkey[2];
- pk.y = pkey[3];
- if( !verify( data[0], data[1], hash, &pk ) )
- return G10ERR_BAD_SIGN;
- return 0;
-}
-
-
-
-unsigned
-dsa_get_nbits( int algo, MPI *pkey )
-{
- if( algo != PUBKEY_ALGO_DSA )
- return 0;
- return mpi_get_nbits( pkey[0] );
-}
-
-
-/****************
- * Return some information about the algorithm. We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- * the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- * 1 set : allows encryption
- */
-const char *
-dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
- int *use )
-{
- *npkey = 4;
- *nskey = 5;
- *nenc = 0;
- *nsig = 2;
-
- switch( algo ) {
- case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
- default: *use = 0; return NULL;
- }
-}
-
-
diff --git a/programs/pluto/dsa.h b/programs/pluto/dsa.h
deleted file mode 100644
index 1456d65b6..000000000
--- a/programs/pluto/dsa.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* dsa.h - DSA signature scheme
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_DSA_H
-#define G10_DSA_H
-
-int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
-int dsa_check_secret_key( int algo, MPI *skey );
-int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI), void *opaquev );
-unsigned dsa_get_nbits( int algo, MPI *pkey );
-const char *dsa_get_info( int algo, int *npkey, int *nskey,
- int *nenc, int *nsig, int *use );
-
-#endif /*G10_DSA_H*/
diff --git a/programs/pluto/elgamal.c b/programs/pluto/elgamal.c
deleted file mode 100644
index 0c099bb90..000000000
--- a/programs/pluto/elgamal.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/* elgamal.c - ElGamal Public Key encryption
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * For a description of the algorithm, see:
- * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- * ISBN 0-471-11709-9. Pages 476 ff.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <config.h> */
-#endif /* !PLUTO */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PLUTO
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif
-
-#include "elgamal.h"
-
-typedef struct {
- MPI p; /* prime */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
-} ELG_public_key;
-
-
-typedef struct {
- MPI p; /* prime */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
- MPI x; /* secret exponent */
-} ELG_secret_key;
-
-
-static void test_keys( ELG_secret_key *sk, unsigned nbits );
-static MPI gen_k( MPI p );
-static void generate( ELG_secret_key *sk, unsigned nbits, MPI **factors );
-static int check_secret_key( ELG_secret_key *sk );
-static void encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey );
-static void decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey );
-static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
-static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
-
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-static void
-test_keys( ELG_secret_key *sk, unsigned nbits )
-{
- ELG_public_key pk;
- MPI test = mpi_alloc( 0 );
- MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
- MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
- MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
-
- pk.p = sk->p;
- pk.g = sk->g;
- pk.y = sk->y;
-
- /*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
- { char *p = get_random_bits( nbits, 0, 0 );
- mpi_set_buffer( test, p, (nbits+7)/8, 0 );
- m_free(p);
- }
-
- encrypt( out1_a, out1_b, test, &pk );
- decrypt( out2, out1_a, out1_b, sk );
- if( mpi_cmp( test, out2 ) )
- log_fatal("ElGamal operation: encrypt, decrypt failed\n");
-
- sign( out1_a, out1_b, test, sk );
- if( !verify( out1_a, out1_b, test, &pk ) )
- log_fatal("ElGamal operation: sign, verify failed\n");
-
- mpi_free( test );
- mpi_free( out1_a );
- mpi_free( out1_b );
- mpi_free( out2 );
-}
-
-
-/****************
- * generate a random secret exponent k from prime p, so
- * that k is relatively prime to p-1
- */
-static MPI
-gen_k( MPI p )
-{
- MPI k = mpi_alloc_secure( 0 );
- MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
- MPI p_1 = mpi_copy(p);
- unsigned int nbits = mpi_get_nbits(p);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
-
- if( DBG_CIPHER )
- log_debug("choosing a random k ");
- mpi_sub_ui( p_1, p, 1);
- for(;;) {
- if( DBG_CIPHER )
- progress('.');
- if( !rndbuf || nbits < 32 ) {
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 1, 1 );
- }
- else { /* change only some of the higher bits */
- /* we could imporove this by directly requesting more memory
- * at the first call to get_random_bits() and use this the here
- * maybe it is easier to do this directly in random.c */
- char *pp = get_random_bits( 32, 1, 1 );
- memcpy( rndbuf,pp, 4 );
- m_free(pp);
- }
- mpi_set_buffer( k, rndbuf, nbytes, 0 );
-
- for(;;) {
- /* make sure that the number is of the exact lenght */
- if( mpi_test_bit( k, nbits-1 ) )
- mpi_set_highbit( k, nbits-1 );
- else {
- mpi_set_highbit( k, nbits-1 );
- mpi_clear_bit( k, nbits-1 );
- }
- if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
- if( DBG_CIPHER )
- progress('+');
- break; /* no */
- }
- if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
- if( DBG_CIPHER )
- progress('-');
- break; /* no */
- }
- if( mpi_gcd( temp, k, p_1 ) )
- goto found; /* okay, k is relatively prime to (p-1) */
- mpi_add_ui( k, k, 1 );
- }
- }
- found:
- m_free(rndbuf);
- if( DBG_CIPHER )
- progress('\n');
- mpi_free(p_1);
- mpi_free(temp);
-
- return k;
-}
-
-/****************
- * Generate a key pair with a key of size NBITS
- * Returns: 2 structures filles with all needed values
- * and an array with n-1 factors of (p-1)
- */
-static void
-generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
-{
- MPI p; /* the prime */
- MPI p_min1;
- MPI g;
- MPI x; /* the secret exponent */
- MPI y;
- MPI temp;
- unsigned qbits;
- byte *rndbuf;
-
- p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
- temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
- if( nbits < 512 )
- qbits = 120;
- else if( nbits <= 1024 )
- qbits = 160;
- else if( nbits <= 2048 )
- qbits = 200;
- else
- qbits = 240;
- g = mpi_alloc(1);
- p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
- mpi_sub_ui(p_min1, p, 1);
-
-
- /* select a random number which has these properties:
- * 0 < x < p-1
- * This must be a very good random number because this is the
- * secret part. The prime is public and may be shared anyway,
- * so a random generator level of 1 is used for the prime.
- */
- x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
- if( DBG_CIPHER )
- log_debug("choosing a random x ");
- rndbuf = NULL;
- do {
- if( DBG_CIPHER )
- progress('.');
- if( rndbuf ) { /* change only some of the higher bits */
- if( nbits < 16 ) {/* should never happen ... */
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 2, 1 );
- }
- else {
- char *r = get_random_bits( 16, 2, 1 );
- memcpy(rndbuf, r, 16/8 );
- m_free(r);
- }
- }
- else
- rndbuf = get_random_bits( nbits, 2, 1 );
- mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
- mpi_clear_highbit( x, nbits+1 );
- } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
- m_free(rndbuf);
-
- y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
- mpi_powm( y, g, x, p );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump("elg p= ", p );
- log_mpidump("elg g= ", g );
- log_mpidump("elg y= ", y );
- log_mpidump("elg x= ", x );
- }
-
- /* copy the stuff to the key structures */
- sk->p = p;
- sk->g = g;
- sk->y = y;
- sk->x = x;
-
- /* now we can test our keys (this should never fail!) */
- test_keys( sk, nbits - 64 );
-
- mpi_free( p_min1 );
- mpi_free( temp );
-}
-
-
-/****************
- * Test whether the secret key is valid.
- * Returns: if this is a valid key.
- */
-static int
-check_secret_key( ELG_secret_key *sk )
-{
- int rc;
- MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
- mpi_powm( y, sk->g, sk->x, sk->p );
- rc = !mpi_cmp( y, sk->y );
- mpi_free( y );
- return rc;
-}
-
-
-static void
-encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
-{
- MPI k;
-
- /* Note: maybe we should change the interface, so that it
- * is possible to check that input is < p and return an
- * error code.
- */
-
- k = gen_k( pkey->p );
- mpi_powm( a, pkey->g, k, pkey->p );
- /* b = (y^k * input) mod p
- * = ((y^k mod p) * (input mod p)) mod p
- * and because input is < p
- * = ((y^k mod p) * input) mod p
- */
- mpi_powm( b, pkey->y, k, pkey->p );
- mpi_mulm( b, b, input, pkey->p );
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg encrypted y= ", pkey->y);
- log_mpidump("elg encrypted p= ", pkey->p);
- log_mpidump("elg encrypted k= ", k);
- log_mpidump("elg encrypted M= ", input);
- log_mpidump("elg encrypted a= ", a);
- log_mpidump("elg encrypted b= ", b);
- }
- #endif
- mpi_free(k);
-}
-
-
-
-
-static void
-decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
-{
- MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
-
- /* output = b/(a^x) mod p */
-
- mpi_powm( t1, a, skey->x, skey->p );
- mpi_invm( t1, t1, skey->p );
- mpi_mulm( output, b, t1, skey->p );
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg decrypted x= ", skey->x);
- log_mpidump("elg decrypted p= ", skey->p);
- log_mpidump("elg decrypted a= ", a);
- log_mpidump("elg decrypted b= ", b);
- log_mpidump("elg decrypted M= ", output);
- }
- #endif
- mpi_free(t1);
-}
-
-
-/****************
- * Make an Elgamal signature out of INPUT
- */
-
-static void
-sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
-{
- MPI k;
- MPI t = mpi_alloc( mpi_get_nlimbs(a) );
- MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
- MPI p_1 = mpi_copy(skey->p);
-
- /*
- * b = (t * inv) mod (p-1)
- * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
- * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
- *
- */
- mpi_sub_ui(p_1, p_1, 1);
- k = gen_k( skey->p );
- mpi_powm( a, skey->g, k, skey->p );
- mpi_mul(t, skey->x, a );
- mpi_subm(t, input, t, p_1 );
- while( mpi_is_neg(t) )
- mpi_add(t, t, p_1);
- mpi_invm(inv, k, p_1 );
- mpi_mulm(b, t, inv, p_1 );
-
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg sign p= ", skey->p);
- log_mpidump("elg sign g= ", skey->g);
- log_mpidump("elg sign y= ", skey->y);
- log_mpidump("elg sign x= ", skey->x);
- log_mpidump("elg sign k= ", k);
- log_mpidump("elg sign M= ", input);
- log_mpidump("elg sign a= ", a);
- log_mpidump("elg sign b= ", b);
- }
- #endif
- mpi_free(k);
- mpi_free(t);
- mpi_free(inv);
- mpi_free(p_1);
-}
-
-
-/****************
- * Returns true if the signature composed of A and B is valid.
- */
-static int
-verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
-{
- int rc;
- MPI t1;
- MPI t2;
- MPI base[4];
- MPI exp[4];
-
- if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
- return 0; /* assertion 0 < a < p failed */
-
- t1 = mpi_alloc( mpi_get_nlimbs(a) );
- t2 = mpi_alloc( mpi_get_nlimbs(a) );
-
- #if 0
- /* t1 = (y^a mod p) * (a^b mod p) mod p */
- mpi_powm( t1, pkey->y, a, pkey->p );
- mpi_powm( t2, a, b, pkey->p );
- mpi_mulm( t1, t1, t2, pkey->p );
-
- /* t2 = g ^ input mod p */
- mpi_powm( t2, pkey->g, input, pkey->p );
-
- rc = !mpi_cmp( t1, t2 );
- #elif 0
- /* t1 = (y^a mod p) * (a^b mod p) mod p */
- base[0] = pkey->y; exp[0] = a;
- base[1] = a; exp[1] = b;
- base[2] = NULL; exp[2] = NULL;
- mpi_mulpowm( t1, base, exp, pkey->p );
-
- /* t2 = g ^ input mod p */
- mpi_powm( t2, pkey->g, input, pkey->p );
-
- rc = !mpi_cmp( t1, t2 );
- #else
- /* t1 = g ^ - input * y ^ a * a ^ b mod p */
- mpi_invm(t2, pkey->g, pkey->p );
- base[0] = t2 ; exp[0] = input;
- base[1] = pkey->y; exp[1] = a;
- base[2] = a; exp[2] = b;
- base[3] = NULL; exp[3] = NULL;
- mpi_mulpowm( t1, base, exp, pkey->p );
- rc = !mpi_cmp_ui( t1, 1 );
-
- #endif
-
- mpi_free(t1);
- mpi_free(t2);
- return rc;
-}
-
-/*********************************************
- ************** interface ******************
- *********************************************/
-
-int
-elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
-
- generate( &sk, nbits, retfactors );
- skey[0] = sk.p;
- skey[1] = sk.g;
- skey[2] = sk.y;
- skey[3] = sk.x;
- return 0;
-}
-
-
-int
-elg_check_secret_key( int algo, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- if( !check_secret_key( &sk ) )
- return G10ERR_BAD_SECKEY;
-
- return 0;
-}
-
-
-
-int
-elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
-{
- ELG_public_key pk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.g = pkey[1];
- pk.y = pkey[2];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
- encrypt( resarr[0], resarr[1], data, &pk );
- return 0;
-}
-
-int
-elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1]
- || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- *result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
- decrypt( *result, data[0], data[1], &sk );
- return 0;
-}
-
-int
-elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- sign( resarr[0], resarr[1], data, &sk );
- return 0;
-}
-
-int
-elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
-{
- ELG_public_key pk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1] || !hash
- || !pkey[0] || !pkey[1] || !pkey[2] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.g = pkey[1];
- pk.y = pkey[2];
- if( !verify( data[0], data[1], hash, &pk ) )
- return G10ERR_BAD_SIGN;
- return 0;
-}
-
-
-
-unsigned
-elg_get_nbits( int algo, MPI *pkey )
-{
- if( !is_ELGAMAL(algo) )
- return 0;
- return mpi_get_nbits( pkey[0] );
-}
-
-
-/****************
- * Return some information about the algorithm. We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- * the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- * 1 set : allows encryption
- * NOTE: This function allows signing also for ELG-E, which is not
- * okay but a bad hack to allow to work with old gpg keys. The real check
- * is done in the gnupg ocde depending on the packet version.
- */
-const char *
-elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
- int *use )
-{
- *npkey = 3;
- *nskey = 4;
- *nenc = 2;
- *nsig = 2;
-
- switch( algo ) {
- case PUBKEY_ALGO_ELGAMAL:
- *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
- return "ELG";
- case PUBKEY_ALGO_ELGAMAL_E:
- *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
- return "ELG-E";
- default: *use = 0; return NULL;
- }
-}
-
-
diff --git a/programs/pluto/elgamal.h b/programs/pluto/elgamal.h
deleted file mode 100644
index f104c2a52..000000000
--- a/programs/pluto/elgamal.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* elgamal.h
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_ELGAMAL_H
-#define G10_ELGAMAL_H
-
-int elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
-int elg_check_secret_key( int algo, MPI *skey );
-int elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
-int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
-int elg_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI), void *opaquev );
-unsigned elg_get_nbits( int algo, MPI *pkey );
-const char *elg_get_info( int algo, int *npkey, int *nskey,
- int *nenc, int *nsig, int *use );
-
-
-#endif /*G10_ELGAMAL_H*/
diff --git a/programs/pluto/fetch.c b/programs/pluto/fetch.c
deleted file mode 100644
index 4bfb6031b..000000000
--- a/programs/pluto/fetch.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-/* Dynamic fetching of X.509 CRLs
- * Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: fetch.c,v 1.12 2006/05/16 14:19:27 as Exp $
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-#include <string.h>
-
-#ifdef THREADS
-#include <pthread.h>
-#endif
-
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif
-
-#include <freeswan.h>
-
-#ifdef LDAP_VER
-#include <ldap.h>
-#endif
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "id.h"
-#include "asn1.h"
-#include "pem.h"
-#include "x509.h"
-#include "ca.h"
-#include "whack.h"
-#include "ocsp.h"
-#include "crl.h"
-#include "fetch.h"
-
-fetch_req_t empty_fetch_req = {
- NULL , /* next */
- 0 , /* installed */
- 0 , /* trials */
- { NULL, 0}, /* issuer */
- { NULL, 0}, /* authKeyID */
- { NULL, 0}, /* authKeySerialNumber */
- NULL /* distributionPoints */
-};
-
-/* chained list of crl fetch requests */
-static fetch_req_t *crl_fetch_reqs = NULL;
-
-/* chained list of ocsp fetch requests */
-static ocsp_location_t *ocsp_fetch_reqs = NULL;
-
-#ifdef THREADS
-static pthread_t thread;
-static pthread_mutex_t certs_and_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t authcert_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t crl_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ocsp_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ca_info_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t crl_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t ocsp_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t fetch_wake_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t fetch_wake_cond = PTHREAD_COND_INITIALIZER;
-
-/*
- * lock access to my certs and keys
- */
-void
-lock_certs_and_keys(const char *who)
-{
- pthread_mutex_lock(&certs_and_keys_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("certs and keys locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to my certs and keys
- */
-void
-unlock_certs_and_keys(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("certs and keys unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&certs_and_keys_mutex);
-}
-
-/*
- * lock access to the chained authcert list
- */
-void
-lock_authcert_list(const char *who)
-{
- pthread_mutex_lock(&authcert_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("authcert list locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the chained authcert list
- */
-void
-unlock_authcert_list(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("authcert list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&authcert_list_mutex);
-}
-
-/*
- * lock access to the chained crl list
- */
-void
-lock_crl_list(const char *who)
-{
- pthread_mutex_lock(&crl_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("crl list locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the chained crl list
- */
-void
-unlock_crl_list(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("crl list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&crl_list_mutex);
-}
-
-/*
- * lock access to the ocsp cache
- */
-extern void
-lock_ocsp_cache(const char *who)
-{
- pthread_mutex_lock(&ocsp_cache_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp cache locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the ocsp cache
- */
-extern void
-unlock_ocsp_cache(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp cache unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ocsp_cache_mutex);
-}
-
-/*
- * lock access to the ca info list
- */
-extern void
-lock_ca_info_list(const char *who)
-{
- pthread_mutex_lock(&ca_info_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ca info list locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the ca info list
- */
-extern void
-unlock_ca_info_list(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("ca info list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ca_info_list_mutex);
-}
-
-/*
- * lock access to the chained crl fetch request list
- */
-static void
-lock_crl_fetch_list(const char *who)
-{
- pthread_mutex_lock(&crl_fetch_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("crl fetch request list locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the chained crl fetch request list
- */
-static void
-unlock_crl_fetch_list(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("crl fetch request list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&crl_fetch_list_mutex);
-}
-
-/*
- * lock access to the chained ocsp fetch request list
- */
-static void
-lock_ocsp_fetch_list(const char *who)
-{
- pthread_mutex_lock(&ocsp_fetch_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp fetch request list locked by '%s'", who)
- )
-}
-
-/*
- * unlock access to the chained ocsp fetch request list
- */
-static void
-unlock_ocsp_fetch_list(const char *who)
-{
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp fetch request list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ocsp_fetch_list_mutex);
-}
-
-/*
- * wakes up the sleeping fetch thread
- */
-void
-wake_fetch_thread(const char *who)
-{
- if (crl_check_interval > 0)
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("fetch thread wake call by '%s'", who)
- )
- pthread_mutex_lock(&fetch_wake_mutex);
- pthread_cond_signal(&fetch_wake_cond);
- pthread_mutex_unlock(&fetch_wake_mutex);
- }
-}
-#else /* !THREADS */
-#define lock_crl_fetch_list(who) /* do nothing */
-#define unlock_crl_fetch_list(who) /* do nothing */
-#define lock_ocsp_fetch_list(who) /* do nothing */
-#define unlock_ocsp_fetch_list(who) /* do nothing */
-#endif /* !THREADS */
-
-/*
- * free the dynamic memory used to store fetch requests
- */
-static void
-free_fetch_request(fetch_req_t *req)
-{
- pfree(req->issuer.ptr);
- pfreeany(req->authKeySerialNumber.ptr);
- pfreeany(req->authKeyID.ptr);
- free_generalNames(req->distributionPoints, TRUE);
- pfree(req);
-}
-
-/* writes data into a dynamically resizeable chunk_t
- * needed for libcurl responses
- */
-size_t
-write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
-{
- size_t realsize = size * nmemb;
- chunk_t *mem = (chunk_t*)data;
-
- mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
- if (mem->ptr) {
- memcpy(&(mem->ptr[mem->len]), ptr, realsize);
- mem->len += realsize;
- }
- return realsize;
-}
-
-#ifdef THREADS
-/*
- * fetches a binary blob from a url with libcurl
- */
-static err_t
-fetch_curl(char *url, chunk_t *blob)
-{
-#ifdef LIBCURL
- char errorbuffer[CURL_ERROR_SIZE] = "";
- chunk_t response = empty_chunk;
- CURLcode res;
-
- /* get it with libcurl */
- CURL *curl = curl_easy_init();
-
- if (curl != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("Trying cURL '%s'", url)
- )
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
- {
- blob->len = response.len;
- blob->ptr = alloc_bytes(response.len, "curl blob");
- memcpy(blob->ptr, response.ptr, response.len);
- }
- else
- {
- plog("fetching uri (%s) with libcurl failed: %s", url, errorbuffer);
- }
- curl_easy_cleanup(curl);
- /* not using freeanychunk because of realloc (no leak detective) */
- curl_free(response.ptr);
- }
- return strlen(errorbuffer) > 0 ? "libcurl error" : NULL;
-#else /* !LIBCURL */
- return "warning: not compiled with libcurl support";
-#endif /* !LIBCURL */
-}
-
-#ifdef LDAP_VER
-/*
- * parses the result returned by an ldap query
- */
-static err_t
-parse_ldap_result(LDAP * ldap, LDAPMessage *result, chunk_t *blob)
-{
- err_t ugh = NULL;
-
- LDAPMessage * entry = ldap_first_entry(ldap, result);
-
- if (entry != NULL)
- {
- BerElement *ber = NULL;
- char *attr;
-
- attr = ldap_first_attribute(ldap, entry, &ber);
-
- if (attr != NULL)
- {
- struct berval **values = ldap_get_values_len(ldap, entry, attr);
-
- if (values != NULL)
- {
- if (values[0] != NULL)
- {
- blob->len = values[0]->bv_len;
- blob->ptr = alloc_bytes(blob->len, "ldap blob");
- memcpy(blob->ptr, values[0]->bv_val, blob->len);
- if (values[1] != NULL)
- {
- plog("warning: more than one value was fetched from LDAP URL");
- }
- }
- else
- {
- ugh = "no values in attribute";
- }
- ldap_value_free_len(values);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ldap_memfree(attr);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ber_free(ber, 0);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
- }
- return ugh;
-}
-
-/*
- * fetches a binary blob from an ldap url
- */
-static err_t
-fetch_ldap_url(char *url, chunk_t *blob)
-{
- LDAPURLDesc *lurl;
- err_t ugh = NULL;
- int rc;
-
- DBG(DBG_CONTROL,
- DBG_log("Trying LDAP URL '%s'", url)
- )
-
- rc = ldap_url_parse(url, &lurl);
-
- if (rc == LDAP_SUCCESS)
- {
- LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port);
-
- if (ldap != NULL)
- {
- int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3;
- struct timeval timeout;
-
- timeout.tv_sec = FETCH_CMD_TIMEOUT;
- timeout.tv_usec = 0;
- ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
- ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
-
- rc = ldap_simple_bind_s(ldap, NULL, NULL);
-
- if (rc == LDAP_SUCCESS)
- {
- LDAPMessage *result;
-
- timeout.tv_sec = FETCH_CMD_TIMEOUT;
- timeout.tv_usec = 0;
-
- rc = ldap_search_st(ldap, lurl->lud_dn
- , lurl->lud_scope
- , lurl->lud_filter
- , lurl->lud_attrs
- , 0, &timeout, &result);
-
- if (rc == LDAP_SUCCESS)
- {
- ugh = parse_ldap_result(ldap, result, blob);
- ldap_msgfree(result);
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- ldap_unbind_s(ldap);
- }
- else
- {
- ugh = "ldap init";
- }
- ldap_free_urldesc(lurl);
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- return ugh;
-}
-#else /* !LDAP_VER */
-static err_t
-fetch_ldap_url(char *url, chunk_t *blob)
-{
- return "LDAP URL fetching not activated in pluto source code";
-}
-#endif /* !LDAP_VER */
-
-/*
- * fetch an ASN.1 blob coded in PEM or DER format from a URL
- */
-static err_t
-fetch_asn1_blob(char *url, chunk_t *blob)
-{
- err_t ugh = NULL;
-
- if (strlen(url) >= 4 && strncasecmp(url, "ldap", 4) == 0)
- {
- ugh = fetch_ldap_url(url, blob);
- }
- else
- {
- ugh = fetch_curl(url, blob);
- }
- if (ugh != NULL)
- return ugh;
-
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" fetched blob coded in DER format")
- )
- }
- else
- {
- bool pgp = FALSE;
-
- ugh = pemtobin(blob, NULL, "", &pgp);
- if (ugh == NULL)
- {
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" fetched blob coded in PEM format")
- )
- }
- else
- {
- ugh = "blob coded in unknown format";
- pfree(blob->ptr);
- }
- }
- else
- {
- pfree(blob->ptr);
- }
- }
- return ugh;
-}
-
-/*
- * complete a distributionPoint URI with ca information
- */
-static char*
-complete_uri(chunk_t distPoint, const char *ldaphost)
-{
- char *uri;
- char *ptr = distPoint.ptr;
- size_t len = distPoint.len;
-
- char *symbol = memchr(ptr, ':', len);
-
- if (symbol != NULL)
- {
- size_t type_len = symbol - ptr;
-
- if (type_len >= 4 && strncasecmp(ptr, "ldap", 4) == 0)
- {
- ptr = symbol + 1;
- len -= (type_len + 1);
-
- if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
- {
- len -= 2;
- symbol = memchr(ptr, '/', len);
-
- if (symbol != NULL && symbol - ptr == 0 && ldaphost != NULL)
- {
- uri = alloc_bytes(distPoint.len+strlen(ldaphost)+1, "uri");
-
- /* insert the ldaphost into the uri */
- sprintf(uri, "%.*s%s%.*s"
- , (int)(distPoint.len - len), distPoint.ptr
- , ldaphost
- , (int)len, symbol);
- return uri;
- }
- }
- }
- }
-
- /* default action: copy distributionPoint without change */
- uri = alloc_bytes(distPoint.len+1, "uri");
- sprintf(uri, "%.*s", (int)distPoint.len, distPoint.ptr);
- return uri;
-}
-
-/*
- * try to fetch the crls defined by the fetch requests
- */
-static void
-fetch_crls(bool cache_crls)
-{
- fetch_req_t *req;
- fetch_req_t **reqp;
-
- lock_crl_fetch_list("fetch_crls");
- req = crl_fetch_reqs;
- reqp = &crl_fetch_reqs;
-
- while (req != NULL)
- {
- bool valid_crl = FALSE;
- chunk_t blob = empty_chunk;
- generalName_t *gn = req->distributionPoints;
- const char *ldaphost;
- ca_info_t *ca;
-
- lock_ca_info_list("fetch_crls");
-
- ca = get_ca_info(req->issuer, req->authKeySerialNumber, req->authKeyID);
- ldaphost = (ca == NULL)? NULL : ca->ldaphost;
-
- while (gn != NULL)
- {
- char *uri = complete_uri(gn->name, ldaphost);
-
- err_t ugh = fetch_asn1_blob(uri, &blob);
- pfree(uri);
-
- if (ugh != NULL)
- {
- plog("fetch failed: %s", ugh);
- }
- else
- {
- chunk_t crl_uri;
-
- clonetochunk(crl_uri, gn->name.ptr, gn->name.len, "crl uri");
- if (insert_crl(blob, crl_uri, cache_crls))
- {
- DBG(DBG_CONTROL,
- DBG_log("we have a valid crl")
- )
- valid_crl = TRUE;
- break;
- }
- }
- gn = gn->next;
- }
-
- unlock_ca_info_list("fetch_crls");
-
- if (valid_crl)
- {
- /* delete fetch request */
- fetch_req_t *req_free = req;
-
- req = req->next;
- *reqp = req;
- free_fetch_request(req_free);
- }
- else
- {
- /* try again next time */
- req->trials++;
- reqp = &req->next;
- req = req->next;
- }
- }
- unlock_crl_fetch_list("fetch_crls");
-}
-
-static void
-fetch_ocsp_status(ocsp_location_t* location)
-{
-#ifdef LIBCURL
- chunk_t request;
- chunk_t response = empty_chunk;
-
- CURL* curl;
- CURLcode res;
-
- request = build_ocsp_request(location);
-
- DBG(DBG_CONTROL,
- DBG_log("sending ocsp request to location '%.*s'"
- , (int)location->uri.len, location->uri.ptr)
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("OCSP request", request)
- )
-
- /* send via http post using libcurl */
- curl = curl_easy_init();
-
- if (curl != NULL)
- {
- char errorbuffer[CURL_ERROR_SIZE];
- struct curl_slist *headers = NULL;
- char* uri = alloc_bytes(location->uri.len+1, "ocsp uri");
-
- /* we need a null terminated string for curl */
- memcpy(uri, location->uri.ptr, location->uri.len);
- *(uri + location->uri.len) = '\0';
-
- /* set content type header */
- headers = curl_slist_append(headers, "Content-Type: application/ocsp-request");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl, CURLOPT_URL, uri);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_FILE, (void *)&response);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.ptr);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request.len);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("received ocsp response")
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("OCSP response:\n", response)
- )
- parse_ocsp(location, response);
- }
- else
- {
- plog("failed to fetch ocsp status from '%s': %s", uri, errorbuffer);
- }
- curl_slist_free_all(headers);
- curl_easy_cleanup(curl);
- pfree(uri);
- /* not using freeanychunk because of realloc (no leak detective) */
- curl_free(response.ptr);
- }
- freeanychunk(location->nonce);
- freeanychunk(request);
-
- /* increment the trial counter of the unresolved fetch requests */
- {
- ocsp_certinfo_t *certinfo = location->certinfo;
-
- while (certinfo != NULL)
- {
- certinfo->trials++;
- certinfo = certinfo->next;
- }
- }
- return;
-#else /* !LIBCURL */
- plog("ocsp error: pluto wasn't compiled with libcurl support");
-#endif /* !LIBCURL */
-}
-
-/*
- * try to fetch the necessary ocsp information
- */
-static void
-fetch_ocsp(void)
-{
- ocsp_location_t *location;
-
- lock_ocsp_fetch_list("fetch_ocsp");
- location = ocsp_fetch_reqs;
-
- /* fetch the ocps status for all locations */
- while (location != NULL)
- {
- if (location->certinfo != NULL)
- fetch_ocsp_status(location);
- location = location->next;
- }
-
- unlock_ocsp_fetch_list("fetch_ocsp");
-}
-
-static void*
-fetch_thread(void *arg)
-{
- struct timespec wait_interval;
-
- DBG(DBG_CONTROL,
- DBG_log("fetch thread started")
- )
-
- pthread_mutex_lock(&fetch_wake_mutex);
-
- while(1)
- {
- int status;
-
- wait_interval.tv_nsec = 0;
- wait_interval.tv_sec = time(NULL) + crl_check_interval;
-
- DBG(DBG_CONTROL,
- DBG_log("next regular crl check in %ld seconds", crl_check_interval)
- )
- status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex
- , &wait_interval);
-
- if (status == ETIMEDOUT)
- {
- DBG(DBG_CONTROL,
- DBG_log(" ");
- DBG_log("*time to check crls and the ocsp cache")
- )
- check_ocsp();
- check_crls();
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("fetch thread was woken up")
- )
- }
- fetch_ocsp();
- fetch_crls(cache_crls);
- }
-}
-#endif /* THREADS*/
-
-/*
- * initializes curl and starts the fetching thread
- */
-void
-init_fetch(void)
-{
- int status;
-
-#ifdef LIBCURL
- /* init curl */
- status = curl_global_init(CURL_GLOBAL_NOTHING);
- if (status != 0)
- {
- plog("libcurl could not be initialized, status = %d", status);
- }
-#endif /* LIBCURL */
-
- if (crl_check_interval > 0)
- {
-#ifdef THREADS
- status = pthread_create( &thread, NULL, fetch_thread, NULL);
- if (status != 0)
- {
- plog("fetching thread could not be started, status = %d", status);
- }
-#else /* !THREADS */
- plog("warning: not compiled with pthread support");
-#endif /* !THREADS */
- }
-}
-
-void
-free_crl_fetch(void)
-{
- lock_crl_fetch_list("free_crl_fetch");
-
- while (crl_fetch_reqs != NULL)
- {
- fetch_req_t *req = crl_fetch_reqs;
- crl_fetch_reqs = req->next;
- free_fetch_request(req);
- }
-
- unlock_crl_fetch_list("free_crl_fetch");
-
-#ifdef LIBCURL
- if (crl_check_interval > 0)
- {
- /* cleanup curl */
- curl_global_cleanup();
- }
-#endif /* LIBCURL */
-}
-
-/*
- * free the chained list of ocsp requests
- */
-void
-free_ocsp_fetch(void)
-{
- lock_ocsp_fetch_list("free_ocsp_fetch");
- free_ocsp_locations(&ocsp_fetch_reqs);
- unlock_ocsp_fetch_list("free_ocsp_fetch");
-}
-
-
-/*
- * add additional distribution points
- */
-void
-add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
-{
- while (newPoints != NULL)
- {
- /* skip empty distribution point */
- if (newPoints->name.len > 0)
- {
- bool add = TRUE;
- generalName_t *gn = *distributionPoints;
-
- while (gn != NULL)
- {
- if (gn->kind == newPoints->kind
- && gn->name.len == newPoints->name.len
- && memcmp(gn->name.ptr, newPoints->name.ptr, gn->name.len) == 0)
- {
- /* skip if the distribution point is already present */
- add = FALSE;
- break;
- }
- gn = gn->next;
- }
-
- if (add)
- {
- /* clone additional distribution point */
- gn = clone_thing(*newPoints, "generalName");
- clonetochunk(gn->name, newPoints->name.ptr, newPoints->name.len
- , "crl uri");
-
- /* insert additional CRL distribution point */
- gn->next = *distributionPoints;
- *distributionPoints = gn;
- }
- }
- newPoints = newPoints->next;
- }
-}
-
-fetch_req_t*
-build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
-, chunk_t authKeyID, const generalName_t *gn)
-{
- fetch_req_t *req = alloc_thing(fetch_req_t, "fetch request");
- *req = empty_fetch_req;
-
- /* note current time */
- req->installed = time(NULL);
-
- /* clone fields */
- clonetochunk(req->issuer, issuer.ptr, issuer.len, "issuer");
- if (authKeySerialNumber.ptr != NULL)
- {
- clonetochunk(req->authKeySerialNumber, authKeySerialNumber.ptr
- , authKeySerialNumber.len, "authKeySerialNumber");
- }
- if (authKeyID.ptr != NULL)
- {
- clonetochunk(req->authKeyID, authKeyID.ptr, authKeyID.len, "authKeyID");
- }
-
- /* copy distribution points */
- add_distribution_points(gn, &req->distributionPoints);
-
- return req;
-}
-
-/*
- * add a crl fetch request to the chained list
- */
-void
-add_crl_fetch_request(fetch_req_t *req)
-{
- fetch_req_t *r;
-
- lock_crl_fetch_list("add_crl_fetch_request");
- r = crl_fetch_reqs;
-
- while (r != NULL)
- {
- if ((req->authKeyID.ptr != NULL)? same_keyid(req->authKeyID, r->authKeyID)
- : (same_dn(req->issuer, r->issuer)
- && same_serial(req->authKeySerialNumber, r->authKeySerialNumber)))
- {
- /* there is already a fetch request */
- DBG(DBG_CONTROL,
- DBG_log("crl fetch request already exists")
- )
-
- /* there might be new distribution points */
- add_distribution_points(req->distributionPoints, &r->distributionPoints);
-
- unlock_crl_fetch_list("add_crl_fetch_request");
- free_fetch_request(req);
- return;
- }
- r = r->next;
- }
-
- /* insert new fetch request at the head of the queue */
- req->next = crl_fetch_reqs;
- crl_fetch_reqs = req;
-
- DBG(DBG_CONTROL,
- DBG_log("crl fetch request added")
- )
- unlock_crl_fetch_list("add_crl_fetch_request");
-}
-
-/*
- * add an ocsp fetch request to the chained list
- */
-void
-add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
-{
- ocsp_certinfo_t certinfo;
-
- certinfo.serialNumber = serialNumber;
-
- lock_ocsp_fetch_list("add_ocsp_fetch_request");
- add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE);
- unlock_ocsp_fetch_list("add_ocsp_fetch_request");
-}
-
-/*
- * list all distribution points
- */
-void
-list_distribution_points(const generalName_t *gn)
-{
- bool first_gn = TRUE;
-
- while (gn != NULL)
- {
- whack_log(RC_COMMENT, " %s '%.*s'", (first_gn)? "distPts: "
- :" ", (int)gn->name.len, gn->name.ptr);
- first_gn = FALSE;
- gn = gn->next;
- }
-}
-
-/*
- * list all fetch requests in the chained list
- */
-void
-list_crl_fetch_requests(bool utc)
-{
- fetch_req_t *req;
-
- lock_crl_fetch_list("list_crl_fetch_requests");
- req = crl_fetch_reqs;
-
- if (req != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of CRL fetch requests:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (req != NULL)
- {
- u_char buf[BUF_LEN];
-
- whack_log(RC_COMMENT, "%s, trials: %d"
- , timetoa(&req->installed, utc), req->trials);
- dntoa(buf, BUF_LEN, req->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- if (req->authKeyID.ptr != NULL)
- {
- datatot(req->authKeyID.ptr, req->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (req->authKeySerialNumber.ptr != NULL)
- {
- datatot(req->authKeySerialNumber.ptr, req->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
- list_distribution_points(req->distributionPoints);
- req = req->next;
- }
- unlock_crl_fetch_list("list_crl_fetch_requests");
-}
-
-void
-list_ocsp_fetch_requests(bool utc)
-{
- lock_ocsp_fetch_list("list_ocsp_fetch_requests");
- list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
- unlock_ocsp_fetch_list("list_ocsp_fetch_requests");
-
-}
diff --git a/programs/pluto/fetch.h b/programs/pluto/fetch.h
deleted file mode 100644
index 6303f37e4..000000000
--- a/programs/pluto/fetch.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Dynamic fetching of X.509 CRLs
- * Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: fetch.h,v 1.6 2005/11/25 10:08:00 as Exp $
- */
-
-#include "x509.h"
-
-#define FETCH_CMD_TIMEOUT 10 /* seconds */
-
-struct ocsp_location; /* forward declaration of ocsp_location defined in ocsp.h */
-
-typedef enum {
- FETCH_GET = 1,
- FETCH_POST = 2
-} fetch_request_t;
-
-typedef struct fetch_req fetch_req_t;
-
-struct fetch_req {
- fetch_req_t *next;
- time_t installed;
- int trials;
- chunk_t issuer;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- generalName_t *distributionPoints;
-};
-
-#ifdef THREADS
-extern void lock_crl_list(const char *who);
-extern void unlock_crl_list(const char *who);
-extern void lock_ocsp_cache(const char *who);
-extern void unlock_ocsp_cache(const char *who);
-extern void lock_ca_info_list(const char *who);
-extern void unlock_ca_info_list(const char *who);
-extern void lock_authcert_list(const char *who);
-extern void unlock_authcert_list(const char *who);
-extern void lock_certs_and_keys(const char *who);
-extern void unlock_certs_and_keys(const char *who);
-extern void wake_fetch_thread(const char *who);
-#else
-#define lock_crl_list(who) /* do nothing */
-#define unlock_crl_list(who) /* do nothing */
-#define lock_ocsp_cache(who) /* do nothing */
-#define unlock_ocsp_cache(who) /* do nothing */
-#define lock_ca_info_list(who) /* do nothing */
-#define unlock_ca_info_list(who) /* do nothing */
-#define lock_authcert_list(who) /* do nothing */
-#define unlock_authcert_list(who) /* do nothing */
-#define lock_certs_and_keys(who) /* do nothing */
-#define unlock_certs_and_keys(who) /* do nothing */
-#define wake_fetch_thread(who) /* do nothing */
-#endif
-extern void init_fetch(void);
-extern void free_crl_fetch(void);
-extern void free_ocsp_fetch(void);
-extern void add_distribution_points(const generalName_t *newPoints
- , generalName_t **distributionPoints);
-extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
- , chunk_t authKeyID, const generalName_t *gn);
-extern void add_crl_fetch_request(fetch_req_t *req);
-extern void add_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber);
-extern void list_distribution_points(const generalName_t *gn);
-extern void list_crl_fetch_requests(bool utc);
-extern void list_ocsp_fetch_requests(bool utc);
-extern size_t write_buffer(void *ptr, size_t size, size_t nmemb, void *data);
-
diff --git a/programs/pluto/foodgroups.c b/programs/pluto/foodgroups.c
deleted file mode 100644
index 52e32f0fb..000000000
--- a/programs/pluto/foodgroups.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* Implement policy groups-style control files (aka "foodgroups")
- * Copyright (C) 2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: foodgroups.c,v 1.2 2004/04/01 18:28:32 as Exp $
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "kernel.h"
-#include "lex.h"
-#include "log.h"
-#include "whack.h"
-
-
-/* Food group config files are found in directory fg_path */
-
-#ifndef POLICYGROUPSDIR
-#define POLICYGROUPSDIR "/etc/ipsec.d/policies"
-#endif
-
-const char *policygroups_dir = POLICYGROUPSDIR;
-
-static char *fg_path = NULL;
-static size_t fg_path_space = 0;
-
-
-/* Groups is a list of connections that are policy groups.
- * The list is updated as group connections are added and deleted.
- */
-
-struct fg_groups {
- struct fg_groups *next;
- struct connection *connection;
-};
-
-static struct fg_groups *groups = NULL;
-
-
-/* Targets is a list of pairs: subnet and its policy group.
- * This list is bulk-updated on whack --listen and
- * incrementally updated when group connections are deleted.
- *
- * It is ordered by source subnet, and if those are equal, then target subnet.
- * A subnet is compared by comparing the network, and if those are equal,
- * comparing the mask.
- */
-
-struct fg_targets {
- struct fg_targets *next;
- struct fg_groups *group;
- ip_subnet subnet;
- char *name; /* name of instance of group conn */
-};
-
-static struct fg_targets *targets = NULL;
-
-struct fg_targets *new_targets;
-
-/* ipcmp compares the two ip_address values a and b.
- * It returns -1, 0, or +1 if a is, respectively,
- * less than, equal to, or greater than b.
- */
-static int
-ipcmp(ip_address *a, ip_address *b)
-{
- if (addrtypeof(a) != addrtypeof(b))
- {
- return addrtypeof(a) < addrtypeof(b)? -1 : 1;
- }
- else if (sameaddr(a, b))
- {
- return 0;
- }
- else
- {
- const struct sockaddr *sa = sockaddrof(a)
- , *sb = sockaddrof(b);
-
- passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
- return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
- < ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
- ? -1 : 1;
- }
-}
-
-/* subnetcmp compares the two ip_subnet values a and b.
- * It returns -1, 0, or +1 if a is, respectively,
- * less than, equal to, or greater than b.
- */
-static int
-subnetcmp(const ip_subnet *a, const ip_subnet *b)
-{
- ip_address neta, maska, netb, maskb;
- int r;
-
- networkof(a, &neta);
- maskof(a, &maska);
- networkof(b, &netb);
- maskof(b, &maskb);
- r = ipcmp(&neta, &netb);
- if (r == 0)
- r = ipcmp(&maska, &maskb);
- return r;
-}
-
-static void
-read_foodgroup(struct fg_groups *g)
-{
- const char *fgn = g->connection->name;
- const ip_subnet *lsn = &g->connection->spd.this.client;
- size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
- struct file_lex_position flp_space;
-
- if (plen > fg_path_space)
- {
- pfreeany(fg_path);
- fg_path_space = plen + 10;
- fg_path = alloc_bytes(fg_path_space, "policy group path");
- }
- snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
- if (!lexopen(&flp_space, fg_path, TRUE))
- {
- DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
- }
- else
- {
- plog("loading group \"%s\"", fg_path);
- for (;;)
- {
- switch (flp->bdry)
- {
- case B_none:
- {
- /* !!! this test is not sufficient for distinguishing address families.
- * We need a notation to specify that a FQDN is to be resolved to IPv6.
- */
- const struct af_info *afi = strchr(tok, ':') == NULL
- ? &af_inet4_info: &af_inet6_info;
- ip_subnet sn;
- err_t ugh;
-
- if (strchr(tok, '/') == NULL)
- {
- /* no /, so treat as /32 or V6 equivalent */
- ip_address t;
-
- ugh = ttoaddr(tok, 0, afi->af, &t);
- if (ugh == NULL)
- ugh = addrtosubnet(&t, &sn);
- }
- else
- {
- ugh = ttosubnet(tok, 0, afi->af, &sn);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
- , flp->filename, flp->lino, ugh, tok);
- }
- else if (afi->af != AF_INET)
- {
- loglog(RC_LOG_SERIOUS
- , "\"%s\" line %d: unsupported Address Family \"%s\""
- , flp->filename, flp->lino, tok);
- }
- else
- {
- /* Find where new entry ought to go in new_targets. */
- struct fg_targets **pp;
- int r;
-
- for (pp = &new_targets; ; pp = &(*pp)->next)
- {
- if (*pp == NULL)
- {
- r = -1; /* end of list is infinite */
- break;
- }
- r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
- if (r == 0)
- r = subnetcmp(&sn, &(*pp)->subnet);
- if (r <= 0)
- break;
- }
-
- if (r == 0)
- {
- char source[SUBNETTOT_BUF];
-
- subnettot(lsn, 0, source, sizeof(source));
- loglog(RC_LOG_SERIOUS
- , "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
- , flp->filename
- , flp->lino
- , tok
- , source
- , (*pp)->group->connection->name);
- }
- else
- {
- struct fg_targets *f = alloc_thing(struct fg_targets, "fg_target");
-
- f->next = *pp;
- f->group = g;
- f->subnet = sn;
- f->name = NULL;
- *pp = f;
- }
- }
- }
- (void)shift(); /* next */
- continue;
-
- case B_record:
- flp->bdry = B_none; /* eat the Record Boundary */
- (void)shift(); /* get real first token */
- continue;
-
- case B_file:
- break; /* done */
- }
- break; /* if we reach here, out of loop */
- }
- lexclose();
- }
-}
-
-static void
-free_targets(void)
-{
- while (targets != NULL)
- {
- struct fg_targets *t = targets;
-
- targets = t->next;
- pfreeany(t->name);
- pfree(t);
- }
-}
-
-void
-load_groups(void)
-{
- passert(new_targets == NULL);
-
- /* for each group, add config file targets into new_targets */
- {
- struct fg_groups *g;
-
- for (g = groups; g != NULL; g = g->next)
- if (oriented(*g->connection))
- read_foodgroup(g);
- }
-
- /* dump new_targets */
- DBG(DBG_CONTROL,
- {
- struct fg_targets *t;
-
- for (t = new_targets; t != NULL; t = t->next)
- {
- char asource[SUBNETTOT_BUF];
- char atarget[SUBNETTOT_BUF];
-
- subnettot(&t->group->connection->spd.this.client
- , 0, asource, sizeof(asource));
- subnettot(&t->subnet, 0, atarget, sizeof(atarget));
- DBG_log("%s->%s %s"
- , asource, atarget
- , t->group->connection->name);
- }
- });
-
- /* determine and deal with differences between targets and new_targets.
- * structured like a merge.
- */
- {
- struct fg_targets *op = targets
- , *np = new_targets;
-
- while (op != NULL && np != NULL)
- {
- int r = subnetcmp(&op->group->connection->spd.this.client
- , &np->group->connection->spd.this.client);
-
- if (r == 0)
- r = subnetcmp(&op->subnet, &np->subnet);
-
- if (r == 0 && op->group == np->group)
- {
- /* unchanged -- steal name & skip over */
- np->name = op->name;
- op->name = NULL;
- op = op->next;
- np = np->next;
- }
- else
- {
- /* note: following cases overlap! */
- if (r <= 0)
- {
- remove_group_instance(op->group->connection, op->name);
- op = op->next;
- }
- if (r >= 0)
- {
- np->name = add_group_instance(np->group->connection, &np->subnet);
- np = np->next;
- }
- }
- }
- for (; op != NULL; op = op->next)
- remove_group_instance(op->group->connection, op->name);
- for (; np != NULL; np = np->next)
- np->name = add_group_instance(np->group->connection, &np->subnet);
-
- /* update: new_targets replaces targets */
- free_targets();
- targets = new_targets;
- new_targets = NULL;
- }
-}
-
-
-void
-add_group(struct connection *c)
-{
- struct fg_groups *g = alloc_thing(struct fg_groups, "policy group");
-
- g->next = groups;
- groups = g;
-
- g->connection = c;
-}
-
-static struct fg_groups *
-find_group(const struct connection *c)
-{
- struct fg_groups *g;
-
- for (g = groups; g != NULL && g->connection != c; g = g->next)
- ;
- return g;
-}
-
-void
-route_group(struct connection *c)
-{
- /* it makes no sense to route a connection that is ISAKMP-only */
- if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
- {
- loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
- }
- else
- {
- struct fg_groups *g = find_group(c);
- struct fg_targets *t;
-
- passert(g != NULL);
- g->connection->policy |= POLICY_GROUTED;
- for (t = targets; t != NULL; t = t->next)
- {
- if (t->group == g)
- {
- struct connection *ci = con_by_name(t->name, FALSE);
-
- if (ci != NULL)
- {
- set_cur_connection(ci);
- if (!trap_connection(ci))
- whack_log(RC_ROUTE, "could not route");
- set_cur_connection(c);
- }
- }
- }
- }
-}
-
-void
-unroute_group(struct connection *c)
-{
- struct fg_groups *g = find_group(c);
- struct fg_targets *t;
-
- passert(g != NULL);
- g->connection->policy &= ~POLICY_GROUTED;
- for (t = targets; t != NULL; t = t->next)
- {
- if (t->group == g)
- {
- struct connection *ci = con_by_name(t->name, FALSE);
-
- if (ci != NULL)
- {
- set_cur_connection(ci);
- unroute_connection(ci);
- set_cur_connection(c);
- }
- }
- }
-}
-
-void
-delete_group(const struct connection *c)
-{
- struct fg_groups *g;
-
- /* find and remove from groups */
- {
- struct fg_groups **pp;
-
- for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
- ;
-
- *pp = g->next;
- }
-
- /* find and remove from targets */
- {
- struct fg_targets **pp;
-
- for (pp = &targets; *pp != NULL; )
- {
- struct fg_targets *t = *pp;
-
- if (t->group == g)
- {
- *pp = t->next;
- remove_group_instance(t->group->connection, t->name);
- pfree(t);
- /* pp is ready for next iteration */
- }
- else
- {
- pp = &t->next;
- }
- }
- }
-
- pfree(g);
-}
diff --git a/programs/pluto/foodgroups.h b/programs/pluto/foodgroups.h
deleted file mode 100644
index 7cbbccc44..000000000
--- a/programs/pluto/foodgroups.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Implement policygroups-style control files (aka "foodgroups")
- * Copyright (C) 2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: foodgroups.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-struct connection; /* forward declaration */
-extern void add_group(struct connection *c);
-extern void route_group(struct connection *c);
-extern void unroute_group(struct connection *c);
-extern void delete_group(const struct connection *c);
-
-extern const char *policygroups_dir;
-extern void load_groups(void);
diff --git a/programs/pluto/gcryptfix.c b/programs/pluto/gcryptfix.c
deleted file mode 100644
index 1ebacdcf6..000000000
--- a/programs/pluto/gcryptfix.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Routines to make gcrypt routines feel at home in Pluto.
- * Copyright (C) 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: gcryptfix.c,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#include <stdlib.h>
-
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
-
-MPI
-mpi_alloc( unsigned nlimbs UNUSED )
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_alloc");
-
- mpz_init(n);
- return n;
-}
-
-MPI
-mpi_alloc_secure( unsigned nlimbs )
-{
- return mpi_alloc(nlimbs);
-}
-
-MPI
-mpi_alloc_set_ui( unsigned long u)
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_copy");
-
- mpz_init_set_ui(n, u);
- return n;
-}
-
-MPI
-mpi_copy( MPI a )
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_copy");
-
- mpz_init_set(n, a);
- return n;
-}
-
-void
-mpi_free( MPI a )
-{
- mpz_clear(a);
- pfree(a);
-}
-
-int
-mpi_divisible_ui(MPI dividend, ulong divisor )
-{
- ulong rem;
- mpz_t remtoo;
-
- mpz_init(remtoo);
- rem = mpz_mod_ui(remtoo, dividend, divisor);
- mpz_clear(remtoo);
- return rem == 0;
-}
-
-unsigned
-mpi_trailing_zeros( MPI a )
-{
- return mpz_scan1(a, 0);
-}
-
-unsigned
-mpi_get_nbits( MPI a )
-{
- return mpz_sizeinbase(a, 2);
-}
-
-int
-mpi_test_bit( MPI a, unsigned n )
-{
- /* inspired by gmp/mpz/clrbit.c */
- mp_size_t li = n / mp_bits_per_limb;
-
- if (li >= a->_mp_size)
- return 0;
- return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
-}
-
-void
-mpi_set_bit( MPI a, unsigned n )
-{
- mpz_setbit(a, n);
-}
-
-void
-mpi_clear_bit( MPI a, unsigned n )
-{
- mpz_clrbit(a, n);
-}
-
-void
-mpi_clear_highbit( MPI a, unsigned n )
-{
- /* This seems whacky, but what do I know. */
- mpz_fdiv_r_2exp(a, a, n);
-}
-
-void
-mpi_set_highbit( MPI a, unsigned n )
-{
- /* This seems whacky, but what do I know. */
- mpz_fdiv_r_2exp(a, a, n+1);
- mpz_setbit(a, n);
-}
-
-void
-mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
-{
- /* this is a lot like n_to_mpz */
- size_t i;
-
- passert(sign == 0); /* we won't hit any negative numbers */
- mpz_init_set_ui(a, 0);
-
- for (i = 0; i != nbytes; i++)
- {
- mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
- mpz_add_ui(a, a, buffer[i]);
- }
-}
-
-u_char *
-get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
-{
- size_t nbytes = (nbits+7)/8;
- u_char *b = alloc_bytes(nbytes, "random bytes");
-
- get_rnd_bytes(b, nbytes);
- return b;
-}
-/**************** from gnupg-1.0.0/mpi/mpi-mpow.c
- * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
- */
-#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) mpi_mulm( (w), (u), (v), (m) )
-
-static int
-build_index( MPI *exparray, int k, int i, int t )
-{
- int j, bitno;
- int index = 0;
-
- bitno = t-i;
- for(j=k-1; j >= 0; j-- ) {
- index <<= 1;
- if( mpi_test_bit( exparray[j], bitno ) )
- index |= 1;
- }
- /*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
- return index;
-}
-
-void
-mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
-{
- int k; /* number of elements */
- int t; /* bit size of largest exponent */
- int i, j, idx;
- MPI *G; /* table with precomputed values of size 2^k */
- MPI tmp;
- #ifdef USE_BARRETT
- MPI barrett_y, barrett_r1, barrett_r2;
- int barrett_k;
- #endif
-
- for(k=0; basearray[k]; k++ )
- ;
- passert(k);
- for(t=0, i=0; (tmp=exparray[i]); i++ ) {
- /*log_mpidump("exp: ", tmp );*/
- j = mpi_get_nbits(tmp);
- if( j > t )
- t = j;
- }
- /*log_mpidump("mod: ", m );*/
- passert(i==k);
- passert(t);
- passert( k < 10 );
-
-#ifdef PLUTO
- m_alloc_ptrs_clear(G, 1<<k);
-#else
- G = m_alloc_clear( (1<<k) * sizeof *G );
-#endif
-
- #ifdef USE_BARRETT
- barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
- #endif
- /* and calculate */
- tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
- mpi_set_ui( res, 1 );
- for(i = 1; i <= t; i++ ) {
- barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
- barrett_r1, barrett_r2 );
- idx = build_index( exparray, k, i, t );
- passert( idx >= 0 && idx < (1<<k) );
- if( !G[idx] ) {
- if( !idx )
- G[0] = mpi_alloc_set_ui( 1 );
- else {
- for(j=0; j < k; j++ ) {
- if( (idx & (1<<j) ) ) {
- if( !G[idx] )
- G[idx] = mpi_copy( basearray[j] );
- else
- barrett_mulm( G[idx], G[idx], basearray[j],
- m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
- }
- }
- if( !G[idx] )
- G[idx] = mpi_alloc(0);
- }
- }
- barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
- }
-
- /* cleanup */
- mpi_free(tmp);
- #ifdef USE_BARRETT
- mpi_free(barrett_y);
- mpi_free(barrett_r1);
- mpi_free(barrett_r2);
- #endif
- for(i=0; i < (1<<k); i++ )
- mpi_free(G[i]);
- m_free(G);
-}
-
-void
-log_mpidump( const char *text UNUSED, MPI a )
-{
- /* Print number in hex -- helpful to see if they match bytes.
- * Humans are not going to do arithmetic with the large numbers!
- * Much code adapted from mpz_to_n.
- */
- u_char buf[8048]; /* this ought to be big enough */
- size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
- MP_INT temp1, temp2;
- int i;
-
- passert(len <= sizeof(buf));
-
- mpz_init(&temp1);
- mpz_init(&temp2);
-
- mpz_set(&temp1, a);
-
- for (i = len-1; i >= 0; i--)
- {
- buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
- mpz_set(&temp1, &temp2);
- }
-
- passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
- mpz_clear(&temp1);
- mpz_clear(&temp2);
-
-#ifdef DEBUG
- DBG_dump(text, buf, len);
-#endif /* DEBUG */
-}
diff --git a/programs/pluto/gcryptfix.h b/programs/pluto/gcryptfix.h
deleted file mode 100644
index 637ecbc8d..000000000
--- a/programs/pluto/gcryptfix.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Definitions to make gcrypt routines feel at home in Pluto.
- * Copyright (C) 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: gcryptfix.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#define DBG_CIPHER 1 /* some day we'll do this right */
-
-/* Simulate MPI routines with gmp routines.
- * gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct.
- * gmp's mpz_t is an array of one of these structs to enable magic pointer
- * conversions to make the notation convenient (but confusing).
- */
-typedef u_char byte;
-typedef MP_INT *MPI;
-
-#define BITS_PER_MPI_LIMB mp_bits_per_limb
-
-extern MPI mpi_alloc( unsigned nlimbs );
-extern MPI mpi_alloc_secure( unsigned nlimbs );
-#define mpi_alloc_like(n) mpi_alloc(mpi_get_nlimbs(n))
-extern MPI mpi_alloc_set_ui( unsigned long u);
-#define mpi_set_ui(w, u) mpz_set_ui(w, u)
-#define mpi_set(w, u) mpz_set(w, u)
-extern void mpi_free( MPI a );
-extern MPI mpi_copy( MPI a );
-extern unsigned mpi_get_nbits( MPI a );
-#define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */
-extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign );
-extern unsigned mpi_trailing_zeros( MPI a );
-extern int mpi_test_bit( MPI a, unsigned n );
-extern void mpi_set_bit( MPI a, unsigned n );
-extern void mpi_clear_bit( MPI a, unsigned n );
-extern void mpi_clear_highbit( MPI a, unsigned n );
-extern void mpi_set_highbit( MPI a, unsigned n );
-#define mpi_cmp_ui(u, v) mpz_cmp_ui((u), (v))
-#define mpi_cmp(u, v) mpz_cmp((u), (v))
-#define mpi_is_neg(n) (mpz_sgn(n) < 0)
-#define mpi_add(w, u, v) mpz_add((w), (u), (v))
-#define mpi_add_ui(w, u, v) mpz_add_ui((w), (u), (v))
-#define mpi_sub_ui(w, u, v) mpz_sub_ui((w), (u), (v))
-#define mpi_subm( w, u, v, m) { mpz_sub( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
-#define mpi_mul( w, u, v) mpz_mul( (w), (u), (v))
-#define mpi_mul_ui( w, u, v) mpz_mul_ui( (w), (u), (v))
-#define mpi_mulm( w, u, v, m) { mpz_mul( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
-#define mpi_fdiv_q(quot, dividend, divisor) mpz_fdiv_q((quot), (dividend), (divisor))
-#define mpi_fdiv_r( rem, dividend, divisor ) mpz_fdiv_r( (rem), (dividend), (divisor) )
-#define mpi_fdiv_r_ui( rem, dividend, divisor ) mpz_fdiv_r_ui( (rem), (dividend), (divisor) )
-#define mpi_tdiv_q_2exp( w, u, count ) mpz_tdiv_q_2exp( (w), (u), (count) )
-extern int mpi_divisible_ui(MPI dividend, ulong divisor );
-#define mpi_powm( res, base, exp, mod) mpz_powm( res, base, exp, mod)
-extern void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
-#define mpi_gcd( g, a, b ) ( mpz_gcd( (g), (a), (b) ), !mpi_cmp_ui( (g), 1))
-#define mpi_invm( x, a, n ) mpz_invert( (x), (a), (n) )
-
-#ifdef DEBUG
-# define log_debug(f...) DBG_log(f)
-#else
-# define log_debug(f...) do ; while (0) /* do nothing, carefully */
-#endif
-#define log_fatal(f...) exit_log(f) /* overreaction? */
-extern void log_mpidump( const char *text, MPI a );
-
-#define assert(p) passert(p)
-#define BUG() passert(FALSE)
-
-#define m_alloc_ptrs_clear(pp, n) { \
- int c = (n); \
- (pp) = alloc_bytes((n) * sizeof(*(pp)), "m_alloc_ptrs_clear"); \
- while (c > 0) (pp)[--c] = NULL; \
- }
-
-extern u_char *get_random_bits(size_t nbits, int level, int secure);
-#define m_alloc(sz) alloc_bytes((sz), "m_alloc") /* not initialized */
-#define m_free(n) pfree(n) /* always freeing something from get_random_bits */
-
-/* declarations from gnupg-1.0.0/include/cipher.h */
-/*-- primegen.c --*/
-MPI generate_secret_prime( unsigned nbits );
-MPI generate_public_prime( unsigned nbits );
-MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
- MPI g, MPI **factors );
-
-#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/
-#define PUBKEY_ALGO_DSA 17
-#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */
-
-#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
-
-#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
-#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
-
-/* from gnupg-1.0.0/include/errors.h */
-
-#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
-#define G10ERR_BAD_SECKEY 7 /* Bad secret key */
-#define G10ERR_BAD_SIGN 8 /* Bad signature */
-#define G10ERR_BAD_MPI 30
-
-/*-- smallprime.c --*/
-extern ushort small_prime_numbers[];
diff --git a/programs/pluto/id.c b/programs/pluto/id.c
deleted file mode 100644
index 4e306d3a7..000000000
--- a/programs/pluto/id.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/* identity representation, as in IKE ID Payloads (RFC 2407 DOI 4.6.2.1)
- * Copyright (C) 1999-2001 D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: id.c,v 1.4 2005/08/15 20:07:08 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
-# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
-#endif
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "id.h"
-#include "log.h"
-#include "connections.h"
-#include "packet.h"
-#include "whack.h"
-
-const struct id empty_id; /* ID_NONE */
-
-enum myid_state myid_state = MYID_UNKNOWN;
-struct id myids[MYID_SPECIFIED+1]; /* %myid */
-char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
-
-/* initialize id module
- * Fills in myid from environment variable IPSECmyid or defaultrouteaddr
- */
-void
-init_id(void)
-{
- passert(empty_id.kind == ID_NONE);
- myid_state = MYID_UNKNOWN;
- {
- enum myid_state s;
-
- for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
- {
- myids[s] = empty_id;
- myid_str[s] = NULL;
- }
- }
- set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
- set_myid(MYID_IP, getenv("defaultrouteaddr"));
- set_myFQDN();
-}
-
-static void
-calc_myid_str(enum myid_state s)
-{
- /* preformat the ID name */
- char buf[BUF_LEN];
-
- idtoa(&myids[s], buf, BUF_LEN);
- replace(myid_str[s], clone_str(buf, "myid string"));
-}
-
-
-void
-set_myid(enum myid_state s, char *idstr)
-{
- if (idstr != NULL)
- {
- struct id id;
- err_t ugh = atoid(idstr, &id, FALSE);
-
- if (ugh != NULL)
- {
- loglog(RC_BADID, "myid malformed: %s \"%s\"", ugh, idstr);
- }
- else
- {
- free_id_content(&myids[s]);
- unshare_id_content(&id);
- myids[s] = id;
- if (s == MYID_SPECIFIED)
- myid_state = MYID_SPECIFIED;
-
- calc_myid_str(s);
- }
- }
-}
-
-void
-set_myFQDN(void)
-{
- char FQDN[HOST_NAME_MAX + 1];
- int r = gethostname(FQDN, sizeof(FQDN));
-
- free_id_content(&myids[MYID_HOSTNAME]);
- myids[MYID_HOSTNAME] = empty_id;
- if (r != 0)
- {
- log_errno((e, "gethostname() failed in set_myFQDN"));
- }
- else
- {
- FQDN[sizeof(FQDN) - 1] = '\0'; /* insurance */
-
- {
- size_t len = strlen(FQDN);
-
- if (len > 0 && FQDN[len-1] == '.')
- {
- /* nuke trailing . */
- FQDN[len-1]='\0';
- }
- }
-
- if (!strcaseeq(FQDN, "localhost.localdomain"))
- {
- clonetochunk(myids[MYID_HOSTNAME].name, FQDN, strlen(FQDN), "my FQDN");
- myids[MYID_HOSTNAME].kind = ID_FQDN;
- calc_myid_str(MYID_HOSTNAME);
- }
- }
-}
-
-void
-show_myid_status(void)
-{
- char idstr[BUF_LEN];
-
- (void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
- whack_log(RC_COMMENT, "%%myid = %s", idstr);
-}
-
-/* Convert textual form of id into a (temporary) struct id.
- * Note that if the id is to be kept, unshare_id_content will be necessary.
- */
-err_t
-atoid(char *src, struct id *id, bool myid_ok)
-{
- err_t ugh = NULL;
-
- *id = empty_id;
-
- if (myid_ok && streq("%myid", src))
- {
- id->kind = ID_MYID;
- }
- else if (strchr(src, '=') != NULL)
- {
- /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
- id->kind = ID_DER_ASN1_DN;
- id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */
- id->name.len = 0;
- /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN
- * discard optional @ character in front of DN
- */
- ugh = atodn((*src == '@')?src+1:src, &id->name);
- }
- else if (strchr(src, '@') == NULL)
- {
- if (streq(src, "%any") || streq(src, "0.0.0.0"))
- {
- /* any ID will be accepted */
- id->kind = ID_NONE;
- }
- else
- {
- /* !!! this test is not sufficient for distinguishing address families.
- * We need a notation to specify that a FQDN is to be resolved to IPv6.
- */
- const struct af_info *afi = strchr(src, ':') == NULL
- ? &af_inet4_info: &af_inet6_info;
-
- id->kind = afi->id_addr;
- ugh = ttoaddr(src, 0, afi->af, &id->ip_addr);
- }
- }
- else
- {
- if (*src == '@')
- {
- if (*(src+1) == '#')
- {
- /* if there is a second specifier (#) on the line
- * we interprete this as ID_KEY_ID
- */
- id->kind = ID_KEY_ID;
- id->name.ptr = src;
- /* discard @~, convert from hex to bin */
- ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
- }
- else if (*(src+1) == '~')
- {
- /* if there is a second specifier (~) on the line
- * we interprete this as a binary ID_DER_ASN1_DN
- */
- id->kind = ID_DER_ASN1_DN;
- id->name.ptr = src;
- /* discard @~, convert from hex to bin */
- ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
- }
- else
- {
- id->kind = ID_FQDN;
- id->name.ptr = src+1; /* discard @ */
- id->name.len = strlen(src)-1;
- }
- }
- else
- {
- /* We leave in @, as per DOI 4.6.2.4
- * (but DNS wants . instead).
- */
- id->kind = ID_USER_FQDN;
- id->name.ptr = src;
- id->name.len = strlen(src);
- }
- }
- return ugh;
-}
-
-
-/*
- * Converts a binary key ID into hexadecimal format
- */
-int
-keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
-{
- int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
- return (((size_t)n < dstlen)? n : dstlen) - 1;
-}
-
-void
-iptoid(const ip_address *ip, struct id *id)
-{
- *id = empty_id;
-
- switch (addrtypeof(ip))
- {
- case AF_INET:
- id->kind = ID_IPV4_ADDR;
- break;
- case AF_INET6:
- id->kind = ID_IPV6_ADDR;
- break;
- default:
- bad_case(addrtypeof(ip));
- }
- id->ip_addr = *ip;
-}
-
-int
-idtoa(const struct id *id, char *dst, size_t dstlen)
-{
- int n;
-
- id = resolve_myid(id);
- switch (id->kind)
- {
- case ID_NONE:
- n = snprintf(dst, dstlen, "(none)");
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
- break;
- case ID_FQDN:
- n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
- break;
- case ID_USER_FQDN:
- n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
- break;
- case ID_DER_ASN1_DN:
- n = dntoa(dst, dstlen, id->name);
- break;
- case ID_KEY_ID:
- n = keyidtoa(dst, dstlen, id->name);
- break;
- default:
- n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
- break;
- }
-
- /* "Sanitize" string so that log isn't endangered:
- * replace unprintable characters with '?'.
- */
- if (n > 0)
- {
- for ( ; *dst != '\0'; dst++)
- if (!isprint(*dst))
- *dst = '?';
- }
-
- return n;
-}
-
-/* Replace the shell metacharacters ', \, ", `, and $ in a character string
- * by escape sequences consisting of their octal values
- */
-void
-escape_metachar(const char *src, char *dst, size_t dstlen)
-{
- while (*src != '\0' && dstlen > 4)
- {
- switch (*src)
- {
- case '\'':
- case '\\':
- case '"':
- case '`':
- case '$':
- sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
- dst += 4;
- dstlen -= 4;
- break;
- default:
- *dst++ = *src;
- dstlen--;
- }
- src++;
- }
- *dst = '\0';
-}
-
-
-/* Make private copy of string in struct id.
- * This is needed if the result of atoid is to be kept.
- */
-void
-unshare_id_content(struct id *id)
-{
- switch (id->kind)
- {
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- id->name.ptr = clone_bytes(id->name.ptr, id->name.len, "keep id name");
- break;
- case ID_MYID:
- case ID_NONE:
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- break;
- default:
- bad_case(id->kind);
- }
-}
-
-void
-free_id_content(struct id *id)
-{
- switch (id->kind)
- {
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- freeanychunk(id->name);
- break;
- case ID_MYID:
- case ID_NONE:
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- break;
- default:
- bad_case(id->kind);
- }
-}
-
-/* compare two struct id values */
-bool
-same_id(const struct id *a, const struct id *b)
-{
- a = resolve_myid(a);
- b = resolve_myid(b);
- if (a->kind != b->kind)
- return FALSE;
- switch (a->kind)
- {
- case ID_NONE:
- return TRUE; /* kind of vacuous */
-
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- return sameaddr(&a->ip_addr, &b->ip_addr);
-
- case ID_FQDN:
- case ID_USER_FQDN:
- /* assumptions:
- * - case should be ignored
- * - trailing "." should be ignored (even if the only character?)
- */
- {
- size_t al = a->name.len
- , bl = b->name.len;
-
- while (al > 0 && a->name.ptr[al - 1] == '.')
- al--;
- while (bl > 0 && b->name.ptr[bl - 1] == '.')
- bl--;
- return al == bl
- && strncasecmp(a->name.ptr, b->name.ptr, al) == 0;
- }
-
- case ID_DER_ASN1_DN:
- return same_dn(a->name, b->name);
-
- case ID_KEY_ID:
- return a->name.len == b->name.len
- && memcmp(a->name.ptr, b->name.ptr, a->name.len) == 0;
-
- default:
- bad_case(a->kind);
- }
- return FALSE;
-}
-
-/* compare two struct id values, DNs can contain wildcards */
-bool
-match_id(const struct id *a, const struct id *b, int *wildcards)
-{
- if (b->kind == ID_NONE)
- {
- *wildcards = MAX_WILDCARDS;
- return TRUE;
- }
- if (a->kind != b->kind)
- return FALSE;
- if (a->kind == ID_DER_ASN1_DN)
- return match_dn(a->name, b->name, wildcards);
- else
- {
- *wildcards = 0;
- return same_id(a, b);
- }
-}
-
-/* count the numer of wildcards in an id */
-int
-id_count_wildcards(const struct id *id)
-{
- switch (id->kind)
- {
- case ID_NONE:
- return MAX_WILDCARDS;
- case ID_DER_ASN1_DN:
- return dn_count_wildcards(id->name);
- default:
- return 0;
- }
-}
-
-/* build an ID payload
- * Note: no memory is allocated for the body of the payload (tl->ptr).
- * We assume it will end up being a pointer into a sufficiently
- * stable datastructure. It only needs to last a short time.
- */
-void
-build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
-{
- const struct id *id = resolve_myid(&end->id);
-
- zero(hd);
- hd->isaiid_idtype = id->kind;
- switch (id->kind)
- {
- case ID_NONE:
- hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
- tl->len = addrbytesptr(&end->host_addr
- , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
- break;
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- *tl = id->name;
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- tl->len = addrbytesptr(&id->ip_addr
- , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
- break;
- default:
- bad_case(id->kind);
- }
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/programs/pluto/id.h b/programs/pluto/id.h
deleted file mode 100644
index 4fe9ef227..000000000
--- a/programs/pluto/id.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* identity representation, as in IKE ID Payloads (RFC 2407 DOI 4.6.2.1)
- * Copyright (C) 1999-2001 D. Hugh Redelmeier
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: id.h,v 1.5 2005/08/15 20:07:08 as Exp $
- */
-
-#ifndef _ID_H
-#define _ID_H
-
-#include "defs.h"
-
-struct id {
- int kind; /* ID_* value */
- ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
- chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
- /* ID_KEY_ID, ID_DER_ASN_DN */
-};
-
-extern void init_id(void);
-
-extern const struct id empty_id; /* ID_NONE */
-
-enum myid_state {
- MYID_UNKNOWN, /* not yet figured out */
- MYID_HOSTNAME, /* our current hostname */
- MYID_IP, /* our default IP address */
- MYID_SPECIFIED /* as specified by ipsec.conf */
-};
-
-extern enum myid_state myid_state;
-extern struct id myids[MYID_SPECIFIED+1]; /* %myid */
-extern char *myid_str[MYID_SPECIFIED+1]; /* strings */
-extern void set_myid(enum myid_state s, char *);
-extern void show_myid_status(void);
-#define resolve_myid(id) ((id)->kind == ID_MYID? &myids[myid_state] : (id))
-extern void set_myFQDN(void);
-
-extern err_t atoid(char *src, struct id *id, bool myid_ok);
-extern int keyidtoa(char *dst, size_t dstlen, chunk_t keyid);
-extern void iptoid(const ip_address *ip, struct id *id);
-extern int idtoa(const struct id *id, char *dst, size_t dstlen);
-#define IDTOA_BUF 512
-extern void escape_metachar(const char *src, char *dst, size_t dstlen);
-struct end; /* forward declaration of tag (defined in connections.h) */
-extern void unshare_id_content(struct id *id);
-extern void free_id_content(struct id *id);
-extern bool same_id(const struct id *a, const struct id *b);
-#define MAX_WILDCARDS 15
-extern bool match_id(const struct id *a, const struct id *b, int *wildcards);
-extern int id_count_wildcards(const struct id *id);
-#define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR)
-
-struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */
-extern void
- build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end);
-
-#endif /* _ID_H */
diff --git a/programs/pluto/ike_alg.c b/programs/pluto/ike_alg.c
deleted file mode 100644
index e090ebed3..000000000
--- a/programs/pluto/ike_alg.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/* IKE modular algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ike_alg.c,v 1.9 2007/02/21 14:21:48 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h"
-
-#include "state.h"
-#include "packet.h"
-#include "log.h"
-#include "whack.h"
-#include "spdb.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "db_ops.h"
-#include "connections.h"
-#include "kernel.h"
-
-#define return_on(var, val) do { var=val;goto return_out; } while(0);
-
-/*
- * IKE algorithm list handling - registration and lookup
- */
-
-/* Modular IKE algorithm storage structure */
-
-static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
-
-/*
- * return ike_algo object by {type, id}
- */
-static struct ike_alg *
-ike_alg_find(u_int algo_type, u_int algo_id, u_int keysize __attribute__((unused)))
-{
- struct ike_alg *e = ike_alg_base[algo_type];
-
- while (e != NULL && algo_id > e->algo_id)
- {
- e = e->algo_next;
- }
- return (e != NULL && e->algo_id == algo_id) ? e : NULL;
-}
-
-/*
- * "raw" ike_alg list adding function
- */
-int
-ike_alg_add(struct ike_alg* a)
-{
- if (a->algo_type > IKE_ALG_MAX)
- {
- plog("ike_alg: Not added, invalid algorithm type");
- return -EINVAL;
- }
-
- if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
- {
- plog("ike_alg: Not added, algorithm already exists");
- return -EEXIST;
- }
-
- {
- struct ike_alg **ep = &ike_alg_base[a->algo_type];
- struct ike_alg *e = *ep;
-
- while (e != NULL && a->algo_id > e->algo_id)
- {
- ep = &e->algo_next;
- e = *ep;
- }
- *ep = a;
- a->algo_next = e;
- return 0;
- }
-}
-
-/*
- * get IKE hash algorithm
- */
-struct hash_desc *ike_alg_get_hasher(u_int alg)
-{
- return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
-}
-
-/*
- * get IKE encryption algorithm
- */
-struct encrypt_desc *ike_alg_get_encrypter(u_int alg)
-{
- return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
-}
-
-/*
- * check if IKE hash algorithm is present
- */
-bool
-ike_alg_hash_present(u_int halg)
-{
- return ike_alg_get_hasher(halg) != NULL;
-}
-
-/*
- * check if IKE encryption algorithm is present
- */
-bool
-ike_alg_enc_present(u_int ealg)
-{
- return ike_alg_get_encrypter(ealg) != NULL;
-}
-
-/*
- * Validate and register IKE hash algorithm object
- */
-int
-ike_alg_register_hash(struct hash_desc *hash_desc)
-{
- const char *alg_name = NULL;
- int ret = 0;
-
- if (hash_desc->algo_id > OAKLEY_HASH_MAX)
- {
- plog ("ike_alg: hash alg=%d > max=%d"
- , hash_desc->algo_id, OAKLEY_HASH_MAX);
- return_on(ret,-EINVAL);
- }
-
- if (hash_desc->hash_ctx_size > sizeof (union hash_ctx))
- {
- plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d"
- , hash_desc->algo_id
- , (int)hash_desc->hash_ctx_size
- , (int)sizeof (union hash_ctx));
- return_on(ret,-EOVERFLOW);
- }
-
- if (!(hash_desc->hash_init && hash_desc->hash_update && hash_desc->hash_final))
- {
- plog ("ike_alg: hash alg=%d needs hash_init(), hash_update() and hash_final()"
- , hash_desc->algo_id);
- return_on(ret,-EINVAL);
- }
-
- alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id);
- if (!alg_name)
- {
- plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names"
- , hash_desc->algo_id);
- alg_name = "<NULL>";
- }
-
-return_out:
- if (ret == 0)
- ret = ike_alg_add((struct ike_alg *)hash_desc);
-
- plog("ike_alg: Activating %s hash: %s"
- ,alg_name, ret == 0 ? "Ok" : "FAILED");
-
- return ret;
-}
-
-/*
- * Validate and register IKE encryption algorithm object
- */
-int
-ike_alg_register_enc(struct encrypt_desc *enc_desc)
-{
- int ret = ike_alg_add((struct ike_alg *)enc_desc);
-
- const char *alg_name = enum_name(&oakley_enc_names, enc_desc->algo_id);
-
- char alg_number[20];
-
- /* algorithm is not listed in oakley_enc_names */
- if (alg_name == NULL)
- {
- snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d"
- , enc_desc->algo_id);
- alg_name = alg_number;
- }
-
- plog("ike_alg: Activating %s encryption: %s"
- , alg_name, ret == 0 ? "Ok" : "FAILED");
-
- return ret;
-}
-
-/*
- * Get pfsgroup for this connection
- */
-const struct oakley_group_desc *
-ike_alg_pfsgroup(struct connection *c, lset_t policy)
-{
- const struct oakley_group_desc * ret = NULL;
-
- if ((policy & POLICY_PFS)
- && c->alg_info_esp
- && c->alg_info_esp->esp_pfsgroup)
- ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
- return ret;
-}
-
-/*
- * Create an OAKLEY proposal based on alg_info and policy
- */
-struct db_context *
-ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
-{
- struct db_context *db_ctx = NULL;
- struct ike_info *ike_info;
- struct encrypt_desc *enc_desc;
- u_int ealg, halg, modp, eklen = 0;
- int i;
-
- bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
-
- if (!ai)
- {
- whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
- "for this connection "
- "(check ike algorithm string)");
- goto fail;
- }
- policy &= POLICY_ID_AUTH_MASK;
- db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
-
- /* for each group */
- ALG_INFO_IKE_FOREACH(ai, ike_info, i)
- {
- ealg = ike_info->ike_ealg;
- halg = ike_info->ike_halg;
- modp = ike_info->ike_modp;
- eklen= ike_info->ike_eklen;
-
- if (!ike_alg_enc_present(ealg))
- {
- DBG_log("ike_alg: ike enc ealg=%d not present"
- , ealg);
- continue;
- }
-
- if (!ike_alg_hash_present(halg))
- {
- DBG_log("ike_alg: ike hash halg=%d not present"
- , halg);
- continue;
- }
-
- enc_desc = ike_alg_get_encrypter(ealg);
- passert(enc_desc != NULL);
-
- if (eklen
- && (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen))
- {
- DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
- , ealg
- , eklen
- , enc_desc->keyminlen
- , enc_desc->keymaxlen
- );
- continue;
- }
-
- if (policy & POLICY_RSASIG)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
-
- if (policy & POLICY_PSK)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
-
- if (policy & POLICY_XAUTH_RSASIG)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
- , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
-
- if (policy & POLICY_XAUTH_PSK)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
- , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
- }
-fail:
- return db_ctx;
-}
-
-/*
- * Show registered IKE algorithms
- */
-void
-ike_alg_list(void)
-{
- u_int i;
- struct ike_alg *a;
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
- {
- struct encrypt_desc *desc = (struct encrypt_desc*)a;
-
- whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
- , a->algo_id
- , enum_name(&oakley_enc_names, a->algo_id)
- , (int)desc->enc_blocksize*BITS_PER_BYTE
- , desc->keyminlen
- , desc->keydeflen
- , desc->keymaxlen
- );
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
- {
- whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
- , a->algo_id
- , enum_name(&oakley_hash_names, a->algo_id)
- , (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
- );
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
- whack_log(RC_COMMENT, " ");
-
- for (i = 0; i < elemsof(oakley_group); i++)
- {
- const struct oakley_group_desc *gdesc=oakley_group + i;
-
- whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
- , gdesc->group
- , enum_name(&oakley_group_names, gdesc->group)
- , (int)gdesc->bytes*BITS_PER_BYTE
- );
- }
-}
-
-/* Show IKE algorithms for
- * - this connection (result from ike= string)
- * - newest SA
- */
-void
-ike_alg_show_connection(struct connection *c, const char *instance)
-{
- char buf[256];
- struct state *st;
-
- if (c->alg_info_ike)
- {
- alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike);
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithms wanted: %s"
- , c->name
- , instance
- , buf
- );
-
- alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike);
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithms found: %s"
- , c->name
- , instance
- , buf
- );
- }
-
- st = state_with_serialno(c->newest_isakmp_sa);
- if (st)
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s"
- , c->name
- , instance
- , enum_show(&oakley_enc_names, st->st_oakley.encrypt)
- +7 /* strlen("OAKLEY_") */
- /* , st->st_oakley.encrypter->keydeflen */
- , st->st_oakley.enckeylen
- , enum_show(&oakley_hash_names, st->st_oakley.hash)
- +7 /* strlen("OAKLEY_") */
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- +13 /* strlen("OAKLEY_GROUP_") */
- );
-}
-
-/*
- * Apply a suite of testvectors to a hash algorithm
- */
-static bool
-ike_hash_test(const struct hash_desc *desc)
-{
- bool hash_results = TRUE;
- bool hmac_results = TRUE;
-
- if (desc->hash_testvectors == NULL)
- {
- plog(" %s hash self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
- }
- else
- {
- int i;
-
- for (i = 0; desc->hash_testvectors[i].msg_digest != NULL; i++)
- {
- u_char digest[MAX_DIGEST_LEN];
- bool result;
-
- union hash_ctx ctx;
-
- desc->hash_init(&ctx);
- desc->hash_update(&ctx, desc->hash_testvectors[i].msg
- ,desc->hash_testvectors[i].msg_size);
- desc->hash_final(digest, &ctx);
- result = memcmp(digest, desc->hash_testvectors[i].msg_digest
- , desc->hash_digest_size) == 0;
- DBG(DBG_CRYPT,
- DBG_log(" hash testvector %d: %s", i, result ? "ok":"failed")
- )
- hash_results &= result;
- }
- plog(" %s hash self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
- , hash_results ? "passed":"failed");
- }
-
- if (desc->hmac_testvectors == NULL)
- {
- plog(" %s hmac self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
- }
- else
- {
- int i;
-
- for (i = 0; desc->hmac_testvectors[i].hmac != NULL; i++)
- {
- u_char digest[MAX_DIGEST_LEN];
- bool result;
-
- struct hmac_ctx ctx;
-
- hmac_init(&ctx, desc, desc->hmac_testvectors[i].key
- , desc->hmac_testvectors[i].key_size);
- hmac_update(&ctx, desc->hmac_testvectors[i].msg
- ,desc->hmac_testvectors[i].msg_size);
- hmac_final(digest, &ctx);
- result = memcmp(digest, desc->hmac_testvectors[i].hmac
- , desc->hash_digest_size) == 0;
- DBG(DBG_CRYPT,
- DBG_log(" hmac testvector %d: %s", i, result ? "ok":"failed")
- )
- hmac_results &= result;
- }
- plog(" %s hmac self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
- , hmac_results ? "passed":"failed");
- }
- return hash_results && hmac_results;
-}
-
-/*
- * Apply test vectors to registered encryption and hash algorithms
- */
-bool
-ike_alg_test(void)
-{
- bool all_results = TRUE;
- struct ike_alg *a;
-
- plog("Testing registered IKE encryption algorithms:");
-
- for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
- {
-
- struct encrypt_desc *desc = (struct encrypt_desc*)a;
-
- plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id));
- }
-
- plog("Testing registered IKE hash algorithms:");
-
- for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
- {
- struct hash_desc *desc = (struct hash_desc*)a;
-
- all_results &= ike_hash_test(desc);
- }
-
- if (all_results)
- plog("All crypto self-tests passed");
- else
- plog("Some crypto self-tests failed");
- return all_results;
-}
-
-/*
- * ML: make F_STRICT logic consider enc,hash/auth,modp algorithms
- */
-bool
-ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
-, struct alg_info_ike *alg_info_ike)
-{
- /*
- * simple test to discard low key_len, will accept it only
- * if specified in "esp" string
- */
- bool ealg_insecure = (key_len < 128);
-
- if (ealg_insecure
- || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
- {
- int i;
- struct ike_info *ike_info;
-
- if (alg_info_ike)
- {
- ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
- {
- if (ike_info->ike_ealg == ealg
- && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
- && ike_info->ike_halg == aalg
- && ike_info->ike_modp == group)
- {
- if (ealg_insecure)
- loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
- , enum_name(&oakley_enc_names, ealg));
- return TRUE;
- }
- }
- }
- plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
- , enum_name(&oakley_enc_names, ealg), key_len
- , enum_name(&oakley_hash_names, aalg)
- , enum_name(&oakley_group_names, group)
- , ealg_insecure ?
- "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
- );
- return FALSE;
- }
- return TRUE;
-}
-
diff --git a/programs/pluto/ike_alg.h b/programs/pluto/ike_alg.h
deleted file mode 100644
index 32f6e8be0..000000000
--- a/programs/pluto/ike_alg.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* IKE modular algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ike_alg.h,v 1.4 2007/02/21 14:21:48 as Exp $
- */
-
-#ifndef _IKE_ALG_H
-#define _IKE_ALG_H
-
-#include "connections.h"
-
-struct ike_alg {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
-};
-
-struct encrypt_desc {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
-
- size_t enc_ctxsize;
- size_t enc_blocksize;
- u_int keydeflen;
- u_int keymaxlen;
- u_int keyminlen;
- void (*do_crypt)(u_int8_t *dat, size_t datasize, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
-};
-
-typedef struct hash_testvector hash_testvector_t;
-
-struct hash_testvector {
- const size_t msg_size;
- const u_char *msg;
- const u_char *msg_digest;
-};
-
-typedef struct hmac_testvector hmac_testvector_t;
-
-struct hmac_testvector {
- const size_t key_size;
- const u_char *key;
- const size_t msg_size;
- const u_char *msg;
- const u_char *hmac;
-};
-struct hash_desc {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
-
- size_t hash_ctx_size;
- size_t hash_block_size;
- size_t hash_digest_size;
- const hash_testvector_t *hash_testvectors;
- const hmac_testvector_t *hmac_testvectors;
- void (*hash_init)(void *ctx);
- void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize);
- void (*hash_final)(u_int8_t *out, void *ctx);
-};
-
-#define IKE_ALG_ENCRYPT 0
-#define IKE_ALG_HASH 1
-#define IKE_ALG_MAX IKE_ALG_HASH
-
-extern int ike_alg_add(struct ike_alg *a);
-extern struct hash_desc *ike_alg_get_hasher(u_int alg);
-extern struct encrypt_desc *ike_alg_get_encrypter(u_int alg);
-extern bool ike_alg_enc_present(u_int ealg);
-extern bool ike_alg_hash_present(u_int halg);
-extern int ike_alg_register_hash(struct hash_desc *a);
-extern int ike_alg_register_enc(struct encrypt_desc *e);
-extern const struct oakley_group_desc* ike_alg_pfsgroup(struct connection *c
- , lset_t policy);
-extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy);
-extern void ike_alg_list(void);
-extern void ike_alg_show_connection(struct connection *c, const char *instance);
-extern bool ike_alg_test(void);
-extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
- , struct alg_info_ike *alg_info_ike);
-extern int ike_alg_init(void);
-
-#endif /* _IKE_ALG_H */
diff --git a/programs/pluto/ipsec.secrets.5 b/programs/pluto/ipsec.secrets.5
deleted file mode 100644
index 3cce4d3f8..000000000
--- a/programs/pluto/ipsec.secrets.5
+++ /dev/null
@@ -1,175 +0,0 @@
-.TH IPSEC.SECRETS 5 "28 March 1999"
-.SH NAME
-ipsec.secrets \- secrets for IKE/IPsec authentication
-.SH DESCRIPTION
-The file \fIipsec.secrets\fP holds a table of secrets.
-These secrets are used by \fIipsec_pluto\fP(8), the FreeS/WAN Internet Key
-Exchange daemon, to authenticate other hosts.
-Currently there are two kinds of secrets: preshared secrets and
-.\" the private part of DSS keys.
-RSA private keys.
-.LP
-It is vital that these secrets be protected. The file should be owned
-by the super-user,
-and its permissions should be set to block all access by others.
-.LP
-The file is a sequence of entries and include directives.
-Here is an example. Each entry or directive must start at the
-left margin, but if it continues beyond a single line, each continuation
-line must be indented.
-.LP
-.RS
-.nf
-# sample /etc/ipsec.secrets file for 10.1.0.1
-10.1.0.1 10.2.0.1: PSK "secret shared by two hosts"
-
-# an entry may be split across lines,
-# but indentation matters
-www.xs4all.nl @www.kremvax.ru
-\ \ \ \ 10.6.0.1 10.7.0.1 1.8.0.1: PSK "secret shared by 5"
-
-.\" # Private part of our DSS key, in base 64,
-.\" # as generated by BIND 8.2.1's dnskeygen.
-.\" # Since this is the default key for this host,
-.\" # there is no need to specify indices.
-.\" : DSS 0siMs0N/hfRoCBMXA6plPtuv58/+c=
-# an RSA private key.
-# note that the lines are too wide for a
-# man page, so ... has been substituted for
-# the truncated part
-@my.com: rsa {
-\ \ \ \ Modulus:\ 0syXpo/6waam+ZhSs8Lt6jnBzu3C4grtt...
-\ \ \ \ PublicExponent:\ 0sAw==
-\ \ \ \ PrivateExponent:\ 0shlGbVR1m8Z+7rhzSyenCaBN...
-\ \ \ \ Prime1:\ 0s8njV7WTxzVzRz7AP+0OraDxmEAt1BL5l...
-\ \ \ \ Prime2:\ 0s1LgR7/oUMo9BvfU8yRFNos1s211KX5K0...
-\ \ \ \ Exponent1:\ 0soaXj85ihM5M2inVf/NfHmtLutVz4r...
-\ \ \ \ Exponent2:\ 0sjdAL9VFizF+BKU4ohguJFzOd55OG6...
-\ \ \ \ Coefficient:\ 0sK1LWwgnNrNFGZsS/2GuMBg9nYVZ...
-\ \ \ \ }
-
-include ipsec.*.secrets # get secrets from other files
-.fi
-.RE
-.LP
-Each entry in the file is a list of indices, followed by a secret.
-The two parts are separated by a colon (\fB:\fP) that is
-followed by whitespace or a newline. For compatability
-with the previous form of this file, if the key part is just a
-double-quoted string the colon may be left out.
-.LP
-An index is an IP address, or a Fully Qualified Domain Name, user@FQDN,
-\fB%any\fP or \fB%any6\fP (other kinds may come). An IP address may be written
-in the familiar dotted quad form or as a domain name to be looked up
-when the file is loaded
-(or in any of the forms supported by the FreeS/WAN \fIipsec_ttoaddr\fP(3)
-routine). In many cases it is a bad idea to use domain names because
-the name server may not be running or may be insecure. To denote a
-Fully Qualified Domain Name (as opposed to an IP address denoted by
-its domain name), precede the name with an at sign (\fB@\fP).
-.LP
-Matching IDs with indices is fairly straightforward: they have to be
-equal. In the case of a ``Road Warrior'' connection, if an equal
-match is not found for the Peer's ID, and it is in the form of an IP
-address, an index of \fB%any\fP will match the peer's IP address if IPV4
-and \fB%any6\fP will match a the peer's IP address if IPV6.
-Currently, the obsolete notation \fB0.0.0.0\fP may be used in place of
-\fB%any\fP.
-.LP
-An additional complexity
-arises in the case of authentication by preshared secret: the
-responder will need to look up the secret before the Peer's ID payload has
-been decoded, so the ID used will be the IP address.
-.LP
-To authenticate a connection between two hosts, the entry that most
-specifically matches the host and peer IDs is used. An entry with no
-index will match any host and peer. More specifically, an entry with one index will
-match a host and peer if the index matches the host's ID (the peer isn't
-considered). Still more specifically, an entry with multiple indices will match a host and
-peer if the host ID and peer ID each match one of the indices. If the key
-is for an asymmetric authentication technique (i.e. a public key
-system such as RSA), an entry with multiple indices will match a host
-and peer even if only the host ID matches an index (it is presumed that the
-multiple indices are all identities of the host).
-It is acceptable for two entries to be the best match as
-long as they agree about the secret or private key.
-.LP
-Authentication by preshared secret requires that both systems find the
-identical secret (the secret is not actually transmitted by the IKE
-protocol). If both the host and peer appear in the index list, the
-same entry will be suitable for both systems so verbatim copying
-between systems can be used. This naturally extends to larger groups
-sharing the same secret. Thus multiple-index entries are best for PSK
-authentication.
-.LP
-Authentication by RSA Signatures requires that each host have its own private
-key. A host could reasonably use a different private keys
-for different interfaces and for different peers. But it would not
-be normal to share entries between systems. Thus thus no-index and
-one-index forms of entry often make sense for RSA Signature authentication.
-.LP
-The key part of an entry may start with a token indicating the kind of
-key. ``RSA'' signifies RSA private key and ``PSK'' signifies
-PreShared Key (case is ignored). For compatability with previous
-forms of this file, PSK is the default.
-.LP
-A preshared secret is most conveniently represented as a sequence of
-characters, delimited by the double-quote
-character (\fB"\fP). The sequence cannot contain a newline or
-double-quote. Strictly speaking, the secret is actually the sequence
-of bytes that is used in the file to represent the sequence of
-characters (excluding the delimiters).
-A preshared secret may also be represented, without quotes, in any form supported by
-\fIipsec_ttodata\fP(3).
-.LP
-An RSA private key is a composite of eight generally large numbers. The notation
-used is a brace-enclosed list of field name and value pairs (see the example above).
-A suitable key, in a suitable format, may be generated by \fIipsec_rsasigkey\fP(8).
-The structure is very similar to that used by BIND 8.2.2 or later, but note that
-the numbers must have a ``0s'' prefix if they are in base 64. The order of
-the fields is fixed.
-.LP
-The first token an entry must start in
-the first column of its line. Subsequent tokens must be
-separated by whitespace,
-except for a colon token, which only needs to be followed by whitespace.
-A newline is taken as whitespace, but every
-line of an entry after the first must be indented.
-.LP
-Whitespace at the end of a line is ignored (except in the 0t
-notation for a key). At the start of line or
-after whitespace, \fB#\fP and the following text up to the end of the
-line is treated as a comment. Within entries, all lines must be
-indented (except for lines with no tokens).
-Outside entries, no line may be indented (this is to make sure that
-the file layout reflects its structure).
-.LP
-An include directive causes the contents of the named file to be processed
-before continuing with the current file. The filename is subject to
-``globbing'' as in \fIsh\fP(1), so every file with a matching name
-is processed. Includes may be nested to a modest
-depth (10, currently). If the filename doesn't start with a \fB/\fP, the
-directory containing the current file is prepended to the name. The
-include directive is a line that starts with the word \fBinclude\fP,
-followed by whitespace, followed by the filename (which must not contain
-whitespace).
-.SH FILES
-/etc/ipsec.secrets
-.SH SEE ALSO
-The rest of the FreeS/WAN distribution, in particular
-\fIipsec.conf\fP(5),
-\fIipsec\fP(8),
-\fIipsec_newhostkey\fP(8),
-\fIipsec_rsasigkey\fP(8),
-\fIipsec_showhostkey\fP(8),
-\fIipsec_auto\fP(8) \fB\-\-rereadsecrets\fP,
-and \fIipsec_pluto\fP(8) \fB\-\-listen\fP,.
-.br
-BIND 8.2.2 or later, ftp://ftp.isc.org/isc/bind/src/
-.SH HISTORY
-Designed for the FreeS/WAN project
-<http://www.freeswan.org>
-by D. Hugh Redelmeier.
-.SH BUGS
-If an ID is \fB0.0.0.0\fP, it will match \fB%any\fP;
-if it is \fB0::0\fP, it will match \fB%any6\fP.
diff --git a/programs/pluto/ipsec_doi.c b/programs/pluto/ipsec_doi.c
deleted file mode 100644
index f4ec22301..000000000
--- a/programs/pluto/ipsec_doi.c
+++ /dev/null
@@ -1,5696 +0,0 @@
-/* IPsec DOI and Oakley resolution routines
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_doi.c,v 1.43 2007/02/21 14:21:48 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-#include <sys/time.h> /* for gettimeofday */
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "state.h"
-#include "id.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "keys.h"
-#include "packet.h"
-#include "demux.h" /* needs packet.h */
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "kernel.h"
-#include "log.h"
-#include "cookie.h"
-#include "server.h"
-#include "spdb.h"
-#include "timer.h"
-#include "rnd.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "whack.h"
-#include "fetch.h"
-#include "pkcs7.h"
-#include "asn1.h"
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-#include "vendor.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-#include "kernel_alg.h"
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-#ifdef VIRTUAL_IP
-#include "virtual.h"
-#endif
-
-/*
- * are we sending Pluto's Vendor ID?
- */
-#ifdef VENDORID
-#define SEND_PLUTO_VID 1
-#else /* !VENDORID */
-#define SEND_PLUTO_VID 0
-#endif /* !VENDORID */
-
-/*
- * are we sending a Cisco Unity VID?
- */
-#ifdef CISCO_QUIRKS
-#define SEND_CISCO_UNITY_VID 1
-#else /* !CISCO_QUIRKS */
-#define SEND_CISCO_UNITY_VID 0
-#endif /* !CISCO_QUIRKS */
-
-/* MAGIC: perform f, a function that returns notification_t
- * and return from the ENCLOSING stf_status returning function if it fails.
- */
-#define RETURN_STF_FAILURE(f) \
- { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; }
-
-/* create output HDR as replica of input HDR */
-void
-echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
-{
- struct isakmp_hdr r_hdr = md->hdr; /* mostly same as incoming header */
-
- r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
- if (enc)
- r_hdr.isa_flags |= ISAKMP_FLAG_ENCRYPTION;
- /* some day, we may have to set r_hdr.isa_version */
- r_hdr.isa_np = np;
- if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
- impossible(); /* surely must have room and be well-formed */
-}
-
-/* Compute DH shared secret from our local secret and the peer's public value.
- * We make the leap that the length should be that of the group
- * (see quoted passage at start of ACCEPT_KE).
- */
-static void
-compute_dh_shared(struct state *st, const chunk_t g
-, const struct oakley_group_desc *group)
-{
- MP_INT mp_g, mp_shared;
- struct timeval tv0, tv1;
- unsigned long tv_diff;
-
- gettimeofday(&tv0, NULL);
- passert(st->st_sec_in_use);
- n_to_mpz(&mp_g, g.ptr, g.len);
- mpz_init(&mp_shared);
- mpz_powm(&mp_shared, &mp_g, &st->st_sec, group->modulus);
- mpz_clear(&mp_g);
- freeanychunk(st->st_shared); /* happens in odd error cases */
- st->st_shared = mpz_to_n(&mp_shared, group->bytes);
- mpz_clear(&mp_shared);
- gettimeofday(&tv1, NULL);
- tv_diff=(tv1.tv_sec - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec);
- DBG(DBG_CRYPT,
- DBG_log("compute_dh_shared(): time elapsed (%s): %ld usec"
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- , tv_diff);
- );
- /* if took more than 200 msec ... */
- if (tv_diff > 200000) {
- loglog(RC_LOG_SERIOUS, "WARNING: compute_dh_shared(): for %s took "
- "%ld usec"
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- , tv_diff);
- }
-
- DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared);
-}
-
-/* if we haven't already done so, compute a local DH secret (st->st_sec) and
- * the corresponding public value (g). This is emitted as a KE payload.
- */
-static bool
-build_and_ship_KE(struct state *st, chunk_t *g
-, const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np)
-{
- if (!st->st_sec_in_use)
- {
- u_char tmp[LOCALSECRETSIZE];
- MP_INT mp_g;
-
- get_rnd_bytes(tmp, LOCALSECRETSIZE);
- st->st_sec_in_use = TRUE;
- n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE);
-
- mpz_init(&mp_g);
- mpz_powm(&mp_g, &groupgenerator, &st->st_sec, group->modulus);
- freeanychunk(*g); /* happens in odd error cases */
- *g = mpz_to_n(&mp_g, group->bytes);
- mpz_clear(&mp_g);
- DBG(DBG_CRYPT,
- DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE);
- DBG_dump_chunk("Public DH value sent:\n", *g));
- }
- return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value");
-}
-
-/* accept_ke
- *
- * Check and accept DH public value (Gi or Gr) from peer's message.
- * According to RFC2409 "The Internet key exchange (IKE)" 5:
- * The Diffie-Hellman public value passed in a KE payload, in either
- * a phase 1 or phase 2 exchange, MUST be the length of the negotiated
- * Diffie-Hellman group enforced, if necessary, by pre-pending the
- * value with zeros.
- */
-static notification_t
-accept_KE(chunk_t *dest, const char *val_name
-, const struct oakley_group_desc *gr
-, pb_stream *pbs)
-{
- if (pbs_left(pbs) != gr->bytes)
- {
- loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required"
- , (unsigned) pbs_left(pbs), (unsigned) gr->bytes);
- /* XXX Could send notification back */
- return INVALID_KEY_INFORMATION;
- }
- clonereplacechunk(*dest, pbs->cur, pbs_left(pbs), val_name);
- DBG_cond_dump_chunk(DBG_CRYPT, "DH public value received:\n", *dest);
- return NOTHING_WRONG;
-}
-
-/* accept_PFS_KE
- *
- * Check and accept optional Quick Mode KE payload for PFS.
- * Extends ACCEPT_PFS to check whether KE is allowed or required.
- */
-static notification_t
-accept_PFS_KE(struct msg_digest *md, chunk_t *dest
-, const char *val_name, const char *msg_name)
-{
- struct state *st = md->st;
- struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
-
- if (ke_pd == NULL)
- {
- if (st->st_pfs_group != NULL)
- {
- loglog(RC_LOG_SERIOUS, "missing KE payload in %s message", msg_name);
- return INVALID_KEY_INFORMATION;
- }
- }
- else
- {
- if (st->st_pfs_group == NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s message KE payload requires a GROUP_DESCRIPTION attribute in SA"
- , msg_name);
- return INVALID_KEY_INFORMATION;
- }
- if (ke_pd->next != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s message contains several KE payloads; we accept at most one", msg_name);
- return INVALID_KEY_INFORMATION; /* ??? */
- }
- return accept_KE(dest, val_name, st->st_pfs_group, &ke_pd->pbs);
- }
- return NOTHING_WRONG;
-}
-
-static bool
-build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np
-, const char *name)
-{
- freeanychunk(*n);
- setchunk(*n, alloc_bytes(DEFAULT_NONCE_SIZE, name), DEFAULT_NONCE_SIZE);
- get_rnd_bytes(n->ptr, DEFAULT_NONCE_SIZE);
- return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
-}
-
-static bool
-collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
-{
- struct connection *d = find_host_connection(&md->iface->addr
- , pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
-
- for (; d != NULL; d = d->hp_next)
- {
- /* must be a road warrior connection */
- if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO)
- && d->spd.that.ca.ptr != NULL)
- {
- generalName_t *gn;
- bool new_entry = TRUE;
-
- for (gn = *top; gn != NULL; gn = gn->next)
- {
- if (same_dn(gn->name, d->spd.that.ca))
- {
- new_entry = FALSE;
- break;
- }
- }
- if (new_entry)
- {
- gn = alloc_thing(generalName_t, "generalName");
- gn->kind = GN_DIRECTORY_NAME;
- gn->name = d->spd.that.ca;
- gn->next = *top;
- *top = gn;
- }
- }
- }
- return *top != NULL;
-}
-
-static bool
-build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
-{
- pb_stream cr_pbs;
- struct isakmp_cr cr_hd;
- cr_hd.isacr_np = np;
- cr_hd.isacr_type = type;
-
- /* build CR header */
- if (!out_struct(&cr_hd, &isakmp_ipsec_cert_req_desc, outs, &cr_pbs))
- return FALSE;
-
- if (ca.ptr != NULL)
- {
- /* build CR body containing the distinguished name of the CA */
- if (!out_chunk(ca, &cr_pbs, "CA"))
- return FALSE;
- }
- close_output_pbs(&cr_pbs);
- return TRUE;
-}
-
-/* Send a notification to the peer. We could decide
- * whether to send the notification, based on the type and the
- * destination, if we care to.
- */
-static void
-send_notification(struct state *sndst, u_int16_t type, struct state *encst,
- msgid_t msgid, u_char *icookie, u_char *rcookie,
- u_char *spi, size_t spisize, u_char protoid)
-{
- u_char buffer[1024];
- pb_stream pbs, r_hdr_pbs;
- u_char *r_hashval = NULL; /* where in reply to jam hash value */
- u_char *r_hash_start = NULL; /* start of what is to be hashed */
-
- passert((sndst) && (sndst->st_connection));
-
- plog("sending %snotification %s to %s:%u"
- , encst ? "encrypted " : ""
- , enum_name(&notification_names, type)
- , ip_str(&sndst->st_connection->spd.that.host_addr)
- , (unsigned)sndst->st_connection->spd.that.host_port);
-
- memset(buffer, 0, sizeof(buffer));
- init_pbs(&pbs, buffer, sizeof(buffer), "ISAKMP notify");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = encst ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_N;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = encst ? ISAKMP_FLAG_ENCRYPTION : 0;
- if (icookie)
- memcpy(hdr.isa_icookie, icookie, COOKIE_SIZE);
- if (rcookie)
- memcpy(hdr.isa_rcookie, rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &pbs, &r_hdr_pbs))
- impossible();
- }
-
- /* HASH -- value to be filled later */
- if (encst)
- {
- pb_stream hash_pbs;
- if (!out_generic(ISAKMP_NEXT_N, &isakmp_hash_desc, &r_hdr_pbs,
- &hash_pbs))
- impossible();
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(
- encst->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
- impossible();
- close_output_pbs(&hash_pbs);
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH */
- }
-
- /* Notification Payload */
- {
- pb_stream not_pbs;
- struct isakmp_notification isan;
-
- isan.isan_doi = ISAKMP_DOI_IPSEC;
- isan.isan_np = ISAKMP_NEXT_NONE;
- isan.isan_type = type;
- isan.isan_spisize = spisize;
- isan.isan_protoid = protoid;
-
- if (!out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, &not_pbs)
- || !out_raw(spi, spisize, &not_pbs, "spi"))
- impossible();
- close_output_pbs(&not_pbs);
- }
-
- /* calculate hash value and patch into Hash Payload */
- if (encst)
- {
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, encst->st_oakley.hasher, encst->st_skeyid_a);
- hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size);
- )
- }
-
- /* Encrypt message (preserve st_iv and st_new_iv) */
- if (encst)
- {
- u_char old_iv[MAX_DIGEST_LEN];
- u_char new_iv[MAX_DIGEST_LEN];
-
- u_int old_iv_len = encst->st_iv_len;
- u_int new_iv_len = encst->st_new_iv_len;
-
- if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
- impossible();
-
- memcpy(old_iv, encst->st_iv, old_iv_len);
- memcpy(new_iv, encst->st_new_iv, new_iv_len);
-
- if (!IS_ISAKMP_SA_ESTABLISHED(encst->st_state))
- {
- memcpy(encst->st_ph1_iv, encst->st_new_iv, encst->st_new_iv_len);
- encst->st_ph1_iv_len = encst->st_new_iv_len;
- }
- init_phase2_iv(encst, &msgid);
- if (!encrypt_message(&r_hdr_pbs, encst))
- impossible();
-
- /* restore preserved st_iv and st_new_iv */
- memcpy(encst->st_iv, old_iv, old_iv_len);
- memcpy(encst->st_new_iv, new_iv, new_iv_len);
- encst->st_iv_len = old_iv_len;
- encst->st_new_iv_len = new_iv_len;
- }
- else
- {
- close_output_pbs(&r_hdr_pbs);
- }
-
- /* Send packet (preserve st_tpacket) */
- {
- chunk_t saved_tpacket = sndst->st_tpacket;
-
- setchunk(sndst->st_tpacket, pbs.start, pbs_offset(&pbs));
- send_packet(sndst, "ISAKMP notify");
- sndst->st_tpacket = saved_tpacket;
- }
-}
-
-void
-send_notification_from_state(struct state *st, enum state_kind state,
- u_int16_t type)
-{
- struct state *p1st;
-
- passert(st);
-
- if (state == STATE_UNDEFINED)
- state = st->st_state;
-
- if (IS_QUICK(state)) {
- p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
- if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))) {
- loglog(RC_LOG_SERIOUS,
- "no Phase1 state for Quick mode notification");
- return;
- }
- send_notification(st, type, p1st, generate_msgid(p1st),
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
- else if (IS_ISAKMP_ENCRYPTED(state)) {
- send_notification(st, type, st, generate_msgid(st),
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
- else {
- /* no ISAKMP SA established - don't encrypt notification */
- send_notification(st, type, NULL, 0,
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
-}
-
-void
-send_notification_from_md(struct msg_digest *md, u_int16_t type)
-{
- /**
- * Create a dummy state to be able to use send_packet in
- * send_notification
- *
- * we need to set:
- * st_connection->that.host_addr
- * st_connection->that.host_port
- * st_connection->interface
- */
- struct state st;
- struct connection cnx;
-
- passert(md);
-
- memset(&st, 0, sizeof(st));
- memset(&cnx, 0, sizeof(cnx));
- st.st_connection = &cnx;
- cnx.spd.that.host_addr = md->sender;
- cnx.spd.that.host_port = md->sender_port;
- cnx.interface = md->iface;
-
- send_notification(&st, type, NULL, 0,
- md->hdr.isa_icookie, md->hdr.isa_rcookie, NULL, 0, PROTO_ISAKMP);
-}
-
-/* Send a Delete Notification to announce deletion of ISAKMP SA or
- * inbound IPSEC SAs. Does nothing if no such SAs are being deleted.
- * Delete Notifications cannot announce deletion of outbound IPSEC/ISAKMP SAs.
- */
-void
-send_delete(struct state *st)
-{
- pb_stream reply_pbs;
- pb_stream r_hdr_pbs;
- msgid_t msgid;
- u_char buffer[8192];
- struct state *p1st;
- ip_said said[EM_MAXRELSPIS];
- ip_said *ns = said;
- u_char
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
- bool isakmp_sa = FALSE;
-
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
- if (p1st == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("no Phase 1 state for Delete"));
- return;
- }
-
- if (st->st_ah.present)
- {
- ns->spi = st->st_ah.our_spi;
- ns->dst = st->st_connection->spd.this.host_addr;
- ns->proto = PROTO_IPSEC_AH;
- ns++;
- }
- if (st->st_esp.present)
- {
- ns->spi = st->st_esp.our_spi;
- ns->dst = st->st_connection->spd.this.host_addr;
- ns->proto = PROTO_IPSEC_ESP;
- ns++;
- }
-
- passert(ns != said); /* there must be some SAs to delete */
- }
- else if (IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- p1st = st;
- isakmp_sa = TRUE;
- }
- else
- {
- return; /* nothing to do */
- }
-
- msgid = generate_msgid(p1st);
-
- zero(buffer);
- init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs))
- impossible();
- }
-
- /* HASH -- value to be filled later */
- {
- pb_stream hash_pbs;
-
- if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
- impossible();
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(p1st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH(1)"))
- impossible();
- close_output_pbs(&hash_pbs);
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */
- }
-
- /* Delete Payloads */
- if (isakmp_sa)
- {
- pb_stream del_pbs;
- struct isakmp_delete isad;
- u_char isakmp_spi[2*COOKIE_SIZE];
-
- isad.isad_doi = ISAKMP_DOI_IPSEC;
- isad.isad_np = ISAKMP_NEXT_NONE;
- isad.isad_spisize = (2 * COOKIE_SIZE);
- isad.isad_protoid = PROTO_ISAKMP;
- isad.isad_nospi = 1;
-
- memcpy(isakmp_spi, st->st_icookie, COOKIE_SIZE);
- memcpy(isakmp_spi+COOKIE_SIZE, st->st_rcookie, COOKIE_SIZE);
-
- if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
- || !out_raw(&isakmp_spi, (2*COOKIE_SIZE), &del_pbs, "delete payload"))
- impossible();
- close_output_pbs(&del_pbs);
- }
- else
- {
- while (ns != said)
- {
-
- pb_stream del_pbs;
- struct isakmp_delete isad;
-
- ns--;
- isad.isad_doi = ISAKMP_DOI_IPSEC;
- isad.isad_np = ns == said? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D;
- isad.isad_spisize = sizeof(ipsec_spi_t);
- isad.isad_protoid = ns->proto;
-
- isad.isad_nospi = 1;
- if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
- || !out_raw(&ns->spi, sizeof(ipsec_spi_t), &del_pbs, "delete payload"))
- impossible();
- close_output_pbs(&del_pbs);
- }
- }
-
- /* calculate hash value and patch into Hash Payload */
- {
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, p1st->st_oakley.hasher, p1st->st_skeyid_a);
- hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH(1) computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size);
- )
- }
-
- /* Do a dance to avoid needing a new state object.
- * We use the Phase 1 State. This is the one with right
- * IV, for one thing.
- * The tricky bits are:
- * - we need to preserve (save/restore) st_iv (but not st_iv_new)
- * - we need to preserve (save/restore) st_tpacket.
- */
- {
- u_char old_iv[MAX_DIGEST_LEN];
- chunk_t saved_tpacket = p1st->st_tpacket;
-
- memcpy(old_iv, p1st->st_iv, p1st->st_iv_len);
- init_phase2_iv(p1st, &msgid);
-
- if (!encrypt_message(&r_hdr_pbs, p1st))
- impossible();
-
- setchunk(p1st->st_tpacket, reply_pbs.start, pbs_offset(&reply_pbs));
- send_packet(p1st, "delete notify");
- p1st->st_tpacket = saved_tpacket;
-
- /* get back old IV for this state */
- memcpy(p1st->st_iv, old_iv, p1st->st_iv_len);
- }
-}
-
-void
-accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
-{
- struct isakmp_delete *d = &(p->payload.delete);
- size_t sizespi;
- int i;
-
- if (!md->encrypted)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: not encrypted");
- return;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- /* can't happen (if msg is encrypt), but just to be sure */
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA not established");
- return;
- }
-
- if (d->isad_nospi == 0)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: no SPI");
- return;
- }
-
- switch (d->isad_protoid)
- {
- case PROTO_ISAKMP:
- sizespi = 2 * COOKIE_SIZE;
- break;
- case PROTO_IPSEC_AH:
- case PROTO_IPSEC_ESP:
- sizespi = sizeof(ipsec_spi_t);
- break;
- case PROTO_IPCOMP:
- /* nothing interesting to delete */
- return;
- default:
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: unknown Protocol ID (%s)"
- , enum_show(&protocol_names, d->isad_protoid));
- return;
- }
-
- if (d->isad_spisize != sizespi)
- {
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: bad SPI size (%d) for %s"
- , d->isad_spisize, enum_show(&protocol_names, d->isad_protoid));
- return;
- }
-
- if (pbs_left(&p->pbs) != d->isad_nospi * sizespi)
- {
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: invalid payload size");
- return;
- }
-
- for (i = 0; i < d->isad_nospi; i++)
- {
- u_char *spi = p->pbs.cur + (i * sizespi);
-
- if (d->isad_protoid == PROTO_ISAKMP)
- {
- /**
- * ISAKMP
- */
- struct state *dst = find_state(spi /*iCookie*/
- , spi+COOKIE_SIZE /*rCookie*/
- , &st->st_connection->spd.that.host_addr
- , MAINMODE_MSGID);
-
- if (dst == NULL)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA not found (maybe expired)");
- }
- else if (!same_peer_ids(st->st_connection, dst->st_connection, NULL))
- {
- /* we've not authenticated the relevant identities */
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA used to convey Delete has different IDs from ISAKMP SA it deletes");
- }
- else
- {
- struct connection *oldc;
-
- oldc = cur_connection;
- set_cur_connection(dst->st_connection);
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, dst);
-#endif
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "deleting ISAKMP State #%lu", dst->st_serialno);
- delete_state(dst);
- set_cur_connection(oldc);
- }
- }
- else
- {
- /**
- * IPSEC (ESP/AH)
- */
- bool bogus;
- struct state *dst = find_phase2_state_to_delete(st
- , d->isad_protoid
- , *(ipsec_spi_t *)spi /* network order */
- , &bogus);
-
- if (dst == NULL)
- {
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: %s SA(0x%08lx) not found (%s)"
- , enum_show(&protocol_names, d->isad_protoid)
- , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
- , bogus ? "our SPI - bogus implementation" : "maybe expired");
- }
- else
- {
- struct connection *rc = dst->st_connection;
- struct connection *oldc;
-
- oldc = cur_connection;
- set_cur_connection(rc);
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, dst);
-#endif
- if (rc->newest_ipsec_sa == dst->st_serialno
- && (rc->policy & POLICY_UP))
- {
- /* Last IPSec SA for a permanent connection that we
- * have initiated. Replace it in a few seconds.
- *
- * Useful if the other peer is rebooting.
- */
-#define DELETE_SA_DELAY EVENT_RETRANSMIT_DELAY_0
- if (dst->st_event != NULL
- && dst->st_event->ev_type == EVENT_SA_REPLACE
- && dst->st_event->ev_time <= DELETE_SA_DELAY + now())
- {
- /* Patch from Angus Lees to ignore retransmited
- * Delete SA.
- */
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "already replacing IPSEC State #%lu in %d seconds"
- , dst->st_serialno, (int)(dst->st_event->ev_time - now()));
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "replace IPSEC State #%lu in %d seconds"
- , dst->st_serialno, DELETE_SA_DELAY);
- dst->st_margin = DELETE_SA_DELAY;
- delete_event(dst);
- event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, dst);
- }
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "received Delete SA(0x%08lx) payload: "
- "deleting IPSEC State #%lu"
- , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
- , dst->st_serialno);
- delete_state(dst);
- }
-
- /* reset connection */
- set_cur_connection(oldc);
- }
- }
- }
-}
-
-/* The whole message must be a multiple of 4 octets.
- * I'm not sure where this is spelled out, but look at
- * rfc2408 3.6 Transform Payload.
- * Note: it talks about 4 BYTE boundaries!
- */
-void
-close_message(pb_stream *pbs)
-{
- size_t padding = pad_up(pbs_offset(pbs), 4);
-
- if (padding != 0)
- (void) out_zero(padding, pbs, "message padding");
- close_output_pbs(pbs);
-}
-
-/* Initiate an Oakley Main Mode exchange.
- * --> HDR;SA
- * Note: this is not called from demux.c
- */
-static stf_status
-main_outI1(int whack_sock, struct connection *c, struct state *predecessor
- , lset_t policy, unsigned long try)
-{
- struct state *st = new_state();
- pb_stream reply; /* not actually a reply, but you know what I mean */
- pb_stream rbody;
-
- int vids_to_send = 0;
-
- /* set up new state */
- st->st_connection = c;
- set_cur_state(st); /* we must reset before exit */
- st->st_policy = policy & ~POLICY_IPSEC_MASK;
- st->st_whack_sock = whack_sock;
- st->st_try = try;
- st->st_state = STATE_MAIN_I1;
-
- /* determine how many Vendor ID payloads we will be sending */
- if (SEND_PLUTO_VID)
- vids_to_send++;
- if (SEND_CISCO_UNITY_VID)
- vids_to_send++;
- if (c->spd.this.cert.type == CERT_PGP)
- vids_to_send++;
- /* always send XAUTH Vendor ID */
- vids_to_send++;
- /* always send DPD Vendor ID */
- vids_to_send++;
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- vids_to_send++;
-#endif
-
- get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);
-
- insert_state(st); /* needs cookies, connection, and msgid (0) */
-
- if (HAS_IPSEC_POLICY(policy))
- add_pending(dup_any(whack_sock), st, c, policy, 1
- , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);
-
- if (predecessor == NULL)
- plog("initiating Main Mode");
- else
- plog("initiating Main Mode to replace #%lu", predecessor->st_serialno);
-
- /* set up reply */
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_SA;
- hdr.isa_xchg = ISAKMP_XCHG_IDPROT;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- /* R-cookie, flags and MessageID are left zero */
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* SA out */
- {
- u_char *sa_start = rbody.cur;
- lset_t auth_policy = policy & POLICY_ID_AUTH_MASK;
-
- if (!out_sa(&rbody, &oakley_sadb, st, TRUE
- , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
-
- /* save initiator SA for later HASH */
- passert(st->st_p1isa.ptr == NULL); /* no leak! (MUST be first time) */
- clonetochunk(st->st_p1isa, sa_start, rbody.cur - sa_start
- , "sa in main_outI1");
- }
-
- /* if enabled send Pluto Vendor ID */
- if (SEND_PLUTO_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_STRONGSWAN))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* if enabled send Cisco Unity Vendor ID */
- if (SEND_CISCO_UNITY_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_CISCO_UNITY))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
- /* if we have an OpenPGP certificate we assume an
- * OpenPGP peer and have to send the Vendor ID
- */
- if (c->spd.this.cert.type == CERT_PGP)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_OPENPGP))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* Announce our ability to do eXtended AUTHentication to the peer */
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_XAUTH))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
-
- /* Announce our ability to do Dead Peer Detection to the peer */
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_DPD))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_enabled)
- {
- /* Add supported NAT-Traversal VID */
- if (!nat_traversal_add_vid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-#endif
-
- close_message(&rbody);
- close_output_pbs(&reply);
-
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "reply packet for main_outI1");
-
- /* Transmit */
-
- send_packet(st, "main_outI1");
-
- /* Set up a retransmission event, half a minute henceforth */
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-
- if (predecessor != NULL)
- {
- update_pending(predecessor, st);
- whack_log(RC_NEW_STATE + STATE_MAIN_I1
- , "%s: initiate, replacing #%lu"
- , enum_name(&state_names, st->st_state)
- , predecessor->st_serialno);
- }
- else
- {
- whack_log(RC_NEW_STATE + STATE_MAIN_I1
- , "%s: initiate", enum_name(&state_names, st->st_state));
- }
- reset_cur_state();
- return STF_OK;
-}
-
-void
-ipsecdoi_initiate(int whack_sock
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
-{
- /* If there's already an ISAKMP SA established, use that and
- * go directly to Quick Mode. We are even willing to use one
- * that is still being negotiated, but only if we are the Initiator
- * (thus we can be sure that the IDs are not going to change;
- * other issues around intent might matter).
- * Note: there is no way to initiate with a Road Warrior.
- */
- struct state *st = find_phase1_state(c
- , ISAKMP_SA_ESTABLISHED_STATES | PHASE1_INITIATOR_STATES);
-
- if (st == NULL)
- {
- (void) main_outI1(whack_sock, c, NULL, policy, try);
- }
- else if (HAS_IPSEC_POLICY(policy))
- {
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- /* leave our Phase 2 negotiation pending */
- add_pending(whack_sock, st, c, policy, try, replacing);
- }
- else
- {
- /* ??? we assume that peer_nexthop_sin isn't important:
- * we already have it from when we negotiated the ISAKMP SA!
- * It isn't clear what to do with the error return.
- */
- (void) quick_outI1(whack_sock, st, c, policy, try, replacing);
- }
- }
- else
- {
- close_any(whack_sock);
- }
-}
-
-/* Replace SA with a fresh one that is similar
- *
- * Shares some logic with ipsecdoi_initiate, but not the same!
- * - we must not reuse the ISAKMP SA if we are trying to replace it!
- * - if trying to replace IPSEC SA, use ipsecdoi_initiate to build
- * ISAKMP SA if needed.
- * - duplicate whack fd, if live.
- * Does not delete the old state -- someone else will do that.
- */
-void
-ipsecdoi_replace(struct state *st, unsigned long try)
-{
- int whack_sock = dup_any(st->st_whack_sock);
- lset_t policy = st->st_policy;
-
- if (IS_PHASE1(st->st_state))
- {
- passert(!HAS_IPSEC_POLICY(policy));
- (void) main_outI1(whack_sock, st->st_connection, st, policy, try);
- }
- else
- {
- /* Add features of actual old state to policy. This ensures
- * that rekeying doesn't downgrade security. I admit that
- * this doesn't capture everything.
- */
- if (st->st_pfs_group != NULL)
- policy |= POLICY_PFS;
- if (st->st_ah.present)
- {
- policy |= POLICY_AUTHENTICATE;
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
- }
- if (st->st_esp.present && st->st_esp.attrs.transid != ESP_NULL)
- {
- policy |= POLICY_ENCRYPT;
- if (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
- }
- if (st->st_ipcomp.present)
- {
- policy |= POLICY_COMPRESS;
- if (st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
- }
- passert(HAS_IPSEC_POLICY(policy));
- ipsecdoi_initiate(whack_sock, st->st_connection, policy, try
- , st->st_serialno);
- }
-}
-
-/* SKEYID for preshared keys.
- * See draft-ietf-ipsec-ike-01.txt 4.1
- */
-static bool
-skeyid_preshared(struct state *st)
-{
- const chunk_t *pss = get_preshared_secret(st->st_connection);
-
- if (pss == NULL)
- {
- loglog(RC_LOG_SERIOUS, "preshared secret disappeared!");
- return FALSE;
- }
- else
- {
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, *pss);
- hmac_update_chunk(&ctx, st->st_ni);
- hmac_update_chunk(&ctx, st->st_nr);
- hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_preshared()", &ctx);
- return TRUE;
- }
-}
-
-static bool
-skeyid_digisig(struct state *st)
-{
- struct hmac_ctx ctx;
- chunk_t nir;
-
- /* We need to hmac_init with the concatenation of Ni_b and Nr_b,
- * so we have to build a temporary concatentation.
- */
- nir.len = st->st_ni.len + st->st_nr.len;
- nir.ptr = alloc_bytes(nir.len, "Ni + Nr in skeyid_digisig");
- memcpy(nir.ptr, st->st_ni.ptr, st->st_ni.len);
- memcpy(nir.ptr+st->st_ni.len, st->st_nr.ptr, st->st_nr.len);
- hmac_init_chunk(&ctx, st->st_oakley.hasher, nir);
- pfree(nir.ptr);
-
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_digisig()", &ctx);
- return TRUE;
-}
-
-/* Generate the SKEYID_* and new IV
- * See draft-ietf-ipsec-ike-01.txt 4.1
- */
-static bool
-generate_skeyids_iv(struct state *st)
-{
- /* Generate the SKEYID */
- switch (st->st_oakley.auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- if (!skeyid_preshared(st))
- return FALSE;
- break;
-
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- if (!skeyid_digisig(st))
- return FALSE;
- break;
-
- case OAKLEY_DSS_SIG:
- /* XXX */
-
- case OAKLEY_RSA_ENC:
- case OAKLEY_RSA_ENC_REV:
- case OAKLEY_ELGAMAL_ENC:
- case OAKLEY_ELGAMAL_ENC_REV:
- /* XXX */
-
- default:
- bad_case(st->st_oakley.auth);
- }
-
- /* generate SKEYID_* from SKEYID */
- {
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid);
-
- /* SKEYID_D */
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\0", 1);
- hmac_final_chunk(st->st_skeyid_d, "st_skeyid_d in generate_skeyids_iv()", &ctx);
-
- /* SKEYID_A */
- hmac_reinit(&ctx);
- hmac_update_chunk(&ctx, st->st_skeyid_d);
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\1", 1);
- hmac_final_chunk(st->st_skeyid_a, "st_skeyid_a in generate_skeyids_iv()", &ctx);
-
- /* SKEYID_E */
- hmac_reinit(&ctx);
- hmac_update_chunk(&ctx, st->st_skeyid_a);
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\2", 1);
- hmac_final_chunk(st->st_skeyid_e, "st_skeyid_e in generate_skeyids_iv()", &ctx);
- }
-
- /* generate IV */
- {
- union hash_ctx hash_ctx;
- const struct hash_desc *h = st->st_oakley.hasher;
-
- st->st_new_iv_len = h->hash_digest_size;
- passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
-
- DBG(DBG_CRYPT,
- DBG_dump_chunk("DH_i:", st->st_gi);
- DBG_dump_chunk("DH_r:", st->st_gr);
- );
- h->hash_init(&hash_ctx);
- h->hash_update(&hash_ctx, st->st_gi.ptr, st->st_gi.len);
- h->hash_update(&hash_ctx, st->st_gr.ptr, st->st_gr.len);
- h->hash_final(st->st_new_iv, &hash_ctx);
- }
-
- /* Oakley Keying Material
- * Derived from Skeyid_e: if it is not big enough, generate more
- * using the PRF.
- * See RFC 2409 "IKE" Appendix B
- */
- {
- /* const size_t keysize = st->st_oakley.encrypter->keydeflen/BITS_PER_BYTE; */
- const size_t keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;
- u_char keytemp[MAX_OAKLEY_KEY_LEN + MAX_DIGEST_LEN];
- u_char *k = st->st_skeyid_e.ptr;
-
- if (keysize > st->st_skeyid_e.len)
- {
- struct hmac_ctx ctx;
- size_t i = 0;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_e);
- hmac_update(&ctx, "\0", 1);
- for (;;)
- {
- hmac_final(&keytemp[i], &ctx);
- i += ctx.hmac_digest_size;
- if (i >= keysize)
- break;
- hmac_reinit(&ctx);
- hmac_update(&ctx, &keytemp[i - ctx.hmac_digest_size], ctx.hmac_digest_size);
- }
- k = keytemp;
- }
- clonereplacechunk(st->st_enc_key, k, keysize, "st_enc_key");
- }
-
- DBG(DBG_CRYPT,
- DBG_dump_chunk("Skeyid: ", st->st_skeyid);
- DBG_dump_chunk("Skeyid_d:", st->st_skeyid_d);
- DBG_dump_chunk("Skeyid_a:", st->st_skeyid_a);
- DBG_dump_chunk("Skeyid_e:", st->st_skeyid_e);
- DBG_dump_chunk("enc key:", st->st_enc_key);
- DBG_dump("IV:", st->st_new_iv, st->st_new_iv_len));
- return TRUE;
-}
-
-/* Generate HASH_I or HASH_R for ISAKMP Phase I.
- * This will *not* generate other hash payloads (eg. Phase II or Quick Mode,
- * New Group Mode, or ISAKMP Informational Exchanges).
- * If the hashi argument is TRUE, generate HASH_I; if FALSE generate HASH_R.
- * If hashus argument is TRUE, we're generating a hash for our end.
- * See RFC2409 IKE 5.
- *
- * Generating the SIG_I and SIG_R for DSS is an odd perversion of this:
- * Most of the logic is the same, but SHA-1 is used in place of HMAC-whatever.
- * The extensive common logic is embodied in main_mode_hash_body().
- * See draft-ietf-ipsec-ike-01.txt 4.1 and 6.1.1.2
- */
-
-typedef void (*hash_update_t)(union hash_ctx *, const u_char *, size_t) ;
-static void
-main_mode_hash_body(struct state *st
-, bool hashi /* Initiator? */
-, const pb_stream *idpl /* ID payload, as PBS */
-, union hash_ctx *ctx
-, void (*hash_update_void)(void *, const u_char *input, size_t))
-{
-#define HASH_UPDATE_T (union hash_ctx *, const u_char *input, unsigned int len)
- hash_update_t hash_update=(hash_update_t) hash_update_void;
-#if 0 /* if desperate to debug hashing */
-# define hash_update(ctx, input, len) { \
- DBG_dump("hash input", input, len); \
- (hash_update)(ctx, input, len); \
- }
-#endif
-
-# define hash_update_chunk(ctx, ch) hash_update((ctx), (ch).ptr, (ch).len)
-
- if (hashi)
- {
- hash_update_chunk(ctx, st->st_gi);
- hash_update_chunk(ctx, st->st_gr);
- hash_update(ctx, st->st_icookie, COOKIE_SIZE);
- hash_update(ctx, st->st_rcookie, COOKIE_SIZE);
- }
- else
- {
- hash_update_chunk(ctx, st->st_gr);
- hash_update_chunk(ctx, st->st_gi);
- hash_update(ctx, st->st_rcookie, COOKIE_SIZE);
- hash_update(ctx, st->st_icookie, COOKIE_SIZE);
- }
-
- DBG(DBG_CRYPT, DBG_log("hashing %lu bytes of SA"
- , (unsigned long) (st->st_p1isa.len - sizeof(struct isakmp_generic))));
-
- /* SA_b */
- hash_update(ctx, st->st_p1isa.ptr + sizeof(struct isakmp_generic)
- , st->st_p1isa.len - sizeof(struct isakmp_generic));
-
- /* Hash identification payload, without generic payload header.
- * We used to reconstruct ID Payload for this purpose, but now
- * we use the bytes as they appear on the wire to avoid
- * "spelling problems".
- */
- hash_update(ctx
- , idpl->start + sizeof(struct isakmp_generic)
- , pbs_offset(idpl) - sizeof(struct isakmp_generic));
-
-# undef hash_update_chunk
-# undef hash_update
-}
-
-static size_t /* length of hash */
-main_mode_hash(struct state *st
-, u_char *hash_val /* resulting bytes */
-, bool hashi /* Initiator? */
-, const pb_stream *idpl) /* ID payload, as PBS; cur must be at end */
-{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid);
- main_mode_hash_body(st, hashi, idpl, &ctx.hash_ctx, ctx.h->hash_update);
- hmac_final(hash_val, &ctx);
- return ctx.hmac_digest_size;
-}
-
-#if 0 /* only needed for DSS */
-static void
-main_mode_sha1(struct state *st
-, u_char *hash_val /* resulting bytes */
-, size_t *hash_len /* length of hash */
-, bool hashi /* Initiator? */
-, const pb_stream *idpl) /* ID payload, as PBS */
-{
- union hash_ctx ctx;
-
- SHA1Init(&ctx.ctx_sha1);
- SHA1Update(&ctx.ctx_sha1, st->st_skeyid.ptr, st->st_skeyid.len);
- *hash_len = SHA1_DIGEST_SIZE;
- main_mode_hash_body(st, hashi, idpl, &ctx
- , (void (*)(union hash_ctx *, const u_char *, unsigned int))&SHA1Update);
- SHA1Final(hash_val, &ctx.ctx_sha1);
-}
-#endif
-
-/* Create an RSA signature of a hash.
- * Poorly specified in draft-ietf-ipsec-ike-01.txt 6.1.1.2.
- * Use PKCS#1 version 1.5 encryption of hash (called
- * RSAES-PKCS1-V1_5) in PKCS#2.
- */
-static size_t
-RSA_sign_hash(struct connection *c
-, u_char sig_val[RSA_MAX_OCTETS]
-, const u_char *hash_val, size_t hash_len)
-{
- size_t sz = 0;
- smartcard_t *sc = c->spd.this.sc;
-
- if (sc == NULL) /* no smartcard */
- {
- const struct RSA_private_key *k = get_RSA_private_key(c);
-
- if (k == NULL)
- return 0; /* failure: no key to use */
-
- sz = k->pub.k;
- passert(RSA_MIN_OCTETS <= sz && 4 + hash_len < sz && sz <= RSA_MAX_OCTETS);
- sign_hash(k, hash_val, hash_len, sig_val, sz);
- }
- else if (sc->valid) /* if valid pin then sign hash on the smartcard */
- {
- lock_certs_and_keys("RSA_sign_hash");
- if (!scx_establish_context(sc) || !scx_login(sc))
- {
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- return 0;
- }
-
- sz = scx_get_keylength(sc);
- if (sz == 0)
- {
- plog("failed to get keylength from smartcard");
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- return 0;
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
- )
- sz = scx_sign_hash(sc, hash_val, hash_len, sig_val, sz) ? sz : 0;
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- }
- return sz;
-}
-
-/* Check a Main Mode RSA Signature against computed hash using RSA public key k.
- *
- * As a side effect, on success, the public key is copied into the
- * state object to record the authenticator.
- *
- * Can fail because wrong public key is used or because hash disagrees.
- * We distinguish because diagnostics should also.
- *
- * The result is NULL if the Signature checked out.
- * Otherwise, the first character of the result indicates
- * how far along failure occurred. A greater character signifies
- * greater progress.
- *
- * Classes:
- * 0 reserved for caller
- * 1 SIG length doesn't match key length -- wrong key
- * 2-8 malformed ECB after decryption -- probably wrong key
- * 9 decrypted hash != computed hash -- probably correct key
- *
- * Although the math should be the same for generating and checking signatures,
- * it is not: the knowledge of the private key allows more efficient (i.e.
- * different) computation for encryption.
- */
-static err_t
-try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN], size_t hash_len
-, const pb_stream *sig_pbs, pubkey_t *kr
-, struct state *st)
-{
- const u_char *sig_val = sig_pbs->cur;
- size_t sig_len = pbs_left(sig_pbs);
- u_char s[RSA_MAX_OCTETS]; /* for decrypted sig_val */
- u_char *hash_in_s = &s[sig_len - hash_len];
- const struct RSA_public_key *k = &kr->u.rsa;
-
- /* decrypt the signature -- reversing RSA_sign_hash */
- if (sig_len != k->k)
- {
- /* XXX notification: INVALID_KEY_INFORMATION */
- return "1" "SIG length does not match public key length";
- }
-
- /* actual exponentiation; see PKCS#1 v2.0 5.1 */
- {
- chunk_t temp_s;
- mpz_t c;
-
- n_to_mpz(c, sig_val, sig_len);
- mpz_powm(c, c, &k->e, &k->n);
-
- temp_s = mpz_to_n(c, sig_len); /* back to octets */
- memcpy(s, temp_s.ptr, sig_len);
- pfree(temp_s.ptr);
- mpz_clear(c);
- }
-
- /* sanity check on signature: see if it matches
- * PKCS#1 v1.5 8.1 encryption-block formatting
- */
- {
- err_t ugh = NULL;
-
- if (s[0] != 0x00)
- ugh = "2" "no leading 00";
- else if (hash_in_s[-1] != 0x00)
- ugh = "3" "00 separator not present";
- else if (s[1] == 0x01)
- {
- const u_char *p;
-
- for (p = &s[2]; p != hash_in_s - 1; p++)
- {
- if (*p != 0xFF)
- {
- ugh = "4" "invalid Padding String";
- break;
- }
- }
- }
- else if (s[1] == 0x02)
- {
- const u_char *p;
-
- for (p = &s[2]; p != hash_in_s - 1; p++)
- {
- if (*p == 0x00)
- {
- ugh = "5" "invalid Padding String";
- break;
- }
- }
- }
- else
- ugh = "6" "Block Type not 01 or 02";
-
- if (ugh != NULL)
- {
- /* note: it might be a good idea to make sure that
- * an observer cannot tell what kind of failure happened.
- * I don't know what this means in practice.
- */
- /* We probably selected the wrong public key for peer:
- * SIG Payload decrypted into malformed ECB
- */
- /* XXX notification: INVALID_KEY_INFORMATION */
- return ugh;
- }
- }
-
- /* We have the decoded hash: see if it matches. */
- if (memcmp(hash_val, hash_in_s, hash_len) != 0)
- {
- /* good: header, hash, signature, and other payloads well-formed
- * good: we could find an RSA Sig key for the peer.
- * bad: hash doesn't match
- * Guess: sides disagree about key to be used.
- */
- DBG_cond_dump(DBG_CRYPT, "decrypted SIG", s, sig_len);
- DBG_cond_dump(DBG_CRYPT, "computed HASH", hash_val, hash_len);
- /* XXX notification: INVALID_HASH_INFORMATION */
- return "9" "authentication failure: received SIG does not match computed HASH, but message is well-formed";
- }
-
- /* Success: copy successful key into state.
- * There might be an old one if we previously aborted this
- * state transition.
- */
- unreference_key(&st->st_peer_pubkey);
- st->st_peer_pubkey = reference_key(kr);
-
- return NULL; /* happy happy */
-}
-
-/* Check signature against all RSA public keys we can find.
- * If we need keys from DNS KEY records, and they haven't been fetched,
- * return STF_SUSPEND to ask for asynch DNS lookup.
- *
- * Note: parameter keys_from_dns contains results of DNS lookup for key
- * or is NULL indicating lookup not yet tried.
- *
- * take_a_crack is a helper function. Mostly forensic.
- * If only we had coroutines.
- */
-struct tac_state {
- /* RSA_check_signature's args that take_a_crack needs */
- struct state *st;
- const u_char *hash_val;
- size_t hash_len;
- const pb_stream *sig_pbs;
-
- /* state carried between calls */
- err_t best_ugh; /* most successful failure */
- int tried_cnt; /* number of keys tried */
- char tried[50]; /* keyids of tried public keys */
- char *tn; /* roof of tried[] */
-};
-
-static bool
-take_a_crack(struct tac_state *s
-, pubkey_t *kr
-, const char *story USED_BY_DEBUG)
-{
- err_t ugh = try_RSA_signature(s->hash_val, s->hash_len, s->sig_pbs
- , kr, s->st);
- const struct RSA_public_key *k = &kr->u.rsa;
-
- s->tried_cnt++;
- if (ugh == NULL)
- {
- DBG(DBG_CRYPT | DBG_CONTROL
- , DBG_log("an RSA Sig check passed with *%s [%s]"
- , k->keyid, story));
- return TRUE;
- }
- else
- {
- DBG(DBG_CRYPT
- , DBG_log("an RSA Sig check failure %s with *%s [%s]"
- , ugh + 1, k->keyid, story));
- if (s->best_ugh == NULL || s->best_ugh[0] < ugh[0])
- s->best_ugh = ugh;
- if (ugh[0] > '0'
- && s->tn - s->tried + KEYID_BUF + 2 < (ptrdiff_t)sizeof(s->tried))
- {
- strcpy(s->tn, " *");
- strcpy(s->tn + 2, k->keyid);
- s->tn += strlen(s->tn);
- }
- return FALSE;
- }
-}
-
-static stf_status
-RSA_check_signature(const struct id* peer
-, struct state *st
-, const u_char hash_val[MAX_DIGEST_LEN]
-, size_t hash_len
-, const pb_stream *sig_pbs
-#ifdef USE_KEYRR
-, const pubkey_list_t *keys_from_dns
-#endif /* USE_KEYRR */
-, const struct gw_info *gateways_from_dns
-)
-{
- const struct connection *c = st->st_connection;
- struct tac_state s;
- err_t dns_ugh = NULL;
-
- s.st = st;
- s.hash_val = hash_val;
- s.hash_len = hash_len;
- s.sig_pbs = sig_pbs;
-
- s.best_ugh = NULL;
- s.tried_cnt = 0;
- s.tn = s.tried;
-
- /* try all gateway records hung off c */
- if (c->policy & POLICY_OPPO)
- {
- struct gw_info *gw;
-
- for (gw = c->gw_info; gw != NULL; gw = gw->next)
- {
- /* only consider entries that have a key and are for our peer */
- if (gw->gw_key_present
- && same_id(&gw->gw_id, &c->spd.that.id)
- && take_a_crack(&s, gw->key, "key saved from DNS TXT"))
- return STF_OK;
- }
- }
-
- /* try all appropriate Public keys */
- {
- pubkey_list_t *p, **pp;
-
- pp = &pubkeys;
-
- for (p = pubkeys; p != NULL; p = *pp)
- {
- pubkey_t *key = p->key;
-
- if (key->alg == PUBKEY_ALG_RSA && same_id(peer, &key->id))
- {
- time_t now = time(NULL);
-
- /* check if found public key has expired */
- if (key->until_time != UNDEFINED_TIME && key->until_time < now)
- {
- loglog(RC_LOG_SERIOUS,
- "cached RSA public key has expired and has been deleted");
- *pp = free_public_keyentry(p);
- continue; /* continue with next public key */
- }
-
- if (take_a_crack(&s, key, "preloaded key"))
- return STF_OK;
- }
- pp = &p->next;
- }
- }
-
- /* if no key was found (evidenced by best_ugh == NULL)
- * and that side of connection is key_from_DNS_on_demand
- * then go search DNS for keys for peer.
- */
- if (s.best_ugh == NULL && c->spd.that.key_from_DNS_on_demand)
- {
- if (gateways_from_dns != NULL)
- {
- /* TXT keys */
- const struct gw_info *gwp;
-
- for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
- if (gwp->gw_key_present
- && take_a_crack(&s, gwp->key, "key from DNS TXT"))
- return STF_OK;
- }
-#ifdef USE_KEYRR
- else if (keys_from_dns != NULL)
- {
- /* KEY keys */
- const pubkey_list_t *kr;
-
- for (kr = keys_from_dns; kr != NULL; kr = kr->next)
- if (kr->key->alg == PUBKEY_ALG_RSA
- && take_a_crack(&s, kr->key, "key from DNS KEY"))
- return STF_OK;
- }
-#endif /* USE_KEYRR */
- else
- {
- /* nothing yet: ask for asynch DNS lookup */
- return STF_SUSPEND;
- }
- }
-
- /* no acceptable key was found: diagnose */
- {
- char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
-
- (void) idtoa(peer, id_buf, sizeof(id_buf));
-
- if (s.best_ugh == NULL)
- {
- if (dns_ugh == NULL)
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- , id_buf);
- else
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- "; DNS search for KEY failed (%s)"
- , id_buf, dns_ugh);
-
- /* ??? is this the best code there is? */
- return STF_FAIL + INVALID_KEY_INFORMATION;
- }
-
- if (s.best_ugh[0] == '9')
- {
- loglog(RC_LOG_SERIOUS, "%s", s.best_ugh + 1);
- /* XXX Could send notification back */
- return STF_FAIL + INVALID_HASH_INFORMATION;
- }
- else
- {
- if (s.tried_cnt == 1)
- {
- loglog(RC_LOG_SERIOUS
- , "Signature check (on %s) failed (wrong key?); tried%s"
- , id_buf, s.tried);
- DBG(DBG_CONTROL,
- DBG_log("public key for %s failed:"
- " decrypted SIG payload into a malformed ECB (%s)"
- , id_buf, s.best_ugh + 1));
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "Signature check (on %s) failed:"
- " tried%s keys but none worked."
- , id_buf, s.tried);
- DBG(DBG_CONTROL,
- DBG_log("all %d public keys for %s failed:"
- " best decrypted SIG payload into a malformed ECB (%s)"
- , s.tried_cnt, id_buf, s.best_ugh + 1));
- }
- return STF_FAIL + INVALID_KEY_INFORMATION;
- }
- }
-}
-
-static notification_t
-accept_nonce(struct msg_digest *md, chunk_t *dest, const char *name)
-{
- pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
- size_t len = pbs_left(nonce_pbs);
-
- if (len < MINIMUM_NONCE_SIZE || MAXIMUM_NONCE_SIZE < len)
- {
- loglog(RC_LOG_SERIOUS, "%s length not between %d and %d"
- , name , MINIMUM_NONCE_SIZE, MAXIMUM_NONCE_SIZE);
- return PAYLOAD_MALFORMED; /* ??? */
- }
- clonereplacechunk(*dest, nonce_pbs->cur, len, "nonce");
- return NOTHING_WRONG;
-}
-
-/* encrypt message, sans fixed part of header
- * IV is fetched from st->st_new_iv and stored into st->st_iv.
- * The theory is that there will be no "backing out", so we commit to IV.
- * We also close the pbs.
- */
-bool
-encrypt_message(pb_stream *pbs, struct state *st)
-{
- const struct encrypt_desc *e = st->st_oakley.encrypter;
- u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
- size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
-
- DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
-
- /* Pad up to multiple of encryption blocksize.
- * See the description associated with the definition of
- * struct isakmp_hdr in packet.h.
- */
- {
- size_t padding = pad_up(enc_len, e->enc_blocksize);
-
- if (padding != 0)
- {
- if (!out_zero(padding, pbs, "encryption padding"))
- return FALSE;
- enc_len += padding;
- }
- }
-
- DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
-
- /* e->crypt(TRUE, enc_start, enc_len, st); */
- crypto_cbc_encrypt(e, TRUE, enc_start, enc_len, st);
-
- update_iv(st);
- DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
- close_message(pbs);
- return TRUE;
-}
-
-/* Compute HASH(1), HASH(2) of Quick Mode.
- * HASH(1) is part of Quick I1 message.
- * HASH(2) is part of Quick R1 message.
- * Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
- * (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
- */
-static size_t
-quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
-, const struct state *st, const msgid_t *msgid, bool hash2)
-{
- struct hmac_ctx ctx;
-
-#if 0 /* if desperate to debug hashing */
-# define hmac_update(ctx, ptr, len) { \
- DBG_dump("hash input", (ptr), (len)); \
- (hmac_update)((ctx), (ptr), (len)); \
- }
- DBG_dump("hash key", st->st_skeyid_a.ptr, st->st_skeyid_a.len);
-#endif
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const void *) msgid, sizeof(msgid_t));
- if (hash2)
- hmac_update_chunk(&ctx, st->st_ni); /* include Ni_b in the hash */
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH(%d) computed:", hash2 + 1);
- DBG_dump("", dest, ctx.hmac_digest_size));
- return ctx.hmac_digest_size;
-# undef hmac_update
-}
-
-/* Compute HASH(3) in Quick Mode (part of Quick I2 message).
- * Used by: quick_inR1_outI2, quick_inI2
- * See RFC2409 "The Internet Key Exchange (IKE)" 5.5.
- * NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
- * Message ID and Nonces. This is a mistake.
- */
-static size_t
-quick_mode_hash3(u_char *dest, struct state *st)
-{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, "\0", 1);
- hmac_update(&ctx, (u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update_chunk(&ctx, st->st_ni);
- hmac_update_chunk(&ctx, st->st_nr);
- hmac_final(dest, &ctx);
- DBG_cond_dump(DBG_CRYPT, "HASH(3) computed:", dest, ctx.hmac_digest_size);
- return ctx.hmac_digest_size;
-}
-
-/* Compute Phase 2 IV.
- * Uses Phase 1 IV from st_iv; puts result in st_new_iv.
- */
-void
-init_phase2_iv(struct state *st, const msgid_t *msgid)
-{
- const struct hash_desc *h = st->st_oakley.hasher;
- union hash_ctx ctx;
-
- DBG_cond_dump(DBG_CRYPT, "last Phase 1 IV:"
- , st->st_ph1_iv, st->st_ph1_iv_len);
-
- st->st_new_iv_len = h->hash_digest_size;
- passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
-
- h->hash_init(&ctx);
- h->hash_update(&ctx, st->st_ph1_iv, st->st_ph1_iv_len);
- passert(*msgid != 0);
- h->hash_update(&ctx, (const u_char *)msgid, sizeof(*msgid));
- h->hash_final(st->st_new_iv, &ctx);
-
- DBG_cond_dump(DBG_CRYPT, "computed Phase 2 IV:"
- , st->st_new_iv, st->st_new_iv_len);
-}
-
-/* Initiate quick mode.
- * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
- * (see RFC 2409 "IKE" 5.5)
- * Note: this is not called from demux.c
- */
-
-static bool
-emit_subnet_id(ip_subnet *net
-, u_int8_t np, u_int8_t protoid, u_int16_t port, pb_stream *outs)
-{
- struct isakmp_ipsec_id id;
- pb_stream id_pbs;
- ip_address ta;
- const unsigned char *tbp;
- size_t tal;
-
- id.isaiid_np = np;
- id.isaiid_idtype = subnetishost(net)
- ? aftoinfo(subnettypeof(net))->id_addr
- : aftoinfo(subnettypeof(net))->id_subnet;
- id.isaiid_protoid = protoid;
- id.isaiid_port = port;
-
- if (!out_struct(&id, &isakmp_ipsec_identification_desc, outs, &id_pbs))
- return FALSE;
-
- networkof(net, &ta);
- tal = addrbytesptr(&ta, &tbp);
- if (!out_raw(tbp, tal, &id_pbs, "client network"))
- return FALSE;
-
- if (!subnetishost(net))
- {
- maskof(net, &ta);
- tal = addrbytesptr(&ta, &tbp);
- if (!out_raw(tbp, tal, &id_pbs, "client mask"))
- return FALSE;
- }
-
- close_output_pbs(&id_pbs);
- return TRUE;
-}
-
-stf_status
-quick_outI1(int whack_sock
-, struct state *isakmp_sa
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
-{
- struct state *st = duplicate_state(isakmp_sa);
- pb_stream reply; /* not really a reply */
- pb_stream rbody;
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
- bool has_client = c->spd.this.has_client || c->spd.that.has_client ||
- c->spd.this.protocol || c->spd.that.protocol ||
- c->spd.this.port || c->spd.that.port;
-
- bool send_natoa = FALSE;
- u_int8_t np = ISAKMP_NEXT_NONE;
-
- st->st_whack_sock = whack_sock;
- st->st_connection = c;
- set_cur_state(st); /* we must reset before exit */
- st->st_policy = policy;
- st->st_try = try;
-
- st->st_myuserprotoid = c->spd.this.protocol;
- st->st_peeruserprotoid = c->spd.that.protocol;
- st->st_myuserport = c->spd.this.port;
- st->st_peeruserport = c->spd.that.port;
-
- st->st_msgid = generate_msgid(isakmp_sa);
- st->st_state = STATE_QUICK_I1;
-
- insert_state(st); /* needs cookies, connection, and msgid */
-
- if (replacing == SOS_NOBODY)
- plog("initiating Quick Mode %s {using isakmp#%lu}"
- , prettypolicy(policy)
- , isakmp_sa->st_serialno);
- else
- plog("initiating Quick Mode %s to replace #%lu {using isakmp#%lu}"
- , prettypolicy(policy)
- , replacing
- , isakmp_sa->st_serialno);
-
-#ifdef NAT_TRAVERSAL
- if (isakmp_sa->nat_traversal & NAT_T_DETECTED)
- {
- /* Duplicate nat_traversal status in new state */
- st->nat_traversal = isakmp_sa->nat_traversal;
-
- if (isakmp_sa->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
- has_client = TRUE;
-
- nat_traversal_change_port_lookup(NULL, st);
- }
- else
- st->nat_traversal = 0;
-
- /* are we going to send a NAT-OA payload? */
- if ((st->nat_traversal & NAT_T_WITH_NATOA)
- && !(st->st_policy & POLICY_TUNNEL)
- && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)))
- {
- send_natoa = TRUE;
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATOA_RFC : ISAKMP_NEXT_NATOA_DRAFTS;
- }
-#endif
-
- /* set up reply */
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
- /* HDR* out */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_QUICK;
- hdr.isa_msgid = st->st_msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* HASH(1) -- create and note space to be filled later */
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
-
- /* SA out */
-
- /*
- * See if pfs_group has been specified for this conn,
- * if not, fallback to old use-same-as-P1 behaviour
- */
-#ifndef NO_IKE_ALG
- if (st->st_connection)
- st->st_pfs_group = ike_alg_pfsgroup(st->st_connection, policy);
- if (!st->st_pfs_group)
-#endif
- /* If PFS specified, use the same group as during Phase 1:
- * since no negotiation is possible, we pick one that is
- * very likely supported.
- */
- st->st_pfs_group = policy & POLICY_PFS? isakmp_sa->st_oakley.group : NULL;
-
- /* Emit SA payload based on a subset of the policy bits.
- * POLICY_COMPRESS is considered iff we can do IPcomp.
- */
- {
- lset_t pm = POLICY_ENCRYPT | POLICY_AUTHENTICATE;
-
- if (can_do_IPcomp)
- pm |= POLICY_COMPRESS;
-
- if (!out_sa(&rbody
- , &ipsec_sadb[(st->st_policy & pm) >> POLICY_IPSEC_SHIFT]
- , st, FALSE, ISAKMP_NEXT_NONCE))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &rbody
- , policy & POLICY_PFS? ISAKMP_NEXT_KE : has_client? ISAKMP_NEXT_ID : np
- , "Ni"))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
-
- /* [ KE ] out (for PFS) */
-
- if (st->st_pfs_group != NULL)
- {
- if (!build_and_ship_KE(st, &st->st_gi, st->st_pfs_group
- , &rbody, has_client? ISAKMP_NEXT_ID : np))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* [ IDci, IDcr ] out */
- if (has_client)
- {
- /* IDci (we are initiator), then IDcr (peer is responder) */
- if (!emit_subnet_id(&c->spd.this.client
- , ISAKMP_NEXT_ID, st->st_myuserprotoid, st->st_myuserport, &rbody)
- || !emit_subnet_id(&c->spd.that.client
- , np, st->st_peeruserprotoid, st->st_peeruserport, &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
-#ifdef NAT_TRAVERSAL
- /* Send NAT-OA if our address is NATed */
- if (send_natoa)
- {
- if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &rbody, st))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-#endif
-
- /* finish computing HASH(1), inserting it in output */
- (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur
- , st, &st->st_msgid, FALSE);
-
- /* encrypt message, except for fixed part of header */
-
- init_phase2_iv(isakmp_sa, &st->st_msgid);
- st->st_new_iv_len = isakmp_sa->st_new_iv_len;
- memcpy(st->st_new_iv, isakmp_sa->st_new_iv, st->st_new_iv_len);
-
- if (!encrypt_message(&rbody, st))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
-
- /* save packet, now that we know its size */
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "reply packet from quick_outI1");
-
- /* send the packet */
-
- send_packet(st, "quick_outI1");
-
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-
- if (replacing == SOS_NOBODY)
- whack_log(RC_NEW_STATE + STATE_QUICK_I1
- , "%s: initiate"
- , enum_name(&state_names, st->st_state));
- else
- whack_log(RC_NEW_STATE + STATE_QUICK_I1
- , "%s: initiate to replace #%lu"
- , enum_name(&state_names, st->st_state)
- , replacing);
- reset_cur_state();
- return STF_OK;
-}
-
-
-/*
- * Decode the CERT payload of Phase 1.
- */
-static void
-decode_cert(struct msg_digest *md)
-{
- struct payload_digest *p;
-
- for (p = md->chain[ISAKMP_NEXT_CERT]; p != NULL; p = p->next)
- {
- struct isakmp_cert *const cert = &p->payload.cert;
- chunk_t blob;
- time_t valid_until;
- blob.ptr = p->pbs.cur;
- blob.len = pbs_left(&p->pbs);
- if (cert->isacert_type == CERT_X509_SIGNATURE)
- {
- x509cert_t cert = empty_x509cert;
- if (parse_x509cert(blob, 0, &cert))
- {
- if (verify_x509cert(&cert, strict_crl_policy, &valid_until))
- {
- DBG(DBG_PARSING,
- DBG_log("Public key validated")
- )
- add_x509_public_key(&cert, valid_until, DAL_SIGNED);
- }
- else
- {
- plog("X.509 certificate rejected");
- }
- free_generalNames(cert.subjectAltName, FALSE);
- free_generalNames(cert.crlDistributionPoints, FALSE);
- }
- else
- plog("Syntax error in X.509 certificate");
- }
- else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509)
- {
- x509cert_t *cert = NULL;
-
- if (pkcs7_parse_signedData(blob, NULL, &cert, NULL, NULL))
- store_x509certs(&cert, strict_crl_policy);
- else
- plog("Syntax error in PKCS#7 wrapped X.509 certificates");
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload",
- enum_show(&cert_type_names, cert->isacert_type));
- DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob);
- }
- }
-}
-
-/*
- * Decode the CR payload of Phase 1.
- */
-static void
-decode_cr(struct msg_digest *md, struct connection *c)
-{
- struct payload_digest *p;
-
- for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
- {
- struct isakmp_cr *const cr = &p->payload.cr;
- chunk_t ca_name;
-
- ca_name.len = pbs_left(&p->pbs);
- ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;
-
- DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);
-
- if (cr->isacr_type == CERT_X509_SIGNATURE)
- {
- char buf[BUF_LEN];
-
- if (ca_name.len > 0)
- {
- generalName_t *gn;
-
- if (!is_asn1(ca_name))
- continue;
-
- gn = alloc_thing(generalName_t, "generalName");
- clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name");
- gn->kind = GN_DIRECTORY_NAME;
- gn->name = ca_name;
- gn->next = c->requested_ca;
- c->requested_ca = gn;
- }
- c->got_certrequest = TRUE;
-
- DBG(DBG_PARSING | DBG_CONTROL,
- dntoa_or_null(buf, BUF_LEN, ca_name, "%any");
- DBG_log("requested CA: '%s'", buf);
- )
- }
- else
- loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
- enum_show(&cert_type_names, cr->isacr_type));
- }
-}
-
-/* Decode the ID payload of Phase 1 (main_inI3_outR3 and main_inR3)
- * Note: we may change connections as a result.
- * We must be called before SIG or HASH are decoded since we
- * may change the peer's RSA key or ID.
- */
-static bool
-decode_peer_id(struct msg_digest *md, struct id *peer)
-{
- struct state *const st = md->st;
- struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
- const pb_stream *const id_pbs = &id_pld->pbs;
- struct isakmp_id *const id = &id_pld->payload.id;
-
- /* I think that RFC2407 (IPSEC DOI) 4.6.2 is confused.
- * It talks about the protocol ID and Port fields of the ID
- * Payload, but they don't exist as such in Phase 1.
- * We use more appropriate names.
- * isaid_doi_specific_a is in place of Protocol ID.
- * isaid_doi_specific_b is in place of Port.
- * Besides, there is no good reason for allowing these to be
- * other than 0 in Phase 1.
- */
-#ifdef NAT_TRAVERSAL
- if ((st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
- && id->isaid_doi_specific_a == IPPROTO_UDP
- && (id->isaid_doi_specific_b == 0 || id->isaid_doi_specific_b == NAT_T_IKE_FLOAT_PORT))
- {
- DBG_log("protocol/port in Phase 1 ID Payload is %d/%d. "
- "accepted with port_floating NAT-T",
- id->isaid_doi_specific_a, id->isaid_doi_specific_b);
- }
- else
-#endif
- if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
- && !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
- {
- loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must be 0/0 or %d/%d"
- " but are %d/%d"
- , IPPROTO_UDP, IKE_UDP_PORT
- , id->isaid_doi_specific_a, id->isaid_doi_specific_b);
- return FALSE;
- }
-
- peer->kind = id->isaid_idtype;
-
- switch (peer->kind)
- {
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- /* failure mode for initaddr is probably inappropriate address length */
- {
- err_t ugh = initaddr(id_pbs->cur, pbs_left(id_pbs)
- , peer->kind == ID_IPV4_ADDR? AF_INET : AF_INET6
- , &peer->ip_addr);
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "improper %s identification payload: %s"
- , enum_show(&ident_names, peer->kind), ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
- }
- break;
-
- case ID_USER_FQDN:
- if (memchr(id_pbs->cur, '@', pbs_left(id_pbs)) == NULL)
- {
- loglog(RC_LOG_SERIOUS, "peer's ID_USER_FQDN contains no @");
- return FALSE;
- }
- /* FALLTHROUGH */
- case ID_FQDN:
- if (memchr(id_pbs->cur, '\0', pbs_left(id_pbs)) != NULL)
- {
- loglog(RC_LOG_SERIOUS, "Phase 1 ID Payload of type %s contains a NUL"
- , enum_show(&ident_names, peer->kind));
- return FALSE;
- }
-
- /* ??? ought to do some more sanity check, but what? */
-
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- break;
-
- case ID_KEY_ID:
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- DBG(DBG_PARSING,
- DBG_dump_chunk("KEY ID:", peer->name));
- break;
-
- case ID_DER_ASN1_DN:
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- DBG(DBG_PARSING,
- DBG_dump_chunk("DER ASN1 DN:", peer->name));
- break;
-
- default:
- /* XXX Could send notification back */
- loglog(RC_LOG_SERIOUS, "Unacceptable identity type (%s) in Phase 1 ID Payload"
- , enum_show(&ident_names, peer->kind));
- return FALSE;
- }
-
- {
- char buf[BUF_LEN];
-
- idtoa(peer, buf, sizeof(buf));
- plog("Peer ID is %s: '%s'",
- enum_show(&ident_names, id->isaid_idtype), buf);
- }
-
- /* check for certificates */
- decode_cert(md);
- return TRUE;
-}
-
-/* Now that we've decoded the ID payload, let's see if we
- * need to switch connections.
- * We must not switch horses if we initiated:
- * - if the initiation was explicit, we'd be ignoring user's intent
- * - if opportunistic, we'll lose our HOLD info
- */
-static bool
-switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
-{
- struct state *const st = md->st;
- struct connection *c = st->st_connection;
-
- chunk_t peer_ca = (st->st_peer_pubkey != NULL)
- ? st->st_peer_pubkey->issuer : empty_chunk;
-
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
-
- dntoa_or_null(buf, BUF_LEN, peer_ca, "%none");
- DBG_log("peer CA: '%s'", buf);
- )
-
- if (initiator)
- {
- int pathlen;
-
- if (!same_id(&c->spd.that.id, peer))
- {
- char expect[BUF_LEN]
- , found[BUF_LEN];
-
- idtoa(&c->spd.that.id, expect, sizeof(expect));
- idtoa(peer, found, sizeof(found));
- loglog(RC_LOG_SERIOUS
- , "we require peer to have ID '%s', but peer declares '%s'"
- , expect, found);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
-
- dntoa_or_null(buf, BUF_LEN, c->spd.this.ca, "%none");
- DBG_log("required CA: '%s'", buf);
- )
-
- if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen))
- {
- loglog(RC_LOG_SERIOUS
- , "we don't accept the peer's CA");
- return FALSE;
- }
- }
- else
- {
- struct connection *r;
-
- /* check for certificate requests */
- decode_cr(md, c);
-
- r = refine_host_connection(st, peer, peer_ca);
-
- /* delete the collected certificate requests */
- free_generalNames(c->requested_ca, TRUE);
- c->requested_ca = NULL;
-
- if (r == NULL)
- {
- char buf[BUF_LEN];
-
- idtoa(peer, buf, sizeof(buf));
- loglog(RC_LOG_SERIOUS, "no suitable connection for peer '%s'", buf);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
-
- dntoa_or_null(buf, BUF_LEN, r->spd.this.ca, "%none");
- DBG_log("offered CA: '%s'", buf);
- )
-
- if (r != c)
- {
- /* apparently, r is an improvement on c -- replace */
-
- DBG(DBG_CONTROL
- , DBG_log("switched from \"%s\" to \"%s\"", c->name, r->name));
- if (r->kind == CK_TEMPLATE)
- {
- /* instantiate it, filling in peer's ID */
- r = rw_instantiate(r, &c->spd.that.host_addr,
-#ifdef NAT_TRAVERSAL
- c->spd.that.host_port,
-#endif
-#ifdef VIRTUAL_IP
- NULL,
-#endif
- peer);
- }
-
- /* copy certificate request info */
- r->got_certrequest = c->got_certrequest;
-
- st->st_connection = r; /* kill reference to c */
- set_cur_connection(r);
- connection_discard(c);
- }
- else if (c->spd.that.has_id_wildcards)
- {
- free_id_content(&c->spd.that.id);
- c->spd.that.id = *peer;
- c->spd.that.has_id_wildcards = FALSE;
- unshare_id_content(&c->spd.that.id);
- }
- }
- return TRUE;
-}
-
-/* Decode the variable part of an ID packet (during Quick Mode).
- * This is designed for packets that identify clients, not peers.
- * Rejects 0.0.0.0/32 or IPv6 equivalent because
- * (1) it is wrong and (2) we use this value for inband signalling.
- */
-static bool
-decode_net_id(struct isakmp_ipsec_id *id
-, pb_stream *id_pbs
-, ip_subnet *net
-, const char *which)
-{
- const struct af_info *afi = NULL;
-
- /* Note: the following may be a pointer into static memory
- * that may be recycled, but only if the type is not known.
- * That case is disposed of very early -- in the first switch.
- */
- const char *idtypename = enum_show(&ident_names, id->isaiid_idtype);
-
- switch (id->isaiid_idtype)
- {
- case ID_IPV4_ADDR:
- case ID_IPV4_ADDR_SUBNET:
- case ID_IPV4_ADDR_RANGE:
- afi = &af_inet4_info;
- break;
- case ID_IPV6_ADDR:
- case ID_IPV6_ADDR_SUBNET:
- case ID_IPV6_ADDR_RANGE:
- afi = &af_inet6_info;
- break;
- case ID_FQDN:
- return TRUE;
- default:
- /* XXX support more */
- loglog(RC_LOG_SERIOUS, "unsupported ID type %s"
- , idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
-
- switch (id->isaiid_idtype)
- {
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- {
- ip_address temp_address;
- err_t ugh;
-
- ugh = initaddr(id_pbs->cur, pbs_left(id_pbs), afi->af, &temp_address);
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s has wrong length in Quick I1 (%s)"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
- if (isanyaddr(&temp_address))
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s is invalid (%s) in Quick I1"
- , which, idtypename, ip_str(&temp_address));
- /* XXX Could send notification back */
- return FALSE;
- }
- happy(addrtosubnet(&temp_address, net));
- DBG(DBG_PARSING | DBG_CONTROL
- , DBG_log("%s is %s", which, ip_str(&temp_address)));
- break;
- }
-
- case ID_IPV4_ADDR_SUBNET:
- case ID_IPV6_ADDR_SUBNET:
- {
- ip_address temp_address, temp_mask;
- err_t ugh;
-
- if (pbs_left(id_pbs) != 2 * afi->ia_sz)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
- , which, idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
- ugh = initaddr(id_pbs->cur
- , afi->ia_sz, afi->af, &temp_address);
- if (ugh == NULL)
- ugh = initaddr(id_pbs->cur + afi->ia_sz
- , afi->ia_sz, afi->af, &temp_mask);
- if (ugh == NULL)
- ugh = initsubnet(&temp_address, masktocount(&temp_mask)
- , '0', net);
- if (ugh == NULL && subnetisnone(net))
- ugh = "contains only anyaddr";
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s bad subnet in Quick I1 (%s)"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
- DBG(DBG_PARSING | DBG_CONTROL,
- {
- char temp_buff[SUBNETTOT_BUF];
-
- subnettot(net, 0, temp_buff, sizeof(temp_buff));
- DBG_log("%s is subnet %s", which, temp_buff);
- });
- break;
- }
-
- case ID_IPV4_ADDR_RANGE:
- case ID_IPV6_ADDR_RANGE:
- {
- ip_address temp_address_from, temp_address_to;
- err_t ugh;
-
- if (pbs_left(id_pbs) != 2 * afi->ia_sz)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
- , which, idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
- ugh = initaddr(id_pbs->cur, afi->ia_sz, afi->af, &temp_address_from);
- if (ugh == NULL)
- ugh = initaddr(id_pbs->cur + afi->ia_sz
- , afi->ia_sz, afi->af, &temp_address_to);
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s malformed (%s) in Quick I1"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
-
- ugh = rangetosubnet(&temp_address_from, &temp_address_to, net);
- if (ugh == NULL && subnetisnone(net))
- ugh = "contains only anyaddr";
- if (ugh != NULL)
- {
- char temp_buff1[ADDRTOT_BUF], temp_buff2[ADDRTOT_BUF];
-
- addrtot(&temp_address_from, 0, temp_buff1, sizeof(temp_buff1));
- addrtot(&temp_address_to, 0, temp_buff2, sizeof(temp_buff2));
- loglog(RC_LOG_SERIOUS, "%s ID payload in Quick I1, %s"
- " %s - %s unacceptable: %s"
- , which, idtypename, temp_buff1, temp_buff2, ugh);
- return FALSE;
- }
- DBG(DBG_PARSING | DBG_CONTROL,
- {
- char temp_buff[SUBNETTOT_BUF];
-
- subnettot(net, 0, temp_buff, sizeof(temp_buff));
- DBG_log("%s is subnet %s (received as range)"
- , which, temp_buff);
- });
- break;
- }
- }
-
- /* set the port selector */
- setportof(htons(id->isaiid_port), &net->addr);
-
- DBG(DBG_PARSING | DBG_CONTROL,
- DBG_log("%s protocol/port is %d/%d", which, id->isaiid_protoid, id->isaiid_port)
- )
-
- return TRUE;
-}
-
-/* like decode, but checks that what is received matches what was sent */
-static bool
-
-check_net_id(struct isakmp_ipsec_id *id
-, pb_stream *id_pbs
-, u_int8_t *protoid
-, u_int16_t *port
-, ip_subnet *net
-, const char *which)
-{
- ip_subnet net_temp;
-
- if (!decode_net_id(id, id_pbs, &net_temp, which))
- return FALSE;
-
- if (!samesubnet(net, &net_temp)
- || *protoid != id->isaiid_protoid || *port != id->isaiid_port)
- {
- loglog(RC_LOG_SERIOUS, "%s ID returned doesn't match my proposal", which);
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * look for the existence of a non-expiring preloaded public key
- */
-static bool
-has_preloaded_public_key(struct state *st)
-{
- struct connection *c = st->st_connection;
-
- /* do not consider rw connections since
- * the peer's identity must be known
- */
- if (c->kind == CK_PERMANENT)
- {
- pubkey_list_t *p;
-
- /* look for a matching RSA public key */
- for (p = pubkeys; p != NULL; p = p->next)
- {
- pubkey_t *key = p->key;
-
- if (key->alg == PUBKEY_ALG_RSA &&
- same_id(&c->spd.that.id, &key->id) &&
- key->until_time == UNDEFINED_TIME)
- {
- /* found a preloaded public key */
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-/*
- * Produce the new key material of Quick Mode.
- * RFC 2409 "IKE" section 5.5
- * specifies how this is to be done.
- */
-static void
-compute_proto_keymat(struct state *st
-, u_int8_t protoid
-, struct ipsec_proto_info *pi)
-{
- size_t needed_len; /* bytes of keying material needed */
-
- /* Add up the requirements for keying material
- * (It probably doesn't matter if we produce too much!)
- */
- switch (protoid)
- {
- case PROTO_IPSEC_ESP:
- switch (pi->attrs.transid)
- {
- case ESP_NULL:
- needed_len = 0;
- break;
- case ESP_DES:
- needed_len = DES_CBC_BLOCK_SIZE;
- break;
- case ESP_3DES:
- needed_len = DES_CBC_BLOCK_SIZE * 3;
- break;
- default:
-#ifndef NO_KERNEL_ALG
- if((needed_len=kernel_alg_esp_enc_keylen(pi->attrs.transid))>0) {
- /* XXX: check key_len "coupling with kernel.c's */
- if (pi->attrs.key_len) {
- needed_len=pi->attrs.key_len/8;
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "key_len=%d from peer",
- (int)needed_len));
- }
- break;
- }
-#endif
- bad_case(pi->attrs.transid);
- }
-
-#ifndef NO_KERNEL_ALG
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "needed_len (after ESP enc)=%d",
- (int)needed_len));
- if (kernel_alg_esp_auth_ok(pi->attrs.auth, NULL)) {
- needed_len += kernel_alg_esp_auth_keylen(pi->attrs.auth);
- } else
-#endif
- switch (pi->attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- break;
- case AUTH_ALGORITHM_HMAC_MD5:
- needed_len += HMAC_MD5_KEY_LEN;
- break;
- case AUTH_ALGORITHM_HMAC_SHA1:
- needed_len += HMAC_SHA1_KEY_LEN;
- break;
- case AUTH_ALGORITHM_DES_MAC:
- default:
- bad_case(pi->attrs.auth);
- }
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "needed_len (after ESP auth)=%d",
- (int)needed_len));
- break;
-
- case PROTO_IPSEC_AH:
- switch (pi->attrs.transid)
- {
- case AH_MD5:
- needed_len = HMAC_MD5_KEY_LEN;
- break;
- case AH_SHA:
- needed_len = HMAC_SHA1_KEY_LEN;
- break;
- default:
- bad_case(pi->attrs.transid);
- }
- break;
-
- default:
- bad_case(protoid);
- }
-
- pi->keymat_len = needed_len;
-
- /* Allocate space for the keying material.
- * Although only needed_len bytes are desired, we
- * must round up to a multiple of ctx.hmac_digest_size
- * so that our buffer isn't overrun.
- */
- {
- struct hmac_ctx ctx_me, ctx_peer;
- size_t needed_space; /* space needed for keying material (rounded up) */
- size_t i;
-
- hmac_init_chunk(&ctx_me, st->st_oakley.hasher, st->st_skeyid_d);
- ctx_peer = ctx_me; /* duplicate initial conditions */
-
- needed_space = needed_len + pad_up(needed_len, ctx_me.hmac_digest_size);
- replace(pi->our_keymat, alloc_bytes(needed_space, "keymat in compute_keymat()"));
- replace(pi->peer_keymat, alloc_bytes(needed_space, "peer_keymat in quick_inI1_outR1()"));
-
- for (i = 0;; )
- {
- if (st->st_shared.ptr != NULL)
- {
- /* PFS: include the g^xy */
- hmac_update_chunk(&ctx_me, st->st_shared);
- hmac_update_chunk(&ctx_peer, st->st_shared);
- }
- hmac_update(&ctx_me, &protoid, sizeof(protoid));
- hmac_update(&ctx_peer, &protoid, sizeof(protoid));
-
- hmac_update(&ctx_me, (u_char *)&pi->our_spi, sizeof(pi->our_spi));
- hmac_update(&ctx_peer, (u_char *)&pi->attrs.spi, sizeof(pi->attrs.spi));
-
- hmac_update_chunk(&ctx_me, st->st_ni);
- hmac_update_chunk(&ctx_peer, st->st_ni);
-
- hmac_update_chunk(&ctx_me, st->st_nr);
- hmac_update_chunk(&ctx_peer, st->st_nr);
-
- hmac_final(pi->our_keymat + i, &ctx_me);
- hmac_final(pi->peer_keymat + i, &ctx_peer);
-
- i += ctx_me.hmac_digest_size;
- if (i >= needed_space)
- break;
-
- /* more keying material needed: prepare to go around again */
-
- hmac_reinit(&ctx_me);
- hmac_reinit(&ctx_peer);
-
- hmac_update(&ctx_me, pi->our_keymat + i - ctx_me.hmac_digest_size
- , ctx_me.hmac_digest_size);
- hmac_update(&ctx_peer, pi->peer_keymat + i - ctx_peer.hmac_digest_size
- , ctx_peer.hmac_digest_size);
- }
- }
-
- DBG(DBG_CRYPT,
- DBG_dump("KEYMAT computed:\n", pi->our_keymat, pi->keymat_len);
- DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat, pi->keymat_len));
-}
-
-static void
-compute_keymats(struct state *st)
-{
- if (st->st_ah.present)
- compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah);
- if (st->st_esp.present)
- compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp);
-}
-
-/* State Transition Functions.
- *
- * The definition of state_microcode_table in demux.c is a good
- * overview of these routines.
- *
- * - Called from process_packet; result handled by complete_state_transition
- * - struct state_microcode member "processor" points to these
- * - these routine definitionss are in state order
- * - these routines must be restartable from any point of error return:
- * beware of memory allocated before any error.
- * - output HDR is usually emitted by process_packet (if state_microcode
- * member first_out_payload isn't ISAKMP_NEXT_NONE).
- *
- * The transition functions' functions include:
- * - process and judge payloads
- * - update st_iv (result of decryption is in st_new_iv)
- * - build reply packet
- */
-
-/* Handle a Main Mode Oakley first packet (responder side).
- * HDR;SA --> HDR;SA
- */
-stf_status
-main_inI1_outR1(struct msg_digest *md)
-{
- struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
- struct state *st;
- struct connection *c;
- struct isakmp_proposal proposal;
- pb_stream proposal_pbs;
- pb_stream r_sa_pbs;
- u_int32_t ipsecdoisit;
- lset_t policy = LEMPTY;
- int vids_to_send = 0;
-
- /* We preparse the peer's proposal in order to determine
- * the requested authentication policy (RSA or PSK)
- */
- RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
- , &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
-
- backup_pbs(&proposal_pbs);
- RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
- , proposal.isap_notrans, &policy));
- restore_pbs(&proposal_pbs);
-
- /* We are only considering candidate connections that match
- * the requested authentication policy (RSA or PSK)
- */
- c = find_host_connection(&md->iface->addr, pluto_port
- , &md->sender, md->sender_port, policy);
-
-#ifdef NAT_TRAVERSAL
- if (c == NULL && md->iface->ike_float)
- {
- c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
- , &md->sender, md->sender_port, policy);
- }
-#endif
-
- if (c == NULL)
- {
- /* See if a wildcarded connection can be found.
- * We cannot pick the right connection, so we're making a guess.
- * All Road Warrior connections are fair game:
- * we pick the first we come across (if any).
- * If we don't find any, we pick the first opportunistic
- * with the smallest subnet that includes the peer.
- * There is, of course, no necessary relationship between
- * an Initiator's address and that of its client,
- * but Food Groups kind of assumes one.
- */
- {
- struct connection *d;
-
- d = find_host_connection(&md->iface->addr
- , pluto_port, (ip_address*)NULL, md->sender_port, policy);
-
- for (; d != NULL; d = d->hp_next)
- {
- if (d->kind == CK_GROUP)
- {
- /* ignore */
- }
- else
- {
- if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO))
- {
- /* must be Road Warrior: we have a winner */
- c = d;
- break;
- }
-
- /* Opportunistic or Shunt: pick tightest match */
- if (addrinsubnet(&md->sender, &d->spd.that.client)
- && (c == NULL || !subnetinsubnet(&c->spd.that.client, &d->spd.that.client)))
- c = d;
- }
- }
- }
-
- if (c == NULL)
- {
- loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
- " but no connection has been authorized%s%s"
- , ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr))
- , (policy != LEMPTY) ? " with policy=" : ""
- , (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
- /* XXX notification is in order! */
- return STF_IGNORE;
- }
- else if (c->kind != CK_TEMPLATE)
- {
- loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
- " but \"%s\" forbids connection"
- , ip_str(&md->iface->addr), pluto_port, c->name);
- /* XXX notification is in order! */
- return STF_IGNORE;
- }
- else
- {
- /* Create a temporary connection that is a copy of this one.
- * His ID isn't declared yet.
- */
- c = rw_instantiate(c, &md->sender,
-#ifdef NAT_TRAVERSAL
- md->sender_port,
-#endif
-#ifdef VIRTUAL_IP
- NULL,
-#endif
- NULL);
- }
- }
- else if (c->kind == CK_TEMPLATE)
- {
- /* Create an instance
- * This is a rare case: wildcard peer ID but static peer IP address
- */
- c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
- }
-
- /* Set up state */
- md->st = st = new_state();
- st->st_connection = c;
- set_cur_state(st); /* (caller will reset cur_state) */
- st->st_try = 0; /* not our job to try again from start */
- st->st_policy = c->policy & ~POLICY_IPSEC_MASK; /* only as accurate as connection */
-
- memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
- get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);
-
- insert_state(st); /* needs cookies, connection, and msgid (0) */
-
- st->st_doi = ISAKMP_DOI_IPSEC;
- st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */
-
- if ((c->kind == CK_INSTANCE) && (c->spd.that.host_port != pluto_port))
- {
- plog("responding to Main Mode from unknown peer %s:%u"
- , ip_str(&c->spd.that.host_addr), c->spd.that.host_port);
- }
- else if (c->kind == CK_INSTANCE)
- {
- plog("responding to Main Mode from unknown peer %s"
- , ip_str(&c->spd.that.host_addr));
- }
- else
- {
- plog("responding to Main Mode");
- }
-
- /* parse_isakmp_sa also spits out a winning SA into our reply,
- * so we have to build our md->reply and emit HDR before calling it.
- */
-
- /* determine how many Vendor ID payloads we will be sending */
- if (SEND_PLUTO_VID)
- vids_to_send++;
- if (SEND_CISCO_UNITY_VID)
- vids_to_send++;
- if (md->openpgp)
- vids_to_send++;
- /* always send XAUTH Vendor ID */
- vids_to_send++;
- /* always send DPD Vendor ID */
- vids_to_send++;
-#ifdef NAT_TRAVERSAL
- if (md->nat_traversal_vid && nat_traversal_enabled)
- vids_to_send++;
-#endif
-
- /* HDR out.
- * We can't leave this to comm_handle() because we must
- * fill in the cookie.
- */
- {
- struct isakmp_hdr r_hdr = md->hdr;
-
- r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
- memcpy(r_hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- r_hdr.isa_np = ISAKMP_NEXT_SA;
- if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
- return STF_INTERNAL_ERROR;
- }
-
- /* start of SA out */
- {
- struct isakmp_sa r_sa = sa_pd->payload.sa;
-
- r_sa.isasa_np = vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE;
-
- if (!out_struct(&r_sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
- return STF_INTERNAL_ERROR;
- }
-
- /* SA body in and out */
- RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
- ,&proposal, &r_sa_pbs, st, FALSE));
-
- /* if enabled send Pluto Vendor ID */
- if (SEND_PLUTO_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_STRONGSWAN))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* if enabled send Cisco Unity Vendor ID */
- if (SEND_CISCO_UNITY_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_CISCO_UNITY))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- /*
- * if the peer sent an OpenPGP Vendor ID we offer the same capability
- */
- if (md->openpgp)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_OPENPGP))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* Announce our ability to do eXtended AUTHentication to the peer */
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_XAUTH))
- {
- return STF_INTERNAL_ERROR;
- }
-
- /* Announce our ability to do Dead Peer Detection to the peer */
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_DPD))
- {
- return STF_INTERNAL_ERROR;
- }
-
-#ifdef NAT_TRAVERSAL
- DBG(DBG_CONTROLMORE,
- DBG_log("sender checking NAT-t: %d and %d"
- , nat_traversal_enabled, md->nat_traversal_vid)
- )
- if (md->nat_traversal_vid && nat_traversal_enabled)
- {
- /* reply if NAT-Traversal draft is supported */
- st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
-
- if (st->nat_traversal
- && !out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, md->nat_traversal_vid))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-#endif
-
- close_message(&md->rbody);
-
- /* save initiator SA for HASH */
- clonereplacechunk(st->st_p1isa, sa_pd->pbs.start, pbs_room(&sa_pd->pbs), "sa in main_inI1_outR1()");
-
- return STF_OK;
-}
-
-/* STATE_MAIN_I1: HDR, SA --> auth dependent
- * PSK_AUTH, DS_AUTH: --> HDR, KE, Ni
- *
- * The following are not yet implemented:
- * PKE_AUTH: --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * RPKE_AUTH: --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
- * <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- *
- * We must verify that the proposal received matches one we sent.
- */
-stf_status
-main_inR1_outI2(struct msg_digest *md)
-{
- struct state *const st = md->st;
-
- u_int8_t np = ISAKMP_NEXT_NONE;
-
- /* verify echoed SA */
- {
- u_int32_t ipsecdoisit;
- pb_stream proposal_pbs;
- struct isakmp_proposal proposal;
- struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
-
- RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sapd->payload.sa
- ,&sapd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
- if (proposal.isap_notrans != 1)
- {
- loglog(RC_LOG_SERIOUS, "a single Transform is required in a selecting Oakley Proposal; found %u"
- , (unsigned)proposal.isap_notrans);
- RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
- }
- RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
- , &proposal_pbs, &proposal, NULL, st, TRUE));
- }
-
-#ifdef NAT_TRAVERSAL
- DBG(DBG_CONTROLMORE,
- DBG_log("sender checking NAT-t: %d and %d"
- , nat_traversal_enabled, md->nat_traversal_vid)
- )
- if (nat_traversal_enabled && md->nat_traversal_vid)
- {
- st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
- plog("enabling possible NAT-traversal with method %s"
- , bitnamesof(natt_type_bitnames, st->nat_traversal));
- }
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
- }
- #endif
-
- /**************** build output packet HDR;KE;Ni ****************/
-
- /* HDR out.
- * We can't leave this to comm_handle() because the isa_np
- * depends on the type of Auth (eventually).
- */
- echo_hdr(md, FALSE, ISAKMP_NEXT_KE);
-
- /* KE out */
- if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group
- , &md->rbody, ISAKMP_NEXT_NONCE))
- return STF_INTERNAL_ERROR;
-
-#ifdef DEBUG
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &md->rbody
- , (cur_debugging & IMPAIR_BUST_MI2)? ISAKMP_NEXT_VID : np, "Ni"))
- return STF_INTERNAL_ERROR;
-
- if (cur_debugging & IMPAIR_BUST_MI2)
- {
- /* generate a pointless large VID payload to push message over MTU */
- pb_stream vid_pbs;
-
- if (!out_generic(np, &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&vid_pbs);
- }
-#else
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &md->rbody, np, "Ni"))
- return STF_INTERNAL_ERROR;
-#endif
-
-#ifdef NAT_TRAVERSAL
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
- return STF_INTERNAL_ERROR;
- }
-#endif
-
- /* finish message */
- close_message(&md->rbody);
-
- /* Reinsert the state, using the responder cookie we just received */
- unhash_state(st);
- memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE);
- insert_state(st); /* needs cookies, connection, and msgid (0) */
-
- return STF_OK;
-}
-
-/* STATE_MAIN_R1:
- * PSK_AUTH, DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
- *
- * The following are not yet implemented:
- * PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * RPKE_AUTH:
- * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- */
-stf_status
-main_inI2_outR2(struct msg_digest *md)
-{
- struct state *const st = md->st;
- pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-
- /* send CR if auth is RSA and no preloaded RSA public key exists*/
- bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
- bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
-
- u_int8_t np = ISAKMP_NEXT_NONE;
-
- /* KE in */
- RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group, keyex_pbs));
-
- /* Ni in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
-
-#ifdef NAT_TRAVERSAL
- DBG(DBG_CONTROLMORE,
- DBG_log("inI2: checking NAT-t: %d and %d"
- , nat_traversal_enabled, st->nat_traversal)
- )
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- nat_traversal_natd_lookup(md);
-
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
- }
- if (st->nat_traversal)
- {
- nat_traversal_show_result(st->nat_traversal, md->sender_port);
- }
- if (st->nat_traversal & NAT_T_WITH_KA)
- {
- nat_traversal_new_ka_event();
- }
-#endif
-
- /* decode certificate requests */
- st->st_connection->got_certrequest = FALSE;
- decode_cr(md, st->st_connection);
-
- /**************** build output packet HDR;KE;Nr ****************/
-
- /* HDR out done */
-
- /* KE out */
- if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group
- , &md->rbody, ISAKMP_NEXT_NONCE))
- return STF_INTERNAL_ERROR;
-
-#ifdef DEBUG
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody
- , (cur_debugging & IMPAIR_BUST_MR2)? ISAKMP_NEXT_VID
- : (send_cr? ISAKMP_NEXT_CR : np), "Nr"))
- return STF_INTERNAL_ERROR;
-
- if (cur_debugging & IMPAIR_BUST_MR2)
- {
- /* generate a pointless large VID payload to push message over MTU */
- pb_stream vid_pbs;
-
- if (!out_generic((send_cr)? ISAKMP_NEXT_CR : np,
- &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&vid_pbs);
- }
-#else
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody,
- (send_cr)? ISAKMP_NEXT_CR : np, "Nr"))
- return STF_INTERNAL_ERROR;
-#endif
-
- /* CR out */
- if (send_cr)
- {
- if (st->st_connection->kind == CK_PERMANENT)
- {
- if (!build_and_ship_CR(CERT_X509_SIGNATURE
- , st->st_connection->spd.that.ca
- , &md->rbody, np))
- return STF_INTERNAL_ERROR;
- }
- else
- {
- generalName_t *ca = NULL;
-
- if (collect_rw_ca_candidates(md, &ca))
- {
- generalName_t *gn;
-
- for (gn = ca; gn != NULL; gn = gn->next)
- {
- if (!build_and_ship_CR(CERT_X509_SIGNATURE, gn->name
- , &md->rbody
- , gn->next == NULL ? np : ISAKMP_NEXT_CR))
- return STF_INTERNAL_ERROR;
- }
- free_generalNames(ca, FALSE);
- }
- else
- {
- if (!build_and_ship_CR(CERT_X509_SIGNATURE, empty_chunk
- , &md->rbody, np))
- return STF_INTERNAL_ERROR;
- }
- }
- }
-
-#ifdef NAT_TRAVERSAL
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
- return STF_INTERNAL_ERROR;
- }
-#endif
-
- /* finish message */
- close_message(&md->rbody);
-
- /* next message will be encrypted, but not this one.
- * We could defer this calculation.
- */
- compute_dh_shared(st, st->st_gi, st->st_oakley.group);
- if (!generate_skeyids_iv(st))
- return STF_FAIL + AUTHENTICATION_FAILED;
- update_iv(st);
-
- return STF_OK;
-}
-
-/* STATE_MAIN_I2:
- * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
- * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
- *
- * The following are not yet implemented.
- * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * --> HDR*, HASH_I
- * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- * --> HDR*, HASH_I
- */
-stf_status
-main_inR2_outI3(struct msg_digest *md)
-{
- struct state *const st = md->st;
- pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
- pb_stream id_pbs; /* ID Payload; also used for hash calculation */
-
- certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
- cert_t mycert = st->st_connection->spd.this.cert;
- bool requested, send_cert, send_cr;
-
- bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
-
- int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
- /* KE in */
- RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
-
- /* Nr in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
-
- /* decode certificate requests */
- st->st_connection->got_certrequest = FALSE;
- decode_cr(md, st->st_connection);
-
- /* free collected certificate requests since as initiator
- * we don't heed them anyway
- */
- free_generalNames(st->st_connection->requested_ca, TRUE);
- st->st_connection->requested_ca = NULL;
-
- /* send certificate if auth is RSA, we have one and we want
- * or are requested to send it
- */
- requested = cert_policy == CERT_SEND_IF_ASKED
- && st->st_connection->got_certrequest;
- send_cert = RSA_auth && mycert.type != CERT_NONE
- && (cert_policy == CERT_ALWAYS_SEND || requested);
-
- /* send certificate request if we don't have a preloaded RSA public key */
- send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
-
- /* done parsing; initialize crypto */
-
- compute_dh_shared(st, st->st_gr, st->st_oakley.group);
- if (!generate_skeyids_iv(st))
- return STF_FAIL + AUTHENTICATION_FAILED;
-
-#ifdef NAT_TRAVERSAL
- if (st->nat_traversal & NAT_T_WITH_NATD) {
- nat_traversal_natd_lookup(md);
- }
- if (st->nat_traversal) {
- nat_traversal_show_result(st->nat_traversal, md->sender_port);
- }
- if (st->nat_traversal & NAT_T_WITH_KA) {
- nat_traversal_new_ka_event();
- }
-#endif
-
- /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
- /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
-
- /* HDR* out done */
-
- /* IDii out */
- {
- struct isakmp_ipsec_id id_hd;
- chunk_t id_b;
-
- build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
- id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
- if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs)
- || !out_chunk(id_b, &id_pbs, "my identity"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&id_pbs);
- }
-
- /* CERT out */
- if (RSA_auth)
- {
- DBG(DBG_CONTROL,
- DBG_log("our certificate policy is %s"
- , enum_name(&cert_policy_names, cert_policy))
- )
- if (mycert.type != CERT_NONE)
- {
- const char *request_text = "";
-
- if (cert_policy == CERT_SEND_IF_ASKED)
- request_text = (send_cert)? "upon request":"without request";
- plog("we have a cert %s sending it %s"
- , send_cert? "and are":"but are not", request_text);
- }
- else
- {
- plog("we don't have a cert");
- }
- }
- if (send_cert)
- {
- pb_stream cert_pbs;
-
- struct isakmp_cert cert_hd;
- cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
-
- if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&cert_pbs);
- }
-
- /* CR out */
- if (send_cr)
- {
- if (!build_and_ship_CR(mycert.type, st->st_connection->spd.that.ca
- , &md->rbody, ISAKMP_NEXT_SIG))
- return STF_INTERNAL_ERROR;
- }
-
- /* HASH_I or SIG_I out */
- {
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len = main_mode_hash(st, hash_val, TRUE, &id_pbs);
-
- if (auth_payload == ISAKMP_NEXT_HASH)
- {
- /* HASH_I out */
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody
- , hash_val, hash_len, "HASH_I"))
- return STF_INTERNAL_ERROR;
- }
- else
- {
- /* SIG_I out */
- u_char sig_val[RSA_MAX_OCTETS];
- size_t sig_len = RSA_sign_hash(st->st_connection
- , sig_val, hash_val, hash_len);
-
- if (sig_len == 0)
- {
- loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature");
- return STF_FAIL + AUTHENTICATION_FAILED;
- }
-
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
- , &md->rbody, sig_val, sig_len, "SIG_I"))
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* encrypt message, except for fixed part of header */
-
- /* st_new_iv was computed by generate_skeyids_iv */
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
-
- return STF_OK;
-}
-
-/* Shared logic for asynchronous lookup of DNS KEY records.
- * Used for STATE_MAIN_R2 and STATE_MAIN_I3.
- */
-
-enum key_oppo_step {
- kos_null,
- kos_his_txt
-#ifdef USE_KEYRR
- , kos_his_key
-#endif
-};
-
-struct key_continuation {
- struct adns_continuation ac; /* common prefix */
- struct msg_digest *md;
- enum key_oppo_step step;
- bool failure_ok;
- err_t last_ugh;
-};
-
-typedef stf_status (key_tail_fn)(struct msg_digest *md
- , struct key_continuation *kc);
-static void
-report_key_dns_failure(struct id *id, err_t ugh)
-{
- char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
-
- (void) idtoa(id, id_buf, sizeof(id_buf));
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- "; DNS search for KEY failed (%s)", id_buf, ugh);
-}
-
-
-/* Processs the Main Mode ID Payload and the Authenticator
- * (Hash or Signature Payload).
- * If a DNS query is still needed to get the other host's public key,
- * the query is initiated and STF_SUSPEND is returned.
- * Note: parameter kc is a continuation containing the results from
- * the previous DNS query, or NULL indicating no query has been issued.
- */
-static stf_status
-main_id_and_auth(struct msg_digest *md
- , bool initiator /* are we the Initiator? */
- , cont_fn_t cont_fn /* continuation function */
- , const struct key_continuation *kc /* current state, can be NULL */
-)
-{
- struct state *st = md->st;
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len;
- struct id peer;
- stf_status r = STF_OK;
-
- /* ID Payload in */
- if (!decode_peer_id(md, &peer))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* Hash the ID Payload.
- * main_mode_hash requires idpl->cur to be at end of payload
- * so we temporarily set if so.
- */
- {
- pb_stream *idpl = &md->chain[ISAKMP_NEXT_ID]->pbs;
- u_int8_t *old_cur = idpl->cur;
-
- idpl->cur = idpl->roof;
- hash_len = main_mode_hash(st, hash_val, !initiator, idpl);
- idpl->cur = old_cur;
- }
-
- switch (st->st_oakley.auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- {
- pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
-
- if (pbs_left(hash_pbs) != hash_len
- || memcmp(hash_pbs->cur, hash_val, hash_len) != 0)
- {
- DBG_cond_dump(DBG_CRYPT, "received HASH:"
- , hash_pbs->cur, pbs_left(hash_pbs));
- loglog(RC_LOG_SERIOUS, "received Hash Payload does not match computed value");
- /* XXX Could send notification back */
- r = STF_FAIL + INVALID_HASH_INFORMATION;
- }
- }
- break;
-
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- r = RSA_check_signature(&peer, st, hash_val, hash_len
- , &md->chain[ISAKMP_NEXT_SIG]->pbs
-#ifdef USE_KEYRR
- , kc == NULL? NULL : kc->ac.keys_from_dns
-#endif /* USE_KEYRR */
- , kc == NULL? NULL : kc->ac.gateways_from_dns
- );
-
- if (r == STF_SUSPEND)
- {
- /* initiate/resume asynchronous DNS lookup for key */
- struct key_continuation *nkc
- = alloc_thing(struct key_continuation, "key continuation");
- enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
- err_t ugh;
-
- /* Record that state is used by a suspended md */
- passert(st->st_suspended_md == NULL);
- st->st_suspended_md = md;
-
- nkc->failure_ok = FALSE;
- nkc->md = md;
-
- switch (step_done)
- {
- case kos_null:
- /* first try: look for the TXT records */
- nkc->step = kos_his_txt;
-#ifdef USE_KEYRR
- nkc->failure_ok = TRUE;
-#endif
- ugh = start_adns_query(&peer
- , &peer /* SG itself */
- , T_TXT
- , cont_fn
- , &nkc->ac);
- break;
-
-#ifdef USE_KEYRR
- case kos_his_txt:
- /* second try: look for the KEY records */
- nkc->step = kos_his_key;
- ugh = start_adns_query(&peer
- , NULL /* no sgw for KEY */
- , T_KEY
- , cont_fn
- , &nkc->ac);
- break;
-#endif /* USE_KEYRR */
-
- default:
- bad_case(step_done);
- }
-
- if (ugh != NULL)
- {
- report_key_dns_failure(&peer, ugh);
- st->st_suspended_md = NULL;
- r = STF_FAIL + INVALID_KEY_INFORMATION;
- }
- }
- break;
-
- default:
- bad_case(st->st_oakley.auth);
- }
- if (r != STF_OK)
- return r;
-
- DBG(DBG_CRYPT, DBG_log("authentication succeeded"));
-
- /*
- * With the peer ID known, let's see if we need to switch connections.
- */
- if (!switch_connection(md, &peer, initiator))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- return r;
-}
-
-/* This continuation is called as part of either
- * the main_inI3_outR3 state or main_inR3 state.
- *
- * The "tail" function is the corresponding tail
- * function main_inI3_outR3_tail | main_inR3_tail,
- * either directly when the state is started, or via
- * adns continuation.
- *
- * Basically, we go around in a circle:
- * main_in?3* -> key_continue
- * ^ \
- * / V
- * adns main_in?3*_tail
- * ^ |
- * \ V
- * main_id_and_auth
- *
- * until such time as main_id_and_auth is able
- * to find authentication, or we run out of things
- * to try.
- */
-static void
-key_continue(struct adns_continuation *cr
-, err_t ugh
-, key_tail_fn *tail)
-{
- struct key_continuation *kc = (void *)cr;
- struct state *st = kc->md->st;
-
- passert(cur_state == NULL);
-
- /* if st == NULL, our state has been deleted -- just clean up */
- if (st != NULL)
- {
- stf_status r;
-
- passert(st->st_suspended_md == kc->md);
- st->st_suspended_md = NULL; /* no longer connected or suspended */
- cur_state = st;
-
- if (!kc->failure_ok && ugh != NULL)
- {
- report_key_dns_failure(&st->st_connection->spd.that.id, ugh);
- r = STF_FAIL + INVALID_KEY_INFORMATION;
- }
- else
- {
-
-#ifdef USE_KEYRR
- passert(kc->step == kos_his_txt || kc->step == kos_his_key);
-#else
- passert(kc->step == kos_his_txt);
-#endif
- kc->last_ugh = ugh; /* record previous error in case we need it */
- r = (*tail)(kc->md, kc);
- }
- complete_state_transition(&kc->md, r);
- }
- if (kc->md != NULL)
- release_md(kc->md);
- cur_state = NULL;
-}
-
-/* STATE_MAIN_R2:
- * PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
- * DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
- * PKE_AUTH, RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
- *
- * Broken into parts to allow asynchronous DNS lookup.
- *
- * - main_inI3_outR3 to start
- * - main_inI3_outR3_tail to finish or suspend for DNS lookup
- * - main_inI3_outR3_continue to start main_inI3_outR3_tail again
- */
-static key_tail_fn main_inI3_outR3_tail; /* forward */
-
-stf_status
-main_inI3_outR3(struct msg_digest *md)
-{
- return main_inI3_outR3_tail(md, NULL);
-}
-
-static void
-main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
-{
- key_continue(cr, ugh, main_inI3_outR3_tail);
-}
-
-static stf_status
-main_inI3_outR3_tail(struct msg_digest *md
-, struct key_continuation *kc)
-{
- struct state *const st = md->st;
- u_int8_t auth_payload;
- pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
- certpolicy_t cert_policy;
- cert_t mycert;
- bool RSA_auth;
- bool send_cert;
- bool requested;
-
- /* ID and HASH_I or SIG_I in
- * Note: this may switch the connection being used!
- */
- {
- stf_status r = main_id_and_auth(md, FALSE
- , main_inI3_outR3_continue
- , kc);
-
- if (r != STF_OK)
- return r;
- }
-
- /* send certificate if auth is RSA, we have one and we want
- * or are requested to send it
- */
- cert_policy = st->st_connection->spd.this.sendcert;
- mycert = st->st_connection->spd.this.cert;
- requested = cert_policy == CERT_SEND_IF_ASKED
- && st->st_connection->got_certrequest;
- RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
- send_cert = RSA_auth
- && mycert.type != CERT_NONE
- && (cert_policy == CERT_ALWAYS_SEND || requested);
-
- /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
- /* proccess_packet() would automatically generate the HDR*
- * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
- * We don't do this because we wish there to be no partially
- * built output packet if we need to suspend for asynch DNS.
- */
- /* ??? NOTE: this is almost the same as main_inR2_outI3's code */
-
- /* HDR* out
- * If auth were PKE_AUTH or RPKE_AUTH, ISAKMP_NEXT_HASH would
- * be first payload.
- */
- echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
-
- auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
- /* IDir out */
- {
- /* id_hd should be struct isakmp_id, but struct isakmp_ipsec_id
- * allows build_id_payload() to work for both phases.
- */
- struct isakmp_ipsec_id id_hd;
- chunk_t id_b;
-
- build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
- id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
- if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &r_id_pbs)
- || !out_chunk(id_b, &r_id_pbs, "my identity"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&r_id_pbs);
- }
-
- /* CERT out */
- if (RSA_auth)
- {
- DBG(DBG_CONTROL,
- DBG_log("our certificate policy is %s"
- , enum_name(&cert_policy_names, cert_policy))
- )
- if (mycert.type != CERT_NONE)
- {
- const char *request_text = "";
-
- if (cert_policy == CERT_SEND_IF_ASKED)
- request_text = (send_cert)? "upon request":"without request";
- plog("we have a cert %s sending it %s"
- , send_cert? "and are":"but are not", request_text);
- }
- else
- {
- plog("we don't have a cert");
- }
- }
- if (send_cert)
- {
- pb_stream cert_pbs;
-
- struct isakmp_cert cert_hd;
- cert_hd.isacert_np = ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
-
- if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&cert_pbs);
- }
-
- /* HASH_R or SIG_R out */
- {
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len = main_mode_hash(st, hash_val, FALSE, &r_id_pbs);
-
- if (auth_payload == ISAKMP_NEXT_HASH)
- {
- /* HASH_R out */
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody
- , hash_val, hash_len, "HASH_R"))
- return STF_INTERNAL_ERROR;
- }
- else
- {
- /* SIG_R out */
- u_char sig_val[RSA_MAX_OCTETS];
- size_t sig_len = RSA_sign_hash(st->st_connection
- , sig_val, hash_val, hash_len);
-
- if (sig_len == 0)
- {
- loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature");
- return STF_FAIL + AUTHENTICATION_FAILED;
- }
-
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
- , &md->rbody, sig_val, sig_len, "SIG_R"))
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* encrypt message, sans fixed part of header */
-
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
-
- /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */
- DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:"
- , st->st_new_iv, st->st_new_iv_len);
-
- ISAKMP_SA_established(st->st_connection, st->st_serialno);
-
- /* Save Phase 1 IV */
- st->st_ph1_iv_len = st->st_new_iv_len;
- set_ph1_iv(st, st->st_new_iv);
-
- return STF_OK;
-}
-
-/* STATE_MAIN_I3:
- * Handle HDR*;IDir;HASH/SIG_R from responder.
- *
- * Broken into parts to allow asynchronous DNS for KEY records.
- *
- * - main_inR3 to start
- * - main_inR3_tail to finish or suspend for DNS lookup
- * - main_inR3_continue to start main_inR3_tail again
- */
-
-static key_tail_fn main_inR3_tail; /* forward */
-
-stf_status
-main_inR3(struct msg_digest *md)
-{
- return main_inR3_tail(md, NULL);
-}
-
-static void
-main_inR3_continue(struct adns_continuation *cr, err_t ugh)
-{
- key_continue(cr, ugh, main_inR3_tail);
-}
-
-static stf_status
-main_inR3_tail(struct msg_digest *md
-, struct key_continuation *kc)
-{
- struct state *const st = md->st;
-
- /* ID and HASH_R or SIG_R in
- * Note: this may switch the connection being used!
- */
- {
- stf_status r = main_id_and_auth(md, TRUE, main_inR3_continue, kc);
-
- if (r != STF_OK)
- return r;
- }
-
- /**************** done input ****************/
-
- ISAKMP_SA_established(st->st_connection, st->st_serialno);
-
- /* Save Phase 1 IV */
- st->st_ph1_iv_len = st->st_new_iv_len;
- set_ph1_iv(st, st->st_new_iv);
-
-
- update_iv(st); /* finalize our Phase 1 IV */
-
- return STF_OK;
-}
-
-/* Handle first message of Phase 2 -- Quick Mode.
- * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
- * (see RFC 2409 "IKE" 5.5)
- * Installs inbound IPsec SAs.
- * Although this seems early, we know enough to do so, and
- * this way we know that it is soon enough to catch all
- * packets that other side could send using this IPsec SA.
- *
- * Broken into parts to allow asynchronous DNS for TXT records:
- *
- * - quick_inI1_outR1 starts the ball rolling.
- * It checks and parses enough to learn the Phase 2 IDs
- *
- * - quick_inI1_outR1_tail does the rest of the job
- * unless DNS must be consulted. In that case,
- * it starts a DNS query, salts away what is needed
- * to continue, and suspends. Calls
- * + quick_inI1_outR1_start_query
- * + quick_inI1_outR1_process_answer
- *
- * - quick_inI1_outR1_continue will restart quick_inI1_outR1_tail
- * when DNS comes back with an answer.
- *
- * A big chunk of quick_inI1_outR1_tail is executed twice.
- * This is necessary because the set of connections
- * might change while we are awaiting DNS.
- * When first called, gateways_from_dns == NULL. If DNS is
- * consulted asynchronously, gateways_from_dns != NULL the second time.
- * Remember that our state object might disappear too!
- *
- *
- * If the connection is opportunistic, we must verify delegation.
- *
- * 1. Check that we are authorized to be SG for
- * our client. We look for the TXT record that
- * delegates us. We also check that the public
- * key (if present) matches the private key we used.
- * Eventually, we should probably require DNSsec
- * authentication for our side.
- *
- * 2. If our client TXT record did not include a
- * public key, check the KEY record indicated
- * by the identity in the TXT record.
- *
- * 3. If the peer's client is the peer itself, we
- * consider it authenticated. Otherwise, we check
- * the TXT record for the client to see that
- * the identity of the SG matches the peer and
- * that some public key (if present in the TXT)
- * matches. We need not check the public key if
- * it isn't in the TXT record.
- *
- * Since p isn't yet instantiated, we need to look
- * in c for description of peer.
- *
- * We cannot afford to block waiting for a DNS query.
- * The code here is structured as two halves:
- * - process the result of just completed
- * DNS query (if any)
- * - if another query is needed, initiate the next
- * DNS query and suspend
- */
-
-enum verify_oppo_step {
- vos_fail,
- vos_start,
- vos_our_client,
- vos_our_txt,
-#ifdef USE_KEYRR
- vos_our_key,
-#endif /* USE_KEYRR */
- vos_his_client,
- vos_done
-};
-
-static const char *const verify_step_name[] = {
- "vos_fail",
- "vos_start",
- "vos_our_client",
- "vos_our_txt",
-#ifdef USE_KEYRR
- "vos_our_key",
-#endif /* USE_KEYRR */
- "vos_his_client",
- "vos_done"
-};
-
-/* hold anything we can handle of a Phase 2 ID */
-struct p2id {
- ip_subnet net;
- u_int8_t proto;
- u_int16_t port;
-};
-
-struct verify_oppo_bundle {
- enum verify_oppo_step step;
- bool failure_ok; /* if true, quick_inI1_outR1_continue will try
- * other things on DNS failure */
- struct msg_digest *md;
- struct p2id my, his;
- unsigned int new_iv_len; /* p1st's might change */
- u_char new_iv[MAX_DIGEST_LEN];
- /* int whackfd; */ /* not needed because we are Responder */
-};
-
-struct verify_oppo_continuation {
- struct adns_continuation ac; /* common prefix */
- struct verify_oppo_bundle b;
-};
-
-static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b
- , struct adns_continuation *ac);
-
-stf_status
-quick_inI1_outR1(struct msg_digest *md)
-{
- const struct state *const p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
- struct verify_oppo_bundle b;
-
- /* HASH(1) in */
- CHECK_QUICK_HASH(md
- , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
- , p1st, &md->hdr.isa_msgid, FALSE)
- , "HASH(1)", "Quick I1");
-
- /* [ IDci, IDcr ] in
- * We do this now (probably out of physical order) because
- * we wish to select the correct connection before we consult
- * it for policy.
- */
-
- if (id_pd != NULL)
- {
- /* ??? we are assuming IPSEC_DOI */
-
- /* IDci (initiator is peer) */
-
- if (!decode_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
- , &b.his.net, "peer client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* Hack for MS 818043 NAT-T Update */
-
- if (id_pd->payload.ipsec_id.isaiid_idtype == ID_FQDN)
- happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
-
- /* End Hack for MS 818043 NAT-T Update */
-
- b.his.proto = id_pd->payload.ipsec_id.isaiid_protoid;
- b.his.port = id_pd->payload.ipsec_id.isaiid_port;
- b.his.net.addr.u.v4.sin_port = htons(b.his.port);
-
- /* IDcr (we are responder) */
-
- if (!decode_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
- , &b.my.net, "our client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- b.my.proto = id_pd->next->payload.ipsec_id.isaiid_protoid;
- b.my.port = id_pd->next->payload.ipsec_id.isaiid_port;
- b.my.net.addr.u.v4.sin_port = htons(b.my.port);
- }
- else
- {
- /* implicit IDci and IDcr: peer and self */
- if (!sameaddrtype(&c->spd.this.host_addr, &c->spd.that.host_addr))
- return STF_FAIL;
-
- happy(addrtosubnet(&c->spd.this.host_addr, &b.my.net));
- happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
- b.his.proto = b.my.proto = 0;
- b.his.port = b.my.port = 0;
- }
- b.step = vos_start;
- b.md = md;
- b.new_iv_len = p1st->st_new_iv_len;
- memcpy(b.new_iv, p1st->st_new_iv, p1st->st_new_iv_len);
- return quick_inI1_outR1_tail(&b, NULL);
-}
-
-static void
-report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
-{
- struct state *st = b->md->st;
- char fgwb[ADDRTOT_BUF]
- , cb[ADDRTOT_BUF];
- ip_address client;
- err_t which;
-
- switch (b->step)
- {
- case vos_our_client:
- case vos_our_txt:
-#ifdef USE_KEYRR
- case vos_our_key:
-#endif /* USE_KEYRR */
- which = "our";
- networkof(&b->my.net, &client);
- break;
-
- case vos_his_client:
- which = "his";
- networkof(&b->his.net, &client);
- break;
-
- case vos_start:
- case vos_done:
- case vos_fail:
- default:
- bad_case(b->step);
- }
-
- addrtot(&st->st_connection->spd.that.host_addr, 0, fgwb, sizeof(fgwb));
- addrtot(&client, 0, cb, sizeof(cb));
- loglog(RC_OPPOFAILURE
- , "gateway %s wants connection with %s as %s client, but DNS fails to confirm delegation: %s"
- , fgwb, cb, which, ugh);
-}
-
-static void
-quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
-{
- stf_status r;
- struct verify_oppo_continuation *vc = (void *)cr;
- struct verify_oppo_bundle *b = &vc->b;
- struct state *st = b->md->st;
-
- passert(cur_state == NULL);
- /* if st == NULL, our state has been deleted -- just clean up */
- if (st != NULL)
- {
- passert(st->st_suspended_md == b->md);
- st->st_suspended_md = NULL; /* no longer connected or suspended */
- cur_state = st;
- if (!b->failure_ok && ugh != NULL)
- {
- report_verify_failure(b, ugh);
- r = STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
- {
- r = quick_inI1_outR1_tail(b, cr);
- }
- complete_state_transition(&b->md, r);
- }
- if (b->md != NULL)
- release_md(b->md);
- cur_state = NULL;
-}
-
-static stf_status
-quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
-, enum verify_oppo_step next_step)
-{
- struct msg_digest *md = b->md;
- struct state *p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct verify_oppo_continuation *vc
- = alloc_thing(struct verify_oppo_continuation, "verify continuation");
- struct id id /* subject of query */
- , *our_id /* needed for myid playing */
- , our_id_space; /* ephemeral: no need for unshare_id_content */
- ip_address client;
- err_t ugh;
-
- /* Record that state is used by a suspended md */
- b->step = next_step; /* not just vc->b.step */
- vc->b = *b;
- passert(p1st->st_suspended_md == NULL);
- p1st->st_suspended_md = b->md;
-
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
- DBG_log("responding with DNS query - from %s to %s new state: %s"
- , ours, his, verify_step_name[b->step]);
- });
-
- /* Resolve %myid in a cheesy way.
- * We have to do the resolution because start_adns_query
- * et al have insufficient information to do so.
- * If %myid is already known, we'll use that value
- * (XXX this may be a mistake: it could be stale).
- * If %myid is unknown, we should check to see if
- * there are credentials for the IP address or the FQDN.
- * Instead, we'll just assume the IP address since we are
- * acting as the responder and only the IP address would
- * have gotten it to us.
- * We don't even try to do this for the other side:
- * %myid makes no sense for the other side (but it is syntactically
- * legal).
- */
- our_id = resolve_myid(&c->spd.this.id);
- if (our_id->kind == ID_NONE)
- {
- iptoid(&c->spd.this.host_addr, &our_id_space);
- our_id = &our_id_space;
- }
-
- switch (next_step)
- {
- case vos_our_client:
- networkof(&b->my.net, &client);
- iptoid(&client, &id);
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&id
- , our_id
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-
- case vos_our_txt:
- vc->b.failure_ok = b->failure_ok = TRUE;
- ugh = start_adns_query(our_id
- , our_id /* self as SG */
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-
-#ifdef USE_KEYRR
- case vos_our_key:
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(our_id
- , NULL
- , T_KEY
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-#endif
-
- case vos_his_client:
- networkof(&b->his.net, &client);
- iptoid(&client, &id);
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&id
- , &c->spd.that.id
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-
- default:
- bad_case(next_step);
- }
-
- if (ugh != NULL)
- {
- /* note: we'd like to use vc->b but vc has been freed
- * so we have to use b. This is why we plunked next_state
- * into b, not just vc->b.
- */
- report_verify_failure(b, ugh);
- p1st->st_suspended_md = NULL;
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
- {
- return STF_SUSPEND;
- }
-}
-
-static enum verify_oppo_step
-quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
-, struct adns_continuation *ac
-, struct state *p1st)
-{
- struct connection *c = p1st->st_connection;
- enum verify_oppo_step next_step;
- err_t ugh = NULL;
-
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
- DBG_log("responding on demand from %s to %s state: %s"
- , ours, his, verify_step_name[b->step]);
- });
-
- /* process just completed DNS query (if any) */
- switch (b->step)
- {
- case vos_start:
- /* no query to digest */
- next_step = vos_our_client;
- break;
-
- case vos_our_client:
- next_step = vos_his_client;
- {
- const struct RSA_private_key *pri = get_RSA_private_key(c);
- struct gw_info *gwp;
-
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
- break;
- }
- ugh = "our client does not delegate us as its Security Gateway";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- ugh = "our client delegates us as its Security Gateway but with the wrong public key";
- /* If there is no key in the TXT record,
- * we count it as a win, but we will have
- * to separately fetch and check the KEY record.
- * If there is a key from the TXT record,
- * we count it as a win if we match the key.
- */
- if (!gwp->gw_key_present)
- {
- next_step = vos_our_txt;
- ugh = NULL; /* good! */
- break;
- }
- else if (same_RSA_public_key(&pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- break;
-
- case vos_our_txt:
- next_step = vos_his_client;
- {
- const struct RSA_private_key *pri = get_RSA_private_key(c);
-
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
- break;
- }
- {
- struct gw_info *gwp;
-
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
-#ifdef USE_KEYRR
- /* not an error yet, because we have to check KEY RR as well */
- ugh = NULL;
-#else
- ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
-#endif
- if (gwp->gw_key_present
- && same_RSA_public_key(&pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
-#ifdef USE_KEYRR
- next_step = vos_our_key;
-#endif
- }
- }
- }
- break;
-
-#ifdef USE_KEYRR
- case vos_our_key:
- next_step = vos_his_client;
- {
- const struct RSA_private_key *pri = get_RSA_private_key(c);
-
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
- break;
- }
- {
- pubkey_list_t *kp;
-
- ugh = "our client delegation depends on our missing " RRNAME " record";
- for (kp = ac->keys_from_dns; kp != NULL; kp = kp->next)
- {
- ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
- if (same_RSA_public_key(&pri->pub, &kp->key->u.rsa))
- {
- /* do this only once a day */
- if (!logged_txt_warning)
- {
- loglog(RC_LOG_SERIOUS, "found KEY RR but not TXT RR. See http://www.freeswan.org/err/txt-change.html.");
- logged_txt_warning = TRUE;
- }
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- }
- break;
-#endif /* USE_KEYRR */
-
- case vos_his_client:
- next_step = vos_done;
- {
- struct gw_info *gwp;
-
- /* check that the public key that authenticated
- * the ISAKMP SA (p1st) will do for this gateway.
- */
-
- ugh = "peer's client does not delegate to peer";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- ugh = "peer and its client disagree about public key";
- /* If there is a key from the TXT record,
- * we count it as a win if we match the key.
- * If there was no key, we claim a match since
- * it implies fetching a KEY from the same
- * place we must have gotten it.
- */
- if (!gwp->gw_key_present
- || same_RSA_public_key(&p1st->st_peer_pubkey->u.rsa
- , &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- break;
-
- default:
- bad_case(b->step);
- }
-
- if (ugh != NULL)
- {
- report_verify_failure(b, ugh);
- next_step = vos_fail;
- }
- return next_step;
-}
-
-static stf_status
-quick_inI1_outR1_tail(struct verify_oppo_bundle *b
-, struct adns_continuation *ac)
-{
- struct msg_digest *md = b->md;
- struct state *const p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
- ip_subnet *our_net = &b->my.net
- , *his_net = &b->his.net;
-
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* from where to start hashing */
-
- /* Now that we have identities of client subnets, we must look for
- * a suitable connection (our current one only matches for hosts).
- */
- {
- struct connection *p = find_client_connection(c
- , our_net, his_net, b->my.proto, b->my.port, b->his.proto, b->his.port);
-
- if (p == NULL)
- {
- /* This message occurs in very puzzling circumstances
- * so we must add as much information and beauty as we can.
- */
- struct end
- me = c->spd.this,
- he = c->spd.that;
- char buf[2*SUBNETTOT_BUF + 2*ADDRTOT_BUF + 2*BUF_LEN + 2*ADDRTOT_BUF + 12]; /* + 12 for separating */
- size_t l;
-
- me.client = *our_net;
- me.has_client = !subnetisaddr(our_net, &me.host_addr);
- me.protocol = b->my.proto;
- me.port = b->my.port;
-
- he.client = *his_net;
- he.has_client = !subnetisaddr(his_net, &he.host_addr);
- he.protocol = b->his.proto;
- he.port = b->his.port;
-
- l = format_end(buf, sizeof(buf), &me, NULL, TRUE, LEMPTY);
- l += snprintf(buf + l, sizeof(buf) - l, "...");
- (void)format_end(buf + l, sizeof(buf) - l, &he, NULL, FALSE, LEMPTY);
- plog("cannot respond to IPsec SA request"
- " because no connection is known for %s"
- , buf);
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else if (p != c)
- {
- /* We've got a better connection: it can support the
- * specified clients. But it may need instantiation.
- */
- if (p->kind == CK_TEMPLATE)
- {
- /* Yup, it needs instantiation. How much?
- * Is it a Road Warrior connection (simple)
- * or is it an Opportunistic connection (needing gw validation)?
- */
- if (p->policy & POLICY_OPPO)
- {
- /* Opportunistic case: delegation must be verified.
- * Here be dragons.
- */
- enum verify_oppo_step next_step;
- ip_address our_client, his_client;
-
- passert(subnetishost(our_net) && subnetishost(his_net));
- networkof(our_net, &our_client);
- networkof(his_net, &his_client);
-
- next_step = quick_inI1_outR1_process_answer(b, ac, p1st);
- if (next_step == vos_fail)
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* short circuit: if peer's client is self,
- * accept that we've verified delegation in Phase 1
- */
- if (next_step == vos_his_client
- && sameaddr(&c->spd.that.host_addr, &his_client))
- next_step = vos_done;
-
- /* the second chunk: initiate the next DNS query (if any) */
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
- DBG_log("responding on demand from %s to %s new state: %s"
- , ours, his, verify_step_name[next_step]);
- });
-
- /* start next DNS query and suspend (if necessary) */
- if (next_step != vos_done)
- return quick_inI1_outR1_start_query(b, next_step);
-
- /* Instantiate inbound Opportunistic connection,
- * carrying over authenticated peer ID
- * and filling in a few more details.
- * We used to include gateways_from_dns, but that
- * seems pointless at this stage of negotiation.
- * We should record DNS sec use, if any -- belongs in
- * state during perhaps.
- */
- p = oppo_instantiate(p, &c->spd.that.host_addr, &c->spd.that.id
- , NULL, &our_client, &his_client);
- }
- else
- {
- /* Plain Road Warrior:
- * instantiate, carrying over authenticated peer ID
- */
- p = rw_instantiate(p, &c->spd.that.host_addr,
-#ifdef NAT_TRAVERSAL
- md->sender_port,
-#endif
-#ifdef VIRTUAL_IP
- his_net,
-#endif
- &c->spd.that.id);
- }
- }
-#ifdef DEBUG
- /* temporarily bump up cur_debugging to get "using..." message
- * printed if we'd want it with new connection.
- */
- {
- lset_t old_cur_debugging = cur_debugging;
-
- cur_debugging |= p->extra_debugging;
- DBG(DBG_CONTROL, DBG_log("using connection \"%s\"", p->name));
- cur_debugging = old_cur_debugging;
- }
-#endif
- c = p;
- }
- /* fill in the client's true ip address/subnet */
- if (p->spd.that.has_client_wildcard)
- {
- p->spd.that.client = *his_net;
- p->spd.that.has_client_wildcard = FALSE;
- }
-
-#ifdef VIRTUAL_IP
- else if (is_virtual_connection(c))
- {
- c->spd.that.client = *his_net;
- c->spd.that.virt = NULL;
- if (subnetishost(his_net) && addrinsubnet(&c->spd.that.host_addr, his_net))
- c->spd.that.has_client = FALSE;
- }
-#endif
-
- /* fill in the client's true port */
- if (p->spd.that.has_port_wildcard)
- {
- int port = htons(b->his.port);
-
- setportof(port, &p->spd.that.host_addr);
- setportof(port, &p->spd.that.client.addr);
-
- p->spd.that.port = b->his.port;
- p->spd.that.has_port_wildcard = FALSE;
- }
- }
-
- /* now that we are sure of our connection, create our new state */
- {
- struct state *const st = duplicate_state(p1st);
-
- /* first: fill in missing bits of our new state object
- * note: we don't copy over st_peer_pubkey, the public key
- * that authenticated the ISAKMP SA. We only need it in this
- * routine, so we can "reach back" to p1st to get it.
- */
-
- if (st->st_connection != c)
- {
- struct connection *t = st->st_connection;
-
- st->st_connection = c;
- set_cur_connection(c);
- connection_discard(t);
- }
-
- st->st_try = 0; /* not our job to try again from start */
-
- st->st_msgid = md->hdr.isa_msgid;
-
- st->st_new_iv_len = b->new_iv_len;
- memcpy(st->st_new_iv, b->new_iv, b->new_iv_len);
-
- set_cur_state(st); /* (caller will reset) */
- md->st = st; /* feed back new state */
-
- st->st_peeruserprotoid = b->his.proto;
- st->st_peeruserport = b->his.port;
- st->st_myuserprotoid = b->my.proto;
- st->st_myuserport = b->my.port;
-
- insert_state(st); /* needs cookies, connection, and msgid */
-
- /* copy the connection's
- * IPSEC policy into our state. The ISAKMP policy is water under
- * the bridge, I think. It will reflect the ISAKMP SA that we
- * are using.
- */
- st->st_policy = (p1st->st_policy & POLICY_ISAKMP_MASK)
- | (c->policy & ~POLICY_ISAKMP_MASK);
-
-#ifdef NAT_TRAVERSAL
- if (p1st->nat_traversal & NAT_T_DETECTED)
- {
- st->nat_traversal = p1st->nat_traversal;
- nat_traversal_change_port_lookup(md, md->st);
- }
- else
- {
- st->nat_traversal = 0;
- }
- if ((st->nat_traversal & NAT_T_DETECTED) &&
- (st->nat_traversal & NAT_T_WITH_NATOA))
- {
- nat_traversal_natoa_lookup(md);
- }
-#endif
-
- /* Start the output packet.
- *
- * proccess_packet() would automatically generate the HDR*
- * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
- * We don't do this because we wish there to be no partially
- * built output packet if we need to suspend for asynch DNS.
- *
- * We build the reply packet as we parse the message since
- * the parse_ipsec_sa_body emits the reply SA
- */
-
- /* HDR* out */
- echo_hdr(md, TRUE, ISAKMP_NEXT_HASH);
-
- /* HASH(2) out -- first pass */
- START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_SA);
-
- /* process SA (in and out) */
- {
- struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
- pb_stream r_sa_pbs;
- struct isakmp_sa sa = sapd->payload.sa;
-
- /* sa header is unchanged -- except for np */
- sa.isasa_np = ISAKMP_NEXT_NONCE;
- if (!out_struct(&sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
- return STF_INTERNAL_ERROR;
-
- /* parse and accept body */
- st->st_pfs_group = &unset_group;
- RETURN_STF_FAILURE(parse_ipsec_sa_body(&sapd->pbs
- , &sapd->payload.sa, &r_sa_pbs, FALSE, st));
- }
-
- passert(st->st_pfs_group != &unset_group);
-
- if ((st->st_policy & POLICY_PFS) && st->st_pfs_group == NULL)
- {
- loglog(RC_LOG_SERIOUS, "we require PFS but Quick I1 SA specifies no GROUP_DESCRIPTION");
- return STF_FAIL + NO_PROPOSAL_CHOSEN; /* ??? */
- }
-
- /* Ni in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
-
- /* [ KE ] in (for PFS) */
- RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gi, "Gi", "Quick Mode I1"));
-
- plog("responding to Quick Mode");
-
- /**** finish reply packet: Nr [, KE ] [, IDci, IDcr ] ****/
-
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody
- , st->st_pfs_group != NULL? ISAKMP_NEXT_KE : id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE
- , "Nr"))
- return STF_INTERNAL_ERROR;
-
- /* [ KE ] out (for PFS) */
-
- if (st->st_pfs_group != NULL)
- {
- if (!build_and_ship_KE(st, &st->st_gr, st->st_pfs_group
- , &md->rbody, id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE))
- return STF_INTERNAL_ERROR;
-
- /* MPZ-Operations might be done after sending the packet... */
- compute_dh_shared(st, st->st_gi, st->st_pfs_group);
- }
-
- /* [ IDci, IDcr ] out */
- if (id_pd != NULL)
- {
- struct isakmp_ipsec_id *p = (void *)md->rbody.cur; /* UGH! */
-
- if (!out_raw(id_pd->pbs.start, pbs_room(&id_pd->pbs), &md->rbody, "IDci"))
- return STF_INTERNAL_ERROR;
- p->isaiid_np = ISAKMP_NEXT_ID;
-
- p = (void *)md->rbody.cur; /* UGH! */
-
- if (!out_raw(id_pd->next->pbs.start, pbs_room(&id_pd->next->pbs), &md->rbody, "IDcr"))
- return STF_INTERNAL_ERROR;
- p->isaiid_np = ISAKMP_NEXT_NONE;
- }
-
-#ifdef NAT_TRAVERSAL
- if ((st->nat_traversal & NAT_T_WITH_NATOA)
- && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
- && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT))
- {
- /** Send NAT-OA if our address is NATed and if we use Transport Mode */
- if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &md->rbody, md->st))
- {
- return STF_INTERNAL_ERROR;
- }
- }
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT)
- && (c->spd.that.has_client))
- {
- /** Remove client **/
- addrtosubnet(&c->spd.that.host_addr, &c->spd.that.client);
- c->spd.that.has_client = FALSE;
- }
-#endif
-
- /* Compute reply HASH(2) and insert in output */
- (void)quick_mode_hash12(r_hashval, r_hash_start, md->rbody.cur
- , st, &st->st_msgid, TRUE);
-
- /* Derive new keying material */
- compute_keymats(st);
-
- /* Tell the kernel to establish the new inbound SA
- * (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_inbound_ipsec_sa(st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
-
- /* encrypt message, except for fixed part of header */
-
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
-
- return STF_OK;
- }
-}
-
-/*
- * Initialize RFC 3706 Dead Peer Detection
- */
-static void
-dpd_init(struct state *st)
-{
- struct state *p1st = find_state(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr, 0);
-
- if (p1st == NULL)
- loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");
- else if (p1st->st_dpd)
- {
- plog("Dead Peer Detection (RFC 3706) enabled");
- /* randomize the first DPD event */
-
- event_schedule(EVENT_DPD
- , (0.5 + rand()/(RAND_MAX + 1.E0)) * st->st_connection->dpd_delay
- , st);
- }
-}
-
-/* Handle (the single) message from Responder in Quick Mode.
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(3)
- * (see RFC 2409 "IKE" 5.5)
- * Installs inbound and outbound IPsec SAs, routing, etc.
- */
-stf_status
-quick_inR1_outI2(struct msg_digest *md)
-{
- struct state *const st = md->st;
- const struct connection *c = st->st_connection;
-
- /* HASH(2) in */
- CHECK_QUICK_HASH(md
- , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
- , st, &st->st_msgid, TRUE)
- , "HASH(2)", "Quick R1");
-
- /* SA in */
- {
- struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
-
- RETURN_STF_FAILURE(parse_ipsec_sa_body(&sa_pd->pbs
- , &sa_pd->payload.sa, NULL, TRUE, st));
- }
-
- /* Nr in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
-
- /* [ KE ] in (for PFS) */
- RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1"));
-
- if (st->st_pfs_group != NULL)
- compute_dh_shared(st, st->st_gr, st->st_pfs_group);
-
- /* [ IDci, IDcr ] in; these must match what we sent */
-
- {
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
-
- if (id_pd != NULL)
- {
- /* ??? we are assuming IPSEC_DOI */
-
- /* IDci (we are initiator) */
-
- if (!check_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
- , &st->st_myuserprotoid, &st->st_myuserport
- , &st->st_connection->spd.this.client
- , "our client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* IDcr (responder is peer) */
-
- if (!check_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
- , &st->st_peeruserprotoid, &st->st_peeruserport
- , &st->st_connection->spd.that.client
- , "peer client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
- {
- /* no IDci, IDcr: we must check that the defaults match our proposal */
- if (!subnetisaddr(&c->spd.this.client, &c->spd.this.host_addr)
- || !subnetisaddr(&c->spd.that.client, &c->spd.that.host_addr))
- {
- loglog(RC_LOG_SERIOUS, "IDci, IDcr payloads missing in message"
- " but default does not match proposal");
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- }
- }
-
- /* check the peer's group attributes */
-
- {
- const ietfAttrList_t *peer_list = NULL;
-
- get_peer_ca_and_groups(st->st_connection, &peer_list);
-
- if (!group_membership(peer_list, st->st_connection->name
- , st->st_connection->spd.that.groups))
- {
- char buf[BUF_LEN];
-
- format_groups(st->st_connection->spd.that.groups, buf, BUF_LEN);
- loglog(RC_LOG_SERIOUS, "peer is not member of one of the groups: %s"
- , buf);
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- }
-
-#ifdef NAT_TRAVERSAL
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->nat_traversal & NAT_T_WITH_NATOA))
- {
- nat_traversal_natoa_lookup(md);
- }
-#endif
-
- /* ??? We used to copy the accepted proposal into the state, but it was
- * never used. From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).
- */
-
- /**************** build reply packet HDR*, HASH(3) ****************/
-
- /* HDR* out done */
-
- /* HASH(3) out -- since this is the only content, no passes needed */
- {
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
-
- START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_NONE);
- (void)quick_mode_hash3(r_hashval, st);
- }
-
- /* Derive new keying material */
- compute_keymats(st);
-
- /* Tell the kernel to establish the inbound, outbound, and routing part
- * of the new SA (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_ipsec_sa(st, TRUE))
- return STF_INTERNAL_ERROR;
-
- /* encrypt message, except for fixed part of header */
-
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
-
- {
- DBG(DBG_CONTROLMORE, DBG_log("inR1_outI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
- , st->st_connection->name
- , st->st_connection->instance_serial
- , st->st_serialno
- , st->st_connection->newest_ipsec_sa
- , st->st_connection->spd.eroute_owner));
- }
-
- st->st_connection->newest_ipsec_sa = st->st_serialno;
-
- /* note (presumed) success */
- if (c->gw_info != NULL)
- c->gw_info->key->last_worked_time = now();
-
- /* If we want DPD on this connection then initialize it */
- if (st->st_connection->dpd_action != DPD_ACTION_NONE)
- dpd_init(st);
-
- return STF_OK;
-}
-
-/* Handle last message of Quick Mode.
- * HDR*, HASH(3) -> done
- * (see RFC 2409 "IKE" 5.5)
- * Installs outbound IPsec SAs, routing, etc.
- */
-stf_status
-quick_inI2(struct msg_digest *md)
-{
- struct state *const st = md->st;
-
- /* HASH(3) in */
- CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st)
- , "HASH(3)", "Quick I2");
-
- /* Tell the kernel to establish the outbound and routing part of the new SA
- * (the previous state established inbound)
- * (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_ipsec_sa(st, FALSE))
- return STF_INTERNAL_ERROR;
-
- {
- DBG(DBG_CONTROLMORE, DBG_log("inI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
- , st->st_connection->name
- , st->st_connection->instance_serial
- , st->st_serialno
- , st->st_connection->newest_ipsec_sa
- , st->st_connection->spd.eroute_owner));
- }
-
- st->st_connection->newest_ipsec_sa = st->st_serialno;
-
- update_iv(st); /* not actually used, but tidy */
-
- /* note (presumed) success */
- {
- struct gw_info *gw = st->st_connection->gw_info;
-
- if (gw != NULL)
- gw->key->last_worked_time = now();
- }
-
- /* If we want DPD on this connection then initialize it */
- if (st->st_connection->dpd_action != DPD_ACTION_NONE)
- dpd_init(st);
-
- return STF_OK;
-}
-
-static stf_status
-send_isakmp_notification(struct state *st, u_int16_t type
- , const void *data, size_t len)
-{
- msgid_t msgid;
- pb_stream reply;
- pb_stream rbody;
- u_char
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
-
- msgid = generate_msgid(st);
-
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "ISAKMP notify");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- impossible();
- }
- /* HASH -- create and note space to be filled later */
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_N);
-
- /* NOTIFY */
- {
- pb_stream notify_pbs;
- struct isakmp_notification isan;
-
- isan.isan_np = ISAKMP_NEXT_NONE;
- isan.isan_doi = ISAKMP_DOI_IPSEC;
- isan.isan_protoid = PROTO_ISAKMP;
- isan.isan_spisize = COOKIE_SIZE * 2;
- isan.isan_type = type;
- if (!out_struct(&isan, &isakmp_notification_desc, &rbody, &notify_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_raw(st->st_icookie, COOKIE_SIZE, &notify_pbs, "notify icookie"))
- return STF_INTERNAL_ERROR;
- if (!out_raw(st->st_rcookie, COOKIE_SIZE, &notify_pbs, "notify rcookie"))
- return STF_INTERNAL_ERROR;
- if (data != NULL && len > 0)
- if (!out_raw(data, len, &notify_pbs, "notify data"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&notify_pbs);
- }
-
- {
- /* finish computing HASH */
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, rbody.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size));
- }
-
- /* Encrypt message (preserve st_iv and st_new_iv) */
- {
- u_char old_iv[MAX_DIGEST_LEN];
- u_char new_iv[MAX_DIGEST_LEN];
-
- u_int old_iv_len = st->st_iv_len;
- u_int new_iv_len = st->st_new_iv_len;
-
- if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
- return STF_INTERNAL_ERROR;
-
- memcpy(old_iv, st->st_iv, old_iv_len);
- memcpy(new_iv, st->st_new_iv, new_iv_len);
-
- init_phase2_iv(st, &msgid);
- if (!encrypt_message(&rbody, st))
- return STF_INTERNAL_ERROR;
-
- /* restore preserved st_iv and st_new_iv */
- memcpy(st->st_iv, old_iv, old_iv_len);
- memcpy(st->st_new_iv, new_iv, new_iv_len);
- st->st_iv_len = old_iv_len;
- st->st_new_iv_len = new_iv_len;
- }
-
- /* Send packet (preserve st_tpacket) */
- {
- chunk_t saved_tpacket = st->st_tpacket;
-
- setchunk(st->st_tpacket, reply.start, pbs_offset(&reply));
- send_packet(st, "ISAKMP notify");
- st->st_tpacket = saved_tpacket;
- }
-
- return STF_IGNORE;
-}
-
-/*
- * DPD Out Initiator
- */
-void
-dpd_outI(struct state *p2st)
-{
- struct state *st;
- u_int32_t seqno;
- time_t tm;
- time_t idle_time;
- time_t delay = p2st->st_connection->dpd_delay;
- time_t timeout = p2st->st_connection->dpd_timeout;
-
- /* find the newest related Phase 1 state */
- st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-
- if (st == NULL)
- {
- loglog(RC_LOG_SERIOUS, "DPD: Could not find newest phase 1 state");
- return;
- }
-
- /* If no DPD, then get out of here */
- if (!st->st_dpd)
- return;
-
- /* schedule the next periodic DPD event */
- event_schedule(EVENT_DPD, delay, p2st);
-
- /* Current time */
- tm = now();
-
- /* Make sure we really need to invoke DPD */
- if (!was_eroute_idle(p2st, delay, &idle_time))
- {
- DBG(DBG_CONTROL,
- DBG_log("recent eroute activity %u seconds ago, "
- "no need to send DPD notification"
- , (int)idle_time)
- )
- st->st_last_dpd = tm;
- delete_dpd_event(st);
- return;
- }
-
- /* If an R_U_THERE has been sent or received recently, or if a
- * companion Phase 2 SA has shown eroute activity,
- * then we don't need to invoke DPD.
- */
- if (tm < st->st_last_dpd + delay)
- {
- DBG(DBG_CONTROL,
- DBG_log("recent DPD activity %u seconds ago, "
- "no need to send DPD notification"
- , (int)(tm - st->st_last_dpd))
- )
- return;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- return;
-
- if (!st->st_dpd_seqno)
- {
- /* Get a non-zero random value that has room to grow */
- get_rnd_bytes((u_char *)&st->st_dpd_seqno, sizeof(st->st_dpd_seqno));
- st->st_dpd_seqno &= 0x7fff;
- st->st_dpd_seqno++;
- }
- seqno = htonl(st->st_dpd_seqno);
-
- if (send_isakmp_notification(st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
- {
- loglog(RC_LOG_SERIOUS, "DPD: Could not send R_U_THERE");
- return;
- }
- DBG(DBG_CONTROL,
- DBG_log("sent DPD notification R_U_THERE with seqno = %u", st->st_dpd_seqno)
- )
- st->st_dpd_expectseqno = st->st_dpd_seqno++;
- st->st_last_dpd = tm;
- /* Only schedule a new timeout if there isn't one currently,
- * or if it would be sooner than the current timeout. */
- if (st->st_dpd_event == NULL
- || st->st_dpd_event->ev_time > tm + timeout)
- {
- delete_dpd_event(st);
- event_schedule(EVENT_DPD_TIMEOUT, timeout, st);
- }
-}
-
-/*
- * DPD in Initiator, out Responder
- */
-stf_status
-dpd_inI_outR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
-{
- time_t tm = now();
- u_int32_t seqno;
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "DPD: Received R_U_THERE for unestablished ISKAMP SA");
- return STF_IGNORE;
- }
- if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid SPI length (%d)", n->isan_spisize);
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
- {
-#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
-#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid icookie (broken Cisco?)");
- return STF_FAIL + INVALID_COOKIE;
-#endif
- }
- pbs->cur += COOKIE_SIZE;
-
- if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid rcookie (broken Cisco?)");
- return STF_FAIL + INVALID_COOKIE;
- }
- pbs->cur += COOKIE_SIZE;
-
- if (pbs_left(pbs) != sizeof(seqno))
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid data length (%d)"
- , (int) pbs_left(pbs));
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- seqno = ntohl(*(u_int32_t *)pbs->cur);
- DBG(DBG_CONTROL,
- DBG_log("received DPD notification R_U_THERE with seqno = %u", seqno)
- )
-
- if (st->st_dpd_peerseqno && seqno <= st->st_dpd_peerseqno) {
- loglog(RC_LOG_SERIOUS, "DPD: Received old or duplicate R_U_THERE");
- return STF_IGNORE;
- }
-
- st->st_dpd_peerseqno = seqno;
- delete_dpd_event(st);
-
- if (send_isakmp_notification(st, R_U_THERE_ACK, pbs->cur, pbs_left(pbs)) != STF_IGNORE)
- {
- loglog(RC_LOG_SERIOUS, "DPD Info: could not send R_U_THERE_ACK");
- return STF_IGNORE;
- }
- DBG(DBG_CONTROL,
- DBG_log("sent DPD notification R_U_THERE_ACK with seqno = %u", seqno)
- )
-
- st->st_last_dpd = tm;
- return STF_IGNORE;
-}
-
-/*
- * DPD out Responder
- */
-stf_status
-dpd_inR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
-{
- u_int32_t seqno;
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: Received R_U_THERE_ACK for unestablished ISKAMP SA");
- return STF_FAIL;
- }
-
- if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: R_U_THERE_ACK has invalid SPI length (%d)"
- , n->isan_spisize);
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
- {
-#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
-#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid icookie");
- return STF_FAIL + INVALID_COOKIE;
-#endif
- }
- pbs->cur += COOKIE_SIZE;
-
- if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
- {
-#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
-#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid rcookie");
- return STF_FAIL + INVALID_COOKIE;
-#endif
- }
- pbs->cur += COOKIE_SIZE;
-
- if (pbs_left(pbs) != sizeof(seqno))
- {
- loglog(RC_LOG_SERIOUS
- , " DPD: R_U_THERE_ACK has invalid data length (%d)"
- , (int) pbs_left(pbs));
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- seqno = ntohl(*(u_int32_t *)pbs->cur);
- DBG(DBG_CONTROL,
- DBG_log("received DPD notification R_U_THERE_ACK with seqno = %u"
- , seqno)
- )
-
- if (!st->st_dpd_expectseqno && seqno != st->st_dpd_expectseqno)
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: R_U_THERE_ACK has unexpected sequence number");
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- st->st_dpd_expectseqno = 0;
- delete_dpd_event(st);
- return STF_IGNORE;
-}
-
-/*
- * DPD Timeout Function
- *
- * This function is called when a timeout DPD_EVENT occurs. We set clear/trap
- * both the SA and the eroutes, depending on what the connection definition
- * tells us (either 'hold' or 'clear')
- */
-void
-dpd_timeout(struct state *st)
-{
- struct state *newest_phase1_st;
- struct connection *c = st->st_connection;
- int action = st->st_connection->dpd_action;
-
- passert(action == DPD_ACTION_HOLD
- || action == DPD_ACTION_CLEAR
- || DPD_ACTION_RESTART);
-
- /* is there a newer phase1_state? */
- newest_phase1_st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
- if (newest_phase1_st != NULL && newest_phase1_st != st)
- {
- plog("DPD: Phase1 state #%ld has been superseded by #%ld"
- " - timeout ignored"
- , st->st_serialno, newest_phase1_st->st_serialno);
- return;
- }
-
- loglog(RC_LOG_SERIOUS, "DPD: No response from peer - declaring peer dead");
-
- /* delete the state, which is probably in phase 2 */
- set_cur_connection(c);
- plog("DPD: Terminating all SAs using this connection");
- delete_states_by_connection(c, TRUE);
- reset_cur_connection();
-
- switch (action)
- {
- case DPD_ACTION_HOLD:
- /* dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
- * leak traffic. Also, being in %trap means new packets will
- * force an initiation of the conn again.
- */
- loglog(RC_LOG_SERIOUS, "DPD: Putting connection into %%trap");
- break;
- case DPD_ACTION_CLEAR:
- /* dpdaction=clear - Wipe the SA & eroute - everything */
- loglog(RC_LOG_SERIOUS, "DPD: Clearing connection");
- unroute_connection(c);
- break;
- case DPD_ACTION_RESTART:
- /* dpdaction=restart - Restart connection,
- * except if roadwarrior connection
- */
- loglog(RC_LOG_SERIOUS, "DPD: Restarting connection");
- unroute_connection(c);
- initiate_connection(c->name, NULL_FD);
- break;
- default:
- loglog(RC_LOG_SERIOUS, "DPD: unknown action");
- }
-}
-
diff --git a/programs/pluto/ipsec_doi.h b/programs/pluto/ipsec_doi.h
deleted file mode 100644
index 80b12c31d..000000000
--- a/programs/pluto/ipsec_doi.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* IPsec DOI and Oakley resolution routines
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_doi.h,v 1.3 2005/01/06 22:10:44 as Exp $
- */
-
-extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np);
-
-extern void ipsecdoi_initiate(int whack_sock, struct connection *c
- , lset_t policy, unsigned long try, so_serial_t replacing);
-
-extern void ipsecdoi_replace(struct state *st, unsigned long try);
-
-extern void init_phase2_iv(struct state *st, const msgid_t *msgid);
-
-extern stf_status quick_outI1(int whack_sock
- , struct state *isakmp_sa
- , struct connection *c
- , lset_t policy
- , unsigned long try
- , so_serial_t replacing);
-
-extern state_transition_fn
- main_inI1_outR1,
- main_inR1_outI2,
- main_inI2_outR2,
- main_inR2_outI3,
- main_inI3_outR3,
- main_inR3,
- quick_inI1_outR1,
- quick_inR1_outI2,
- quick_inI2;
-
-extern void send_delete(struct state *st);
-extern void accept_delete(struct state *st, struct msg_digest *md
- , struct payload_digest *p);
-extern void close_message(pb_stream *pbs);
-extern bool encrypt_message(pb_stream *pbs, struct state *st);
-
-
-extern void send_notification_from_state(struct state *st,
- enum state_kind state, u_int16_t type);
-extern void send_notification_from_md(struct msg_digest *md, u_int16_t type);
-
-extern const char *init_pluto_vendorid(void);
-
-extern void dpd_outI(struct state *st);
-extern stf_status dpd_inI_outR(struct state *st
- , struct isakmp_notification *const n, pb_stream *n_pbs);
-extern stf_status dpd_inR(struct state *st
- , struct isakmp_notification *const n, pb_stream *n_pbs);
-extern void dpd_timeout(struct state *st);
-
-/* START_HASH_PAYLOAD
- *
- * Emit a to-be-filled-in hash payload, noting the field start (r_hashval)
- * and the start of the part of the message to be hashed (r_hash_start).
- * This macro is magic.
- * - it can cause the caller to return
- * - it references variables local to the caller (r_hashval, r_hash_start, st)
- */
-#define START_HASH_PAYLOAD(rbody, np) { \
- pb_stream hash_pbs; \
- if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
- return STF_INTERNAL_ERROR; \
- r_hashval = hash_pbs.cur; /* remember where to plant value */ \
- if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
- return STF_INTERNAL_ERROR; \
- close_output_pbs(&hash_pbs); \
- r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
-}
-
-/* CHECK_QUICK_HASH
- *
- * This macro is magic -- it cannot be expressed as a function.
- * - it causes the caller to return!
- * - it declares local variables and expects the "do_hash" argument
- * expression to reference them (hash_val, hash_pbs)
- */
-#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
- pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
- u_char hash_val[MAX_DIGEST_LEN]; \
- size_t hash_len = do_hash; \
- if (pbs_left(hash_pbs) != hash_len \
- || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
- { \
- DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \
- loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \
- /* XXX Could send notification back */ \
- return STF_FAIL + INVALID_HASH_INFORMATION; \
- } \
- }
-
-
diff --git a/programs/pluto/kameipsec.h b/programs/pluto/kameipsec.h
deleted file mode 100644
index 5f08c7d38..000000000
--- a/programs/pluto/kameipsec.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __IPSEC_H
-#define __IPSEC_H 1
-
-/* The definitions, required to talk to KAME racoon IKE. */
-
-#define IPSEC_PORT_ANY 0
-#define IPSEC_ULPROTO_ANY 255
-#define IPSEC_PROTO_ANY 255
-
-enum {
- IPSEC_MODE_ANY = 0, /* We do not support this for SA */
- IPSEC_MODE_TRANSPORT = 1,
- IPSEC_MODE_TUNNEL = 2
-};
-
-enum {
- IPSEC_DIR_ANY = 0,
- IPSEC_DIR_INBOUND = 1,
- IPSEC_DIR_OUTBOUND = 2,
- IPSEC_DIR_FWD = 3, /* It is our own */
- IPSEC_DIR_MAX = 4,
- IPSEC_DIR_INVALID = 5
-};
-
-enum {
- IPSEC_POLICY_DISCARD = 0,
- IPSEC_POLICY_NONE = 1,
- IPSEC_POLICY_IPSEC = 2,
- IPSEC_POLICY_ENTRUST = 3,
- IPSEC_POLICY_BYPASS = 4
-};
-
-enum {
- IPSEC_LEVEL_DEFAULT = 0,
- IPSEC_LEVEL_USE = 1,
- IPSEC_LEVEL_REQUIRE = 2,
- IPSEC_LEVEL_UNIQUE = 3
-};
-
-#define IPSEC_MANUAL_REQID_MAX 0x3fff
-
-#define IPSEC_REPLAYWSIZE 32
-
-#define IP_IPSEC_POLICY 16
-#define IPV6_IPSEC_POLICY 34
-
-#endif /* __IPSEC_H */
diff --git a/programs/pluto/kernel.c b/programs/pluto/kernel.c
deleted file mode 100644
index d2070c0d4..000000000
--- a/programs/pluto/kernel.c
+++ /dev/null
@@ -1,2999 +0,0 @@
-/* routines that interface with the kernel's IPsec mechanism
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel.c,v 1.26 2006/04/29 18:16:02 as Exp $
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/queue.h>
-
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#ifdef KLIPS
-#include <signal.h>
-#include <sys/time.h> /* for select(2) */
-#include <sys/types.h> /* for select(2) */
-#include <pfkeyv2.h>
-#include <pfkey.h>
-#include "kameipsec.h"
-#endif /* KLIPS */
-
-#include "constants.h"
-#include "defs.h"
-#include "rnd.h"
-#include "id.h"
-#include "connections.h"
-#include "state.h"
-#include "timer.h"
-#include "kernel.h"
-#include "kernel_netlink.h"
-#include "kernel_pfkey.h"
-#include "kernel_noklips.h"
-#include "log.h"
-#include "ca.h"
-#include "server.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-#include "keys.h"
-
-#ifdef NAT_TRAVERSAL
-#include "packet.h" /* for pb_stream in nat_traversal.h */
-#include "nat_traversal.h"
-#endif
-
-#include "alg_info.h"
-#include "kernel_alg.h"
-
-
-bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
-
-/* How far can IPsec messages arrive out of order before the anti-replay
- * logic loses track and swats them? 64 is the best KLIPS can do.
- * And 32 is the best XFRM can do...
- */
-#define REPLAY_WINDOW 64
-#define REPLAY_WINDOW_XFRM 32
-
-/* test if the routes required for two different connections agree
- * It is assumed that the destination subnets agree; we are only
- * testing that the interfaces and nexthops match.
- */
-#define routes_agree(c, d) ((c)->interface == (d)->interface \
- && sameaddr(&(c)->spd.this.host_nexthop, &(d)->spd.this.host_nexthop))
-
-#ifndef KLIPS
-
-bool no_klips = TRUE; /* don't actually use KLIPS */
-
-#else /* !KLIPS */
-
-/* bare (connectionless) shunt (eroute) table
- *
- * Bare shunts are those that don't "belong" to a connection.
- * This happens because some %trapped traffic hasn't yet or cannot be
- * assigned to a connection. The usual reason is that we cannot discover
- * the peer SG. Another is that even when the peer has been discovered,
- * it may be that no connection matches all the particulars.
- * We record them so that, with scanning, we can discover
- * which %holds are news and which others should expire.
- */
-
-#define SHUNT_SCAN_INTERVAL (60 * 2) /* time between scans of eroutes */
-
-/* SHUNT_PATIENCE only has resolution down to a multiple of the sample rate,
- * SHUNT_SCAN_INTERVAL.
- * By making SHUNT_PATIENCE an odd multiple of half of SHUNT_SCAN_INTERVAL,
- * we minimize the effects of jitter.
- */
-#define SHUNT_PATIENCE (SHUNT_SCAN_INTERVAL * 15 / 2) /* inactivity timeout */
-
-struct bare_shunt {
- policy_prio_t policy_prio;
- ip_subnet ours;
- ip_subnet his;
- ip_said said;
- int transport_proto;
- unsigned long count;
- time_t last_activity;
- char *why;
- struct bare_shunt *next;
-};
-
-static struct bare_shunt *bare_shunts = NULL;
-
-#ifdef DEBUG
-static void
-DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
-{
- DBG(DBG_KLIPS,
- {
- int ourport = ntohs(portof(&(bs)->ours.addr));
- int hisport = ntohs(portof(&(bs)->his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
- char prio[POLICY_PRIO_BUF];
-
- subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
- subnettot(&(bs)->his, 0, hist, sizeof(hist));
- satot(&(bs)->said, 0, sat, sizeof(sat));
- fmt_policy_prio(bs->policy_prio, prio);
- DBG_log("%s bare shunt %p %s:%d -> %s:%d => %s:%d %s %s"
- , op, (const void *)(bs), ourst, ourport, hist, hisport
- , sat, (bs)->transport_proto, prio, (bs)->why);
- });
-}
-#else /* !DEBUG */
-#define DBG_bare_shunt(op, bs) {}
-#endif /* !DEBUG */
-
-/* The orphaned_holds table records %holds for which we
- * scan_proc_shunts found no representation of in any connection.
- * The corresponding ACQUIRE message might have been lost.
- */
-struct eroute_info *orphaned_holds = NULL;
-
-/* forward declaration */
-static bool shunt_eroute(struct connection *c
- , struct spd_route *sr
- , enum routing_t rt_kind
- , unsigned int op, const char *opname);
-static void set_text_said(char *text_said
- , const ip_address *dst
- , ipsec_spi_t spi
- , int proto);
-
-bool no_klips = FALSE; /* don't actually use KLIPS */
-
-static const struct pfkey_proto_info null_proto_info[2] = {
- {
- proto: IPPROTO_ESP,
- encapsulation: ENCAPSULATION_MODE_TRANSPORT,
- reqid: 0
- },
- {
- proto: 0,
- encapsulation: 0,
- reqid: 0
- }
-};
-
-void
-record_and_initiate_opportunistic(const ip_subnet *ours
- , const ip_subnet *his
- , int transport_proto
- , const char *why)
-{
- passert(samesubnettype(ours, his));
-
- /* Add to bare shunt list.
- * We need to do this because the shunt was installed by KLIPS
- * which can't do this itself.
- */
- {
- struct bare_shunt *bs = alloc_thing(struct bare_shunt, "bare shunt");
-
- bs->why = clone_str(why, "story for bare shunt");
- bs->ours = *ours;
- bs->his = *his;
- bs->transport_proto = transport_proto;
- bs->policy_prio = BOTTOM_PRIO;
-
- bs->said.proto = SA_INT;
- bs->said.spi = htonl(SPI_HOLD);
- bs->said.dst = *aftoinfo(subnettypeof(ours))->any;
-
- bs->count = 0;
- bs->last_activity = now();
-
- bs->next = bare_shunts;
- bare_shunts = bs;
- DBG_bare_shunt("add", bs);
- }
-
- /* actually initiate opportunism */
- {
- ip_address src, dst;
-
- networkof(ours, &src);
- networkof(his, &dst);
- initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
- }
-
- /* if present, remove from orphaned_holds list.
- * NOTE: we do this last in case ours or his is a pointer into a member.
- */
- {
- struct eroute_info **pp, *p;
-
- for (pp = &orphaned_holds; (p = *pp) != NULL; pp = &p->next)
- {
- if (samesubnet(ours, &p->ours)
- && samesubnet(his, &p->his)
- && transport_proto == p->transport_proto
- && portof(&ours->addr) == portof(&p->ours.addr)
- && portof(&his->addr) == portof(&p->his.addr))
- {
- *pp = p->next;
- pfree(p);
- break;
- }
- }
- }
-}
-
-#endif /* KLIPS */
-
-static unsigned get_proto_reqid(unsigned base, int proto)
-{
- switch (proto)
- {
- default:
- case IPPROTO_COMP:
- base++;
- /* fall through */
- case IPPROTO_ESP:
- base++;
- /* fall through */
- case IPPROTO_AH:
- break;
- }
-
- return base;
-}
-
-/* Generate Unique SPI numbers.
- *
- * The specs say that the number must not be less than IPSEC_DOI_SPI_MIN.
- * Pluto generates numbers not less than IPSEC_DOI_SPI_OUR_MIN,
- * reserving numbers in between for manual keying (but we cannot so
- * restrict numbers generated by our peer).
- * XXX This should be replaced by a call to the kernel when
- * XXX we get an API.
- * The returned SPI is in network byte order.
- * We use a random number as the initial SPI so that there is
- * a good chance that different Pluto instances will choose
- * different SPIs. This is good for two reasons.
- * - the keying material for the initiator and responder only
- * differs if the SPIs differ.
- * - if Pluto is restarted, it would otherwise recycle the SPI
- * numbers and confuse everything. When the kernel generates
- * SPIs, this will no longer matter.
- * We then allocate numbers sequentially. Thus we don't have to
- * check if the number was previously used (assuming that no
- * SPI lives longer than 4G of its successors).
- */
-ipsec_spi_t
-get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
-{
- static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
- char text_said[SATOT_BUF];
-
- set_text_said(text_said, &sr->this.host_addr, 0, proto);
-
- if (kernel_ops->get_spi)
- return kernel_ops->get_spi(&sr->that.host_addr
- , &sr->this.host_addr, proto, tunnel
- , get_proto_reqid(sr->reqid, proto)
- , IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
- , text_said);
-
- spi++;
- while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
- get_rnd_bytes((u_char *)&spi, sizeof(spi));
-
- DBG(DBG_CONTROL,
- {
- ipsec_spi_t spi_net = htonl(spi);
-
- DBG_dump("generate SPI:", (u_char *)&spi_net, sizeof(spi_net));
- });
-
- return htonl(spi);
-}
-
-/* Generate Unique CPI numbers.
- * The result is returned as an SPI (4 bytes) in network order!
- * The real bits are in the nework-low-order 2 bytes.
- * Modelled on get_ipsec_spi, but range is more limited:
- * 256-61439.
- * If we can't find one easily, return 0 (a bad SPI,
- * no matter what order) indicating failure.
- */
-ipsec_spi_t
-get_my_cpi(struct spd_route *sr, bool tunnel)
-{
- static cpi_t
- first_busy_cpi = 0,
- latest_cpi;
- char text_said[SATOT_BUF];
-
- set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
-
- if (kernel_ops->get_spi)
- return kernel_ops->get_spi(&sr->that.host_addr
- , &sr->this.host_addr, IPPROTO_COMP, tunnel
- , get_proto_reqid(sr->reqid, IPPROTO_COMP)
- , IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
- , text_said);
-
- while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
- {
- get_rnd_bytes((u_char *)&first_busy_cpi, sizeof(first_busy_cpi));
- latest_cpi = first_busy_cpi;
- }
-
- latest_cpi++;
-
- if (latest_cpi == first_busy_cpi)
- find_my_cpi_gap(&latest_cpi, &first_busy_cpi);
-
- if (latest_cpi > IPCOMP_LAST_NEGOTIATED)
- latest_cpi = IPCOMP_FIRST_NEGOTIATED;
-
- return htonl((ipsec_spi_t)latest_cpi);
-}
-
-/* invoke the updown script to do the routing and firewall commands required
- *
- * The user-specified updown script is run. Parameters are fed to it in
- * the form of environment variables. All such environment variables
- * have names starting with "PLUTO_".
- *
- * The operation to be performed is specified by PLUTO_VERB. This
- * verb has a suffix "-host" if the client on this end is just the
- * host; otherwise the suffix is "-client". If the address family
- * of the host is IPv6, an extra suffix of "-v6" is added.
- *
- * "prepare-host" and "prepare-client" are used to delete a route
- * that may exist (due to forces outside of Pluto). It is used to
- * prepare for pluto creating a route.
- *
- * "route-host" and "route-client" are used to install a route.
- * Since routing is based only on destination, the PLUTO_MY_CLIENT_*
- * values are probably of no use (using them may signify a bug).
- *
- * "unroute-host" and "unroute-client" are used to delete a route.
- * Since routing is based only on destination, the PLUTO_MY_CLIENT_*
- * values are probably of no use (using them may signify a bug).
- *
- * "up-host" and "up-client" are run when an eroute is added (not replaced).
- * They are useful for adjusting a firewall: usually for adding a rule
- * to let processed packets flow between clients. Note that only
- * one eroute may exist for a pair of client subnets but inbound
- * IPsec SAs may persist without an eroute.
- *
- * "down-host" and "down-client" are run when an eroute is deleted.
- * They are useful for adjusting a firewall.
- */
-
-#ifndef DEFAULT_UPDOWN
-# define DEFAULT_UPDOWN "ipsec _updown"
-#endif
-
-static bool
-do_command(struct connection *c, struct spd_route *sr, const char *verb)
-{
- char cmd[1536]; /* arbitrary limit on shell command length */
- const char *verb_suffix;
-
- /* figure out which verb suffix applies */
- {
- const char *hs, *cs;
-
- switch (addrtypeof(&sr->this.host_addr))
- {
- case AF_INET:
- hs = "-host";
- cs = "-client";
- break;
- case AF_INET6:
- hs = "-host-v6";
- cs = "-client-v6";
- break;
- default:
- loglog(RC_LOG_SERIOUS, "unknown address family");
- return FALSE;
- }
- verb_suffix = subnetisaddr(&sr->this.client, &sr->this.host_addr)
- ? hs : cs;
- }
-
- /* form the command string */
- {
- char
- nexthop_str[sizeof("PLUTO_NEXT_HOP='' ") +ADDRTOT_BUF] = "",
- srcip_str[sizeof("PLUTO_MY_SOURCEIP='' ")+ADDRTOT_BUF] = "",
- me_str[ADDRTOT_BUF],
- myid_str[BUF_LEN],
- myclient_str[SUBNETTOT_BUF],
- myclientnet_str[ADDRTOT_BUF],
- myclientmask_str[ADDRTOT_BUF],
- peer_str[ADDRTOT_BUF],
- peerid_str[BUF_LEN],
- peerclient_str[SUBNETTOT_BUF],
- peerclientnet_str[ADDRTOT_BUF],
- peerclientmask_str[ADDRTOT_BUF],
- peerca_str[BUF_LEN],
- secure_myid_str[BUF_LEN] = "",
- secure_peerid_str[BUF_LEN] = "",
- secure_peerca_str[BUF_LEN] = "";
- ip_address ta;
- pubkey_list_t *p;
-
- if (addrbytesptr(&sr->this.host_nexthop, NULL)
- && !isanyaddr(&sr->this.host_nexthop))
- {
- char *n;
-
- strcpy(nexthop_str, "PLUTO_NEXT_HOP='");
- n = nexthop_str + strlen(nexthop_str);
-
- addrtot(&sr->this.host_nexthop, 0
- ,n , sizeof(nexthop_str)-strlen(nexthop_str));
- strncat(nexthop_str, "' ", sizeof(nexthop_str));
- }
-
- if (addrbytesptr(&sr->this.host_srcip, NULL)
- && !isanyaddr(&sr->this.host_srcip))
- {
- char *n;
-
- strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
- n = srcip_str + strlen(srcip_str);
-
- addrtot(&sr->this.host_srcip, 0
- ,n , sizeof(srcip_str)-strlen(srcip_str));
- strncat(srcip_str, "' ", sizeof(srcip_str));
- }
-
- addrtot(&sr->this.host_addr, 0, me_str, sizeof(me_str));
- idtoa(&sr->this.id, myid_str, sizeof(myid_str));
- escape_metachar(myid_str, secure_myid_str, sizeof(secure_myid_str));
- subnettot(&sr->this.client, 0, myclient_str, sizeof(myclientnet_str));
- networkof(&sr->this.client, &ta);
- addrtot(&ta, 0, myclientnet_str, sizeof(myclientnet_str));
- maskof(&sr->this.client, &ta);
- addrtot(&ta, 0, myclientmask_str, sizeof(myclientmask_str));
-
- addrtot(&sr->that.host_addr, 0, peer_str, sizeof(peer_str));
- idtoa(&sr->that.id, peerid_str, sizeof(peerid_str));
- escape_metachar(peerid_str, secure_peerid_str, sizeof(secure_peerid_str));
- subnettot(&sr->that.client, 0, peerclient_str, sizeof(peerclientnet_str));
- networkof(&sr->that.client, &ta);
- addrtot(&ta, 0, peerclientnet_str, sizeof(peerclientnet_str));
- maskof(&sr->that.client, &ta);
- addrtot(&ta, 0, peerclientmask_str, sizeof(peerclientmask_str));
-
- for (p = pubkeys; p != NULL; p = p->next)
- {
- pubkey_t *key = p->key;
- int pathlen;
-
- if (key->alg == PUBKEY_ALG_RSA && same_id(&sr->that.id, &key->id)
- && trusted_ca(key->issuer, sr->that.ca, &pathlen))
- {
- dntoa_or_null(peerca_str, BUF_LEN, key->issuer, "");
- escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str));
- break;
- }
- }
-
- if (-1 == snprintf(cmd, sizeof(cmd)
- , "2>&1 " /* capture stderr along with stdout */
- "PLUTO_VERSION='1.1' " /* change VERSION when interface spec changes */
- "PLUTO_VERB='%s%s' "
- "PLUTO_CONNECTION='%s' "
- "%s" /* optional PLUTO_NEXT_HOP */
- "PLUTO_INTERFACE='%s' "
- "%s" /* optional PLUTO_HOST_ACCESS */
- "PLUTO_REQID='%u' "
- "PLUTO_ME='%s' "
- "PLUTO_MY_ID='%s' "
- "PLUTO_MY_CLIENT='%s' "
- "PLUTO_MY_CLIENT_NET='%s' "
- "PLUTO_MY_CLIENT_MASK='%s' "
- "PLUTO_MY_PORT='%u' "
- "PLUTO_MY_PROTOCOL='%u' "
- "PLUTO_PEER='%s' "
- "PLUTO_PEER_ID='%s' "
- "PLUTO_PEER_CLIENT='%s' "
- "PLUTO_PEER_CLIENT_NET='%s' "
- "PLUTO_PEER_CLIENT_MASK='%s' "
- "PLUTO_PEER_PORT='%u' "
- "PLUTO_PEER_PROTOCOL='%u' "
- "PLUTO_PEER_CA='%s' "
- "%s" /* optional PLUTO_MY_SRCIP */
- "%s" /* actual script */
- , verb, verb_suffix
- , c->name
- , nexthop_str
- , c->interface->vname
- , sr->this.hostaccess? "PLUTO_HOST_ACCESS='1' " : ""
- , sr->reqid + 1 /* ESP requid */
- , me_str
- , secure_myid_str
- , myclient_str
- , myclientnet_str
- , myclientmask_str
- , sr->this.port
- , sr->this.protocol
- , peer_str
- , secure_peerid_str
- , peerclient_str
- , peerclientnet_str
- , peerclientmask_str
- , sr->that.port
- , sr->that.protocol
- , secure_peerca_str
- , srcip_str
- , sr->this.updown == NULL? DEFAULT_UPDOWN : sr->this.updown))
- {
- loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb, verb_suffix);
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL, DBG_log("executing %s%s: %s"
- , verb, verb_suffix, cmd));
-
-#ifdef KLIPS
- if (!no_klips)
- {
- /* invoke the script, catching stderr and stdout
- * It may be of concern that some file descriptors will
- * be inherited. For the ones under our control, we
- * have done fcntl(fd, F_SETFD, FD_CLOEXEC) to prevent this.
- * Any used by library routines (perhaps the resolver or syslog)
- * will remain.
- */
- FILE *f = popen(cmd, "r");
-
- if (f == NULL)
- {
- loglog(RC_LOG_SERIOUS, "unable to popen %s%s command", verb, verb_suffix);
- return FALSE;
- }
-
- /* log any output */
- for (;;)
- {
- /* if response doesn't fit in this buffer, it will be folded */
- char resp[256];
-
- if (fgets(resp, sizeof(resp), f) == NULL)
- {
- if (ferror(f))
- {
- log_errno((e, "fgets failed on output of %s%s command"
- , verb, verb_suffix));
- return FALSE;
- }
- else
- {
- passert(feof(f));
- break;
- }
- }
- else
- {
- char *e = resp + strlen(resp);
-
- if (e > resp && e[-1] == '\n')
- e[-1] = '\0'; /* trim trailing '\n' */
- plog("%s%s output: %s", verb, verb_suffix, resp);
- }
- }
-
- /* report on and react to return code */
- {
- int r = pclose(f);
-
- if (r == -1)
- {
- log_errno((e, "pclose failed for %s%s command"
- , verb, verb_suffix));
- return FALSE;
- }
- else if (WIFEXITED(r))
- {
- if (WEXITSTATUS(r) != 0)
- {
- loglog(RC_LOG_SERIOUS, "%s%s command exited with status %d"
- , verb, verb_suffix, WEXITSTATUS(r));
- return FALSE;
- }
- }
- else if (WIFSIGNALED(r))
- {
- loglog(RC_LOG_SERIOUS, "%s%s command exited with signal %d"
- , verb, verb_suffix, WTERMSIG(r));
- return FALSE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "%s%s command exited with unknown status %d"
- , verb, verb_suffix, r);
- return FALSE;
- }
- }
- }
-#endif /* KLIPS */
- return TRUE;
-}
-
-/* Check that we can route (and eroute). Diagnose if we cannot. */
-
-enum routability {
- route_impossible = 0,
- route_easy = 1,
- route_nearconflict = 2,
- route_farconflict = 3
-};
-
-static enum routability
-could_route(struct connection *c)
-{
- struct spd_route *esr, *rosr;
- struct connection *ero /* who, if anyone, owns our eroute? */
- , *ro = route_owner(c, &rosr, &ero, &esr); /* who owns our route? */
-
- /* it makes no sense to route a connection that is ISAKMP-only */
- if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
- {
- loglog(RC_ROUTE, "cannot route an ISAKMP-only connection");
- return route_impossible;
- }
-
- /* if this is a Road Warrior template, we cannot route.
- * Opportunistic template is OK.
- */
- if (c->kind == CK_TEMPLATE && !(c->policy & POLICY_OPPO))
- {
- loglog(RC_ROUTE, "cannot route Road Warrior template");
- return route_impossible;
- }
-
- /* if we don't know nexthop, we cannot route */
- if (isanyaddr(&c->spd.this.host_nexthop))
- {
- loglog(RC_ROUTE, "cannot route connection without knowing our nexthop");
- return route_impossible;
- }
-
- /* if routing would affect IKE messages, reject */
- if (!no_klips
-#ifdef NAT_TRAVERSAL
- && c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT
-#endif
- && c->spd.this.host_port != IKE_UDP_PORT
- && addrinsubnet(&c->spd.that.host_addr, &c->spd.that.client))
- {
- loglog(RC_LOG_SERIOUS, "cannot install route: peer is within its client");
- return route_impossible;
- }
-
- /* If there is already a route for peer's client subnet
- * and it disagrees about interface or nexthop, we cannot steal it.
- * Note: if this connection is already routed (perhaps for another
- * state object), the route will agree.
- * This is as it should be -- it will arise during rekeying.
- */
- if (ro != NULL && !routes_agree(ro, c))
- {
- loglog(RC_LOG_SERIOUS, "cannot route -- route already in use for \"%s\""
- , ro->name);
- return route_impossible; /* another connection already
- using the eroute */
- }
-
-#ifdef KLIPS
- /* if there is an eroute for another connection, there is a problem */
- if (ero != NULL && ero != c)
- {
- struct connection *ero2, *ero_top;
- struct connection *inside, *outside;
-
- /*
- * note, wavesec (PERMANENT) goes *outside* and
- * OE goes *inside* (TEMPLATE)
- */
- inside = NULL;
- outside= NULL;
- if (ero->kind == CK_PERMANENT
- && c->kind == CK_TEMPLATE)
- {
- outside = ero;
- inside = c;
- }
- else if (c->kind == CK_PERMANENT
- && ero->kind == CK_TEMPLATE)
- {
- outside = c;
- inside = ero;
- }
-
- /* okay, check again, with correct order */
- if (outside && outside->kind == CK_PERMANENT
- && inside && inside->kind == CK_TEMPLATE)
- {
- char inst[CONN_INST_BUF];
-
- /* this is a co-terminal attempt of the "near" kind. */
- /* when chaining, we chain from inside to outside */
-
- /* XXX permit multiple deep connections? */
- passert(inside->policy_next == NULL);
-
- inside->policy_next = outside;
-
- /* since we are going to steal the eroute from the secondary
- * policy, we need to make sure that it no longer thinks that
- * it owns the eroute.
- */
- outside->spd.eroute_owner = SOS_NOBODY;
- outside->spd.routing = RT_UNROUTED_KEYED;
-
- /* set the priority of the new eroute owner to be higher
- * than that of the current eroute owner
- */
- inside->prio = outside->prio + 1;
-
- fmt_conn_instance(inside, inst);
-
- loglog(RC_LOG_SERIOUS
- , "conflict on eroute (%s), switching eroute to %s and linking %s"
- , inst, inside->name, outside->name);
-
- return route_nearconflict;
- }
-
- /* look along the chain of policies for one with the same name */
- ero_top = ero;
-
- for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
- {
- if (ero2->kind == CK_TEMPLATE
- && streq(ero2->name, c->name))
- break;
- }
-
- /* If we fell of the end of the list, then we found no TEMPLATE
- * so there must be a conflict that we can't resolve.
- * As the names are not equal, then we aren't replacing/rekeying.
- */
- if (ero2 == NULL)
- {
- char inst[CONN_INST_BUF];
-
- fmt_conn_instance(ero, inst);
-
- loglog(RC_LOG_SERIOUS
- , "cannot install eroute -- it is in use for \"%s\"%s #%lu"
- , ero->name, inst, esr->eroute_owner);
- return FALSE; /* another connection already using the eroute */
- }
- }
-#endif /* KLIPS */
- return route_easy;
-}
-
-bool
-trap_connection(struct connection *c)
-{
- switch (could_route(c))
- {
- case route_impossible:
- return FALSE;
-
- case route_nearconflict:
- case route_easy:
- /* RT_ROUTED_TUNNEL is treated specially: we don't override
- * because we don't want to lose track of the IPSEC_SAs etc.
- */
- if (c->spd.routing < RT_ROUTED_TUNNEL)
- {
- return route_and_eroute(c, &c->spd, NULL);
- }
- return TRUE;
-
- case route_farconflict:
- return FALSE;
- }
-
- return FALSE;
-}
-
-/* delete any eroute for a connection and unroute it if route isn't shared */
-void
-unroute_connection(struct connection *c)
-{
- struct spd_route *sr;
- enum routing_t cr;
-
- for (sr = &c->spd; sr; sr = sr->next)
- {
- cr = sr->routing;
-
- if (erouted(cr))
- {
- /* cannot handle a live one */
- passert(sr->routing != RT_ROUTED_TUNNEL);
-#ifdef KLIPS
- shunt_eroute(c, sr, RT_UNROUTED, ERO_DELETE, "delete");
-#endif
- }
-
- sr->routing = RT_UNROUTED; /* do now so route_owner won't find us */
-
- /* only unroute if no other connection shares it */
- if (routed(cr) && route_owner(c, NULL, NULL, NULL) == NULL)
- (void) do_command(c, sr, "unroute");
- }
-}
-
-
-#ifdef KLIPS
-
-static void
-set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto)
-{
- ip_said said;
-
- initsaid(dst, spi, proto, &said);
- satot(&said, 0, text_said, SATOT_BUF);
-}
-
-/* find an entry in the bare_shunt table.
- * Trick: return a pointer to the pointer to the entry;
- * this allows the entry to be deleted.
- */
-static struct bare_shunt **
-bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
-{
- struct bare_shunt *p, **pp;
-
- for (pp = &bare_shunts; (p = *pp) != NULL; pp = &p->next)
- {
- if (samesubnet(ours, &p->ours)
- && samesubnet(his, &p->his)
- && transport_proto == p->transport_proto
- && portof(&ours->addr) == portof(&p->ours.addr)
- && portof(&his->addr) == portof(&p->his.addr))
- return pp;
- }
- return NULL;
-}
-
-/* free a bare_shunt entry, given a pointer to the pointer */
-static void
-free_bare_shunt(struct bare_shunt **pp)
-{
- if (pp == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("delete bare shunt: null pointer")
- )
- }
- else
- {
- struct bare_shunt *p = *pp;
-
- *pp = p->next;
- DBG_bare_shunt("delete", p);
- pfree(p->why);
- pfree(p);
- }
-}
-
-void
-show_shunt_status(void)
-{
- struct bare_shunt *bs;
-
- for (bs = bare_shunts; bs != NULL; bs = bs->next)
- {
- /* Print interesting fields. Ignore count and last_active. */
-
- int ourport = ntohs(portof(&bs->ours.addr));
- int hisport = ntohs(portof(&bs->his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
- char prio[POLICY_PRIO_BUF];
-
- subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
- subnettot(&(bs)->his, 0, hist, sizeof(hist));
- satot(&(bs)->said, 0, sat, sizeof(sat));
- fmt_policy_prio(bs->policy_prio, prio);
-
- whack_log(RC_COMMENT, "%s:%d -> %s:%d => %s:%d %s %s"
- , ourst, ourport, hist, hisport, sat, bs->transport_proto
- , prio, bs->why);
- }
- if (bare_shunts != NULL)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
-}
-
-/* Setup an IPsec route entry.
- * op is one of the ERO_* operators.
- */
-
-static bool
-raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int proto
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info
- , time_t use_lifetime
- , unsigned int op
- , const char *opname USED_BY_DEBUG)
-{
- char text_said[SATOT_BUF];
-
- set_text_said(text_said, that_host, spi, proto);
-
- DBG(DBG_CONTROL | DBG_KLIPS,
- {
- int sport = ntohs(portof(&this_client->addr));
- int dport = ntohs(portof(&that_client->addr));
- char mybuf[SUBNETTOT_BUF];
- char peerbuf[SUBNETTOT_BUF];
-
- subnettot(this_client, 0, mybuf, sizeof(mybuf));
- subnettot(that_client, 0, peerbuf, sizeof(peerbuf));
- DBG_log("%s eroute %s:%d -> %s:%d => %s:%d"
- , opname, mybuf, sport, peerbuf, dport
- , text_said, transport_proto);
- });
-
- return kernel_ops->raw_eroute(this_host, this_client
- , that_host, that_client, spi, satype, transport_proto, proto_info
- , use_lifetime, op, text_said);
-}
-
-/* test to see if %hold remains */
-bool
-has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
-{
- ip_subnet this_client, that_client;
- struct bare_shunt **bspp;
-
- passert(addrtypeof(src) == addrtypeof(dst));
- happy(addrtosubnet(src, &this_client));
- happy(addrtosubnet(dst, &that_client));
- bspp = bare_shunt_ptr(&this_client, &that_client, transport_proto);
- return bspp != NULL
- && (*bspp)->said.proto == SA_INT && (*bspp)->said.spi == htonl(SPI_HOLD);
-}
-
-
-/* Replace (or delete) a shunt that is in the bare_shunts table.
- * Issues the PF_KEY commands and updates the bare_shunts table.
- */
-bool
-replace_bare_shunt(const ip_address *src, const ip_address *dst
- , policy_prio_t policy_prio
- , ipsec_spi_t shunt_spi /* in host order! */
- , bool repl /* if TRUE, replace; if FALSE, delete */
- , unsigned int transport_proto
- , const char *why)
-{
- ip_subnet this_client, that_client;
- ip_subnet this_broad_client, that_broad_client;
- const ip_address *null_host = aftoinfo(addrtypeof(src))->any;
-
- passert(addrtypeof(src) == addrtypeof(dst));
- happy(addrtosubnet(src, &this_client));
- happy(addrtosubnet(dst, &that_client));
- this_broad_client = this_client;
- that_broad_client = that_client;
- setportof(0, &this_broad_client.addr);
- setportof(0, &that_broad_client.addr);
-
- if (repl)
- {
- struct bare_shunt **bs_pp = bare_shunt_ptr(&this_broad_client
- , &that_broad_client, 0);
-
- /* is there already a broad host-to-host bare shunt? */
- if (bs_pp == NULL)
- {
- if (raw_eroute(null_host, &this_broad_client, null_host, &that_broad_client
- , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
- , 0, null_proto_info
- , SHUNT_PATIENCE, ERO_ADD, why))
- {
- struct bare_shunt *bs = alloc_thing(struct bare_shunt, "bare shunt");
-
- bs->ours = this_broad_client;
- bs->his = that_broad_client;
- bs->transport_proto = 0;
- bs->said.proto = SA_INT;
- bs->why = clone_str(why, "bare shunt story");
- bs->policy_prio = policy_prio;
- bs->said.spi = htonl(shunt_spi);
- bs->said.dst = *null_host;
- bs->count = 0;
- bs->last_activity = now();
- bs->next = bare_shunts;
- bare_shunts = bs;
- DBG_bare_shunt("add", bs);
- }
- }
- shunt_spi = SPI_HOLD;
- }
-
- if (raw_eroute(null_host, &this_client, null_host, &that_client
- , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
- , transport_proto, null_proto_info
- , SHUNT_PATIENCE, ERO_DELETE, why))
- {
- struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
- , transport_proto);
-
- /* delete bare eroute */
- free_bare_shunt(bs_pp);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-static bool
-eroute_connection(struct spd_route *sr
-, ipsec_spi_t spi, unsigned int proto, unsigned int satype
-, const struct pfkey_proto_info *proto_info
-, unsigned int op, const char *opname)
-{
- const ip_address *peer = &sr->that.host_addr;
- char buf2[256];
-
- snprintf(buf2, sizeof(buf2)
- , "eroute_connection %s", opname);
-
- if (proto == SA_INT)
- peer = aftoinfo(addrtypeof(peer))->any;
-
- return raw_eroute(&sr->this.host_addr, &sr->this.client
- , peer
- , &sr->that.client
- , spi, proto, satype
- , sr->this.protocol, proto_info, 0, op, buf2);
-}
-
-/* assign a bare hold to a connection */
-
-bool
-assign_hold(struct connection *c USED_BY_DEBUG
- , struct spd_route *sr
- , int transport_proto
- , const ip_address *src, const ip_address *dst)
-{
- /* either the automatically installed %hold eroute is broad enough
- * or we try to add a broader one and delete the automatic one.
- * Beware: this %hold might be already handled, but still squeak
- * through because of a race.
- */
- enum routing_t ro = sr->routing /* routing, old */
- , rn = ro; /* routing, new */
-
- passert(LHAS(LELEM(CK_PERMANENT) | LELEM(CK_INSTANCE), c->kind));
- /* figure out what routing should become */
- switch (ro)
- {
- case RT_UNROUTED:
- rn = RT_UNROUTED_HOLD;
- break;
- case RT_ROUTED_PROSPECTIVE:
- rn = RT_ROUTED_HOLD;
- break;
- default:
- /* no change: this %hold is old news and should just be deleted */
- break;
- }
-
- /* we need a broad %hold, not the narrow one.
- * First we ensure that there is a broad %hold.
- * There may already be one (race condition): no need to create one.
- * There may already be a %trap: replace it.
- * There may not be any broad eroute: add %hold.
- * Once the broad %hold is in place, delete the narrow one.
- */
- if (rn != ro)
- {
- if (erouted(ro)
- ? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info
- , ERO_REPLACE, "replace %trap with broad %hold")
- : !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info
- , ERO_ADD, "add broad %hold"))
- {
- return FALSE;
- }
- }
- if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE
- , transport_proto, "delete narrow %hold"))
- {
- return FALSE;
- }
- sr->routing = rn;
- return TRUE;
-}
-
-/* install or remove eroute for SA Group */
-static bool
-sag_eroute(struct state *st, struct spd_route *sr
- , unsigned op, const char *opname)
-{
- u_int inner_proto = 0;
- u_int inner_satype = 0;
- ipsec_spi_t inner_spi = 0;
- struct pfkey_proto_info proto_info[4];
- int i;
- bool tunnel;
-
- /* figure out the SPI and protocol (in two forms)
- * for the innermost transformation.
- */
-
- i = sizeof(proto_info) / sizeof(proto_info[0]) - 1;
- proto_info[i].proto = 0;
- tunnel = FALSE;
-
- if (st->st_ah.present)
- {
- inner_spi = st->st_ah.attrs.spi;
- inner_proto = SA_AH;
- inner_satype = SADB_SATYPE_AH;
-
- i--;
- proto_info[i].proto = IPPROTO_AH;
- proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid;
- }
-
- if (st->st_esp.present)
- {
- inner_spi = st->st_esp.attrs.spi;
- inner_proto = SA_ESP;
- inner_satype = SADB_SATYPE_ESP;
-
- i--;
- proto_info[i].proto = IPPROTO_ESP;
- proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid + 1;
- }
-
- if (st->st_ipcomp.present)
- {
- inner_spi = st->st_ipcomp.attrs.spi;
- inner_proto = SA_COMP;
- inner_satype = SADB_X_SATYPE_COMP;
-
- i--;
- proto_info[i].proto = IPPROTO_COMP;
- proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid + 2;
- }
-
- if (i == sizeof(proto_info) / sizeof(proto_info[0]) - 1)
- {
- impossible(); /* no transform at all! */
- }
-
- if (tunnel)
- {
- int j;
-
- inner_spi = st->st_tunnel_out_spi;
- inner_proto = SA_IPIP;
- inner_satype = SADB_X_SATYPE_IPIP;
-
- proto_info[i].encapsulation = ENCAPSULATION_MODE_TUNNEL;
- for (j = i + 1; proto_info[j].proto; j++)
- {
- proto_info[j].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
- }
-
- return eroute_connection(sr
- , inner_spi, inner_proto, inner_satype, proto_info + i
- , op, opname);
-}
-
-/* compute a (host-order!) SPI to implement the policy in connection c */
-ipsec_spi_t
-shunt_policy_spi(struct connection *c, bool prospective)
-{
- /* note: these are in host order :-( */
- static const ipsec_spi_t shunt_spi[] =
- {
- SPI_TRAP, /* --initiateontraffic */
- SPI_PASS, /* --pass */
- SPI_DROP, /* --drop */
- SPI_REJECT, /* --reject */
- };
-
- static const ipsec_spi_t fail_spi[] =
- {
- 0, /* --none*/
- SPI_PASS, /* --failpass */
- SPI_DROP, /* --faildrop */
- SPI_REJECT, /* --failreject */
- };
-
- return prospective
- ? shunt_spi[(c->policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT]
- : fail_spi[(c->policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT];
-}
-
-/* Add/replace/delete a shunt eroute.
- * Such an eroute determines the fate of packets without the use
- * of any SAs. These are defaults, in effect.
- * If a negotiation has not been attempted, use %trap.
- * If negotiation has failed, the choice between %trap/%pass/%drop/%reject
- * is specified in the policy of connection c.
- */
-static bool
-shunt_eroute(struct connection *c
-, struct spd_route *sr
-, enum routing_t rt_kind
-, unsigned int op, const char *opname)
-{
- /* We are constructing a special SAID for the eroute.
- * The destination doesn't seem to matter, but the family does.
- * The protocol is SA_INT -- mark this as shunt.
- * The satype has no meaning, but is required for PF_KEY header!
- * The SPI signifies the kind of shunt.
- */
- ipsec_spi_t spi = shunt_policy_spi(c, rt_kind == RT_ROUTED_PROSPECTIVE);
- bool ok;
-
- if (spi == 0)
- {
- /* we're supposed to end up with no eroute: rejig op and opname */
- switch (op)
- {
- case ERO_REPLACE:
- /* replace with nothing == delete */
- op = ERO_DELETE;
- opname = "delete";
- break;
- case ERO_ADD:
- /* add nothing == do nothing */
- return TRUE;
- case ERO_DELETE:
- /* delete remains delete */
- break;
- default:
- bad_case(op);
- }
- }
- if (sr->routing == RT_ROUTED_ECLIPSED && c->kind == CK_TEMPLATE)
- {
- /* We think that we have an eroute, but we don't.
- * Adjust the request and account for eclipses.
- */
- passert(eclipsable(sr));
- switch (op)
- {
- case ERO_REPLACE:
- /* really an add */
- op = ERO_ADD;
- opname = "replace eclipsed";
- eclipse_count--;
- break;
- case ERO_DELETE:
- /* delete unnecessary: we don't actually have an eroute */
- eclipse_count--;
- return TRUE;
- case ERO_ADD:
- default:
- bad_case(op);
- }
- }
- else if (eclipse_count > 0 && op == ERO_DELETE && eclipsable(sr))
- {
- /* maybe we are uneclipsing something */
- struct spd_route *esr;
- struct connection *ue = eclipsed(c, &esr);
-
- if (ue != NULL)
- {
- esr->routing = RT_ROUTED_PROSPECTIVE;
- return shunt_eroute(ue, esr
- , RT_ROUTED_PROSPECTIVE, ERO_REPLACE, "restoring eclipsed");
- }
- }
-
- ok = TRUE;
- if (kernel_ops->inbound_eroute)
- {
- ok = raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , htonl(spi), SA_INT, SADB_X_SATYPE_INT
- , 0, null_proto_info, 0
- , op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), opname);
- }
- return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info, op, opname) && ok;
-}
-
-
-/*
- * This is only called when s is a likely SAID with trailing protocol i.e.
- * it has the form :-
- *
- * %<keyword>:p
- * <ip-proto><spi>@a.b.c.d:p
- *
- * The task here is to remove the ":p" part so that the rest can be read
- * by another routine.
- */
-static const char *
-read_proto(const char * s, size_t * len, int * transport_proto)
-{
- const char * p;
- const char * ugh;
- unsigned long proto;
- size_t l;
-
- l = *len;
- p = memchr(s, ':', l);
- if (p == 0) {
- *transport_proto = 0;
- return 0;
- }
- ugh = ttoul(p+1, l-((p-s)+1), 10, &proto);
- if (ugh != 0)
- return ugh;
- if (proto > 65535)
- return "protocol number is too large, legal range is 0-65535";
- *len = p-s;
- *transport_proto = proto;
- return 0;
-}
-
-
-/* scan /proc/net/ipsec_eroute every once in a while, looking for:
- *
- * - %hold shunts of which Pluto isn't aware. This situation could
- * be caused by lost ACQUIRE messages. When found, they will
- * added to orphan_holds. This in turn will lead to Opportunistic
- * initiation.
- *
- * - other kinds of shunts that haven't been used recently. These will be
- * deleted. They represent OE failures.
- *
- * - recording recent uses of tunnel eroutes so that rekeying decisions
- * can be made for OE connections.
- *
- * Here are some sample lines:
- * 10 10.3.2.1.0/24 -> 0.0.0.0/0 => %trap
- * 259 10.3.2.1.115/32 -> 10.19.75.161/32 => tun0x1002@10.19.75.145
- * 71 10.44.73.97/32 -> 0.0.0.0/0 => %trap
- * 4119 10.44.73.97/32 -> 10.114.121.41/32 => %pass
- * Newer versions of KLIPS start each line with a 32-bit packet count.
- * If available, the count is used to detect whether a %pass shunt is in use.
- *
- * NOTE: execution time is quadratic in the number of eroutes since the
- * searching for each is sequential. If this becomes a problem, faster
- * searches could be implemented (hash or radix tree, for example).
- */
-void
-scan_proc_shunts(void)
-{
- static const char procname[] = "/proc/net/ipsec_eroute";
- FILE *f;
- time_t nw = now();
- int lino;
- struct eroute_info *expired = NULL;
-
- event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
-
- DBG(DBG_CONTROL,
- DBG_log("scanning for shunt eroutes")
- )
-
- /* free any leftover entries: they will be refreshed if still current */
- while (orphaned_holds != NULL)
- {
- struct eroute_info *p = orphaned_holds;
-
- orphaned_holds = p->next;
- pfree(orphaned_holds);
- }
-
- /* decode the /proc file. Don't do anything strenuous to it
- * (certainly no PF_KEY stuff) to minimize the chance that it
- * might change underfoot.
- */
-
- f = fopen(procname, "r");
- if (f == NULL)
- return;
-
- /* for each line... */
- for (lino = 1; ; lino++)
- {
- unsigned char buf[1024]; /* should be big enough */
- chunk_t field[10]; /* 10 is loose upper bound */
- chunk_t *ff = NULL; /* fixed fields (excluding optional count) */
- int fi;
- struct eroute_info eri;
- char *cp;
- err_t context = ""
- , ugh = NULL;
-
- cp = fgets(buf, sizeof(buf), f);
- if (cp == NULL)
- break;
-
- /* break out each field
- * Note: if there are too many fields, just stop;
- * it will be diagnosed a little later.
- */
- for (fi = 0; fi < (int)elemsof(field); fi++)
- {
- static const char sep[] = " \t\n"; /* field-separating whitespace */
- size_t w;
-
- cp += strspn(cp, sep); /* find start of field */
- w = strcspn(cp, sep); /* find width of field */
- setchunk(field[fi], cp, w);
- cp += w;
- if (w == 0)
- break;
- }
-
- /* This odd do-hickey is to share error reporting code.
- * A break will get to that common code. The setting
- * of "ugh" and "context" parameterize it.
- */
- do {
- /* Old entries have no packet count; new ones do.
- * check if things are as they should be.
- */
- if (fi == 5)
- ff = &field[0]; /* old form, with no count */
- else if (fi == 6)
- ff = &field[1]; /* new form, with count */
- else
- {
- ugh = "has wrong number of fields";
- break;
- }
-
- if (ff[1].len != 2
- || strncmp(ff[1].ptr, "->", 2) != 0
- || ff[3].len != 2
- || strncmp(ff[3].ptr, "=>", 2) != 0)
- {
- ugh = "is missing -> or =>";
- break;
- }
-
- /* actually digest fields of interest */
-
- /* packet count */
-
- eri.count = 0;
- if (ff != field)
- {
- context = "count field is malformed: ";
- ugh = ttoul(field[0].ptr, field[0].len, 10, &eri.count);
- if (ugh != NULL)
- break;
- }
-
- /* our client */
-
- context = "source subnet field malformed: ";
- ugh = ttosubnet(ff[0].ptr, ff[0].len, AF_INET, &eri.ours);
- if (ugh != NULL)
- break;
-
- /* his client */
-
- context = "destination subnet field malformed: ";
- ugh = ttosubnet(ff[2].ptr, ff[2].len, AF_INET, &eri.his);
- if (ugh != NULL)
- break;
-
- /* SAID */
-
- context = "SA ID field malformed: ";
- ugh = read_proto(ff[4].ptr, &ff[4].len, &eri.transport_proto);
- if (ugh != NULL)
- break;
- ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said);
- } while (FALSE);
-
- if (ugh != NULL)
- {
- plog("INTERNAL ERROR: %s line %d %s%s"
- , procname, lino, context, ugh);
- continue; /* ignore rest of line */
- }
-
- /* Now we have decoded eroute, let's consider it.
- * For shunt eroutes:
- *
- * %hold: if not known, add to orphaned_holds list for initiation
- * because ACQUIRE might have been lost.
- *
- * %pass, %drop, %reject: determine if idle; if so, blast it away.
- * Can occur bare (if DNS provided insufficient information)
- * or with a connection (failure context).
- * Could even be installed by ipsec manual.
- *
- * %trap: always welcome.
- *
- * For other eroutes: find state and record count change
- */
- if (eri.said.proto == SA_INT)
- {
- /* shunt eroute */
- switch (ntohl(eri.said.spi))
- {
- case SPI_HOLD:
- if (bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto) == NULL
- && shunt_owner(&eri.ours, &eri.his) == NULL)
- {
- int ourport = ntohs(portof(&eri.ours.addr));
- int hisport = ntohs(portof(&eri.his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
-
- subnettot(&eri.ours, 0, ourst, sizeof(ourst));
- subnettot(&eri.his, 0, hist, sizeof(hist));
- satot(&eri.said, 0, sat, sizeof(sat));
-
- DBG(DBG_CONTROL,
- DBG_log("add orphaned shunt %s:%d -> %s:%d => %s:%d"
- , ourst, ourport, hist, hisport, sat, eri.transport_proto)
- )
- eri.next = orphaned_holds;
- orphaned_holds = clone_thing(eri, "orphaned %hold");
- }
- break;
-
- case SPI_PASS:
- case SPI_DROP:
- case SPI_REJECT:
- /* nothing sensible to do if we don't have counts */
- if (ff != field)
- {
- struct bare_shunt **bs_pp
- = bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto);
-
- if (bs_pp != NULL)
- {
- struct bare_shunt *bs = *bs_pp;
-
- if (eri.count != bs->count)
- {
- bs->count = eri.count;
- bs->last_activity = nw;
- }
- else if (nw - bs->last_activity > SHUNT_PATIENCE)
- {
- eri.next = expired;
- expired = clone_thing(eri, "expired %pass");
- }
- }
- }
- break;
-
- case SPI_TRAP:
- break;
-
- default:
- bad_case(ntohl(eri.said.spi));
- }
- }
- else
- {
- /* regular (non-shunt) eroute */
- state_eroute_usage(&eri.ours, &eri.his, eri.count, nw);
- }
- } /* for each line */
- fclose(f);
-
- /* Now that we've finished processing the /proc file,
- * it is safe to delete the expired %pass shunts.
- */
- while (expired != NULL)
- {
- struct eroute_info *p = expired;
- ip_address src, dst;
-
- networkof(&p->ours, &src);
- networkof(&p->his, &dst);
- (void) replace_bare_shunt(&src, &dst
- , BOTTOM_PRIO /* not used because we are deleting. This value is a filler */
- , SPI_PASS /* not used because we are deleting. This value is a filler */
- , FALSE, p->transport_proto, "delete expired bare shunts");
- expired = p->next;
- pfree(p);
- }
-}
-
-static bool
-del_spi(ipsec_spi_t spi, int proto
-, const ip_address *src, const ip_address *dest)
-{
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
-
- set_text_said(text_said, dest, spi, proto);
-
- DBG(DBG_KLIPS, DBG_log("delete %s", text_said));
-
- memset(&sa, 0, sizeof(sa));
- sa.spi = spi;
- sa.proto = proto;
- sa.src = src;
- sa.dst = dest;
- sa.text_said = text_said;
-
- return kernel_ops->del_sa(&sa);
-}
-
-/* Setup a pair of SAs. Code taken from setsa.c and spigrp.c, in
- * ipsec-0.5.
- */
-
-static bool
-setup_half_ipsec_sa(struct state *st, bool inbound)
-{
- /* Build an inbound or outbound SA */
-
- struct connection *c = st->st_connection;
- ip_subnet src, dst;
- ip_subnet src_client, dst_client;
- ipsec_spi_t inner_spi = 0;
- u_int proto = 0;
- u_int satype = SADB_SATYPE_UNSPEC;
- bool replace;
-
- /* SPIs, saved for spigrouping or undoing, if necessary */
- struct kernel_sa
- said[EM_MAXRELSPIS],
- *said_next = said;
-
- char text_said[SATOT_BUF];
- int encapsulation;
-
- replace = inbound && (kernel_ops->get_spi != NULL);
-
- src.maskbits = 0;
- dst.maskbits = 0;
-
- if (inbound)
- {
- src.addr = c->spd.that.host_addr;
- dst.addr = c->spd.this.host_addr;
- src_client = c->spd.that.client;
- dst_client = c->spd.this.client;
- }
- else
- {
- src.addr = c->spd.this.host_addr,
- dst.addr = c->spd.that.host_addr;
- src_client = c->spd.this.client;
- dst_client = c->spd.that.client;
- }
-
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- encapsulation = ENCAPSULATION_MODE_TUNNEL;
- }
-
- memset(said, 0, sizeof(said));
-
- /* If we are tunnelling, set up IP in IP pseudo SA */
-
- if (kernel_ops->inbound_eroute)
- {
- inner_spi = 256;
- proto = SA_IPIP;
- satype = SADB_SATYPE_UNSPEC;
- }
- else if (encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- /* XXX hack alert -- we SHOULD NOT HAVE TO HAVE A DIFFERENT SPI
- * XXX FOR IP-in-IP ENCAPSULATION!
- */
-
- ipsec_spi_t ipip_spi;
-
- /* Allocate an SPI for the tunnel.
- * Since our peer will never see this,
- * and it comes from its own number space,
- * it is purely a local implementation wart.
- */
- {
- static ipsec_spi_t last_tunnel_spi = IPSEC_DOI_SPI_OUR_MIN;
-
- ipip_spi = htonl(++last_tunnel_spi);
- if (inbound)
- st->st_tunnel_in_spi = ipip_spi;
- else
- st->st_tunnel_out_spi = ipip_spi;
- }
-
- set_text_said(text_said
- , &c->spd.that.host_addr, ipip_spi, SA_IPIP);
-
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ipip_spi;
- said_next->satype = SADB_X_SATYPE_IPIP;
- said_next->text_said = text_said;
-
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
-
- said_next++;
-
- inner_spi = ipip_spi;
- proto = SA_IPIP;
- satype = SADB_X_SATYPE_IPIP;
- }
-
- /* set up IPCOMP SA, if any */
-
- if (st->st_ipcomp.present)
- {
- ipsec_spi_t ipcomp_spi = inbound? st->st_ipcomp.our_spi : st->st_ipcomp.attrs.spi;
- unsigned compalg;
-
- switch (st->st_ipcomp.attrs.transid)
- {
- case IPCOMP_DEFLATE:
- compalg = SADB_X_CALG_DEFLATE;
- break;
-
- default:
- loglog(RC_LOG_SERIOUS, "IPCOMP transform %s not implemented"
- , enum_name(&ipcomp_transformid_names, st->st_ipcomp.attrs.transid));
- goto fail;
- }
-
- set_text_said(text_said, &dst.addr, ipcomp_spi, SA_COMP);
-
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ipcomp_spi;
- said_next->satype = SADB_X_SATYPE_COMP;
- said_next->compalg = compalg;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid + 2;
- said_next->text_said = text_said;
-
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
-
- said_next++;
-
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
-
- /* set up ESP SA, if any */
-
- if (st->st_esp.present)
- {
- ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
- u_char *esp_dst_keymat = inbound? st->st_esp.our_keymat : st->st_esp.peer_keymat;
- const struct esp_info *ei;
- u_int16_t key_len;
-
- static const struct esp_info esp_info[] = {
- { ESP_NULL, AUTH_ALGORITHM_HMAC_MD5,
- 0, HMAC_MD5_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_MD5_HMAC },
- { ESP_NULL, AUTH_ALGORITHM_HMAC_SHA1,
- 0, HMAC_SHA1_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_SHA1_HMAC },
-
- { ESP_DES, AUTH_ALGORITHM_NONE,
- DES_CBC_BLOCK_SIZE, 0,
- SADB_EALG_DES_CBC, SADB_AALG_NONE },
- { ESP_DES, AUTH_ALGORITHM_HMAC_MD5,
- DES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,
- SADB_EALG_DES_CBC, SADB_AALG_MD5_HMAC },
- { ESP_DES, AUTH_ALGORITHM_HMAC_SHA1,
- DES_CBC_BLOCK_SIZE,
- HMAC_SHA1_KEY_LEN, SADB_EALG_DES_CBC, SADB_AALG_SHA1_HMAC },
-
- { ESP_3DES, AUTH_ALGORITHM_NONE,
- DES_CBC_BLOCK_SIZE * 3, 0,
- SADB_EALG_3DES_CBC, SADB_AALG_NONE },
- { ESP_3DES, AUTH_ALGORITHM_HMAC_MD5,
- DES_CBC_BLOCK_SIZE * 3, HMAC_MD5_KEY_LEN,
- SADB_EALG_3DES_CBC, SADB_AALG_MD5_HMAC },
- { ESP_3DES, AUTH_ALGORITHM_HMAC_SHA1,
- DES_CBC_BLOCK_SIZE * 3, HMAC_SHA1_KEY_LEN,
- SADB_EALG_3DES_CBC, SADB_AALG_SHA1_HMAC },
- };
-
-#ifdef NAT_TRAVERSAL
- u_int8_t natt_type = 0;
- u_int16_t natt_sport = 0, natt_dport = 0;
- ip_address natt_oa;
-
- if (st->nat_traversal & NAT_T_DETECTED) {
- natt_type = (st->nat_traversal & NAT_T_WITH_PORT_FLOATING) ?
- ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;
- natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port;
- natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
- natt_oa = st->nat_oa;
- }
-#endif
-
- for (ei = esp_info; ; ei++)
- {
- if (ei == &esp_info[elemsof(esp_info)])
- {
- /* Check for additional kernel alg */
-#ifndef NO_KERNEL_ALG
- if ((ei=kernel_alg_esp_info(st->st_esp.attrs.transid,
- st->st_esp.attrs.auth))!=NULL) {
- break;
- }
-#endif
-
- /* note: enum_show may use a static buffer, so two
- * calls in one printf would be a mistake.
- * enum_name does the same job, without a static buffer,
- * assuming the name will be found.
- */
- loglog(RC_LOG_SERIOUS, "ESP transform %s / auth %s not implemented yet"
- , enum_name(&esp_transformid_names, st->st_esp.attrs.transid)
- , enum_name(&auth_alg_names, st->st_esp.attrs.auth));
- goto fail;
- }
-
- if (st->st_esp.attrs.transid == ei->transid
- && st->st_esp.attrs.auth == ei->auth)
- break;
- }
-
- key_len = st->st_esp.attrs.key_len/8;
- if (key_len) {
- /* XXX: must change to check valid _range_ key_len */
- if (key_len > ei->enckeylen) {
- loglog(RC_LOG_SERIOUS, "ESP transform %s passed key_len=%d > %d",
- enum_name(&esp_transformid_names, st->st_esp.attrs.transid),
- (int)key_len, (int)ei->enckeylen);
- goto fail;
- }
- } else {
- key_len = ei->enckeylen;
- }
- /* Grrrrr.... f*cking 7 bits jurassic algos */
-
- /* 168 bits in kernel, need 192 bits for keymat_len */
- if (ei->transid == ESP_3DES && key_len == 21)
- key_len = 24;
-
- /* 56 bits in kernel, need 64 bits for keymat_len */
- if (ei->transid == ESP_DES && key_len == 7)
- key_len = 8;
-
- /* divide up keying material */
- /* passert(st->st_esp.keymat_len == ei->enckeylen + ei->authkeylen); */
- DBG(DBG_KLIPS|DBG_CONTROL|DBG_PARSING,
- if(st->st_esp.keymat_len != key_len + ei->authkeylen)
- DBG_log("keymat_len=%d key_len=%d authkeylen=%d",
- st->st_esp.keymat_len, (int)key_len, (int)ei->authkeylen);
- );
- passert(st->st_esp.keymat_len == key_len + ei->authkeylen);
-
- set_text_said(text_said, &dst.addr, esp_spi, SA_ESP);
-
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = esp_spi;
- said_next->satype = SADB_SATYPE_ESP;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
- said_next->authalg = ei->authalg;
- said_next->authkeylen = ei->authkeylen;
- /* said_next->authkey = esp_dst_keymat + ei->enckeylen; */
- said_next->authkey = esp_dst_keymat + key_len;
- said_next->encalg = ei->encryptalg;
- /* said_next->enckeylen = ei->enckeylen; */
- said_next->enckeylen = key_len;
- said_next->enckey = esp_dst_keymat;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid + 1;
-#ifdef NAT_TRAVERSAL
- said_next->natt_sport = natt_sport;
- said_next->natt_dport = natt_dport;
- said_next->transid = st->st_esp.attrs.transid;
- said_next->natt_type = natt_type;
- said_next->natt_oa = &natt_oa;
-#endif
- said_next->text_said = text_said;
-
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
-
- said_next++;
-
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
-
- /* set up AH SA, if any */
-
- if (st->st_ah.present)
- {
- ipsec_spi_t ah_spi = inbound? st->st_ah.our_spi : st->st_ah.attrs.spi;
- u_char *ah_dst_keymat = inbound? st->st_ah.our_keymat : st->st_ah.peer_keymat;
-
- unsigned char authalg;
-
- switch (st->st_ah.attrs.auth)
- {
- case AUTH_ALGORITHM_HMAC_MD5:
- authalg = SADB_AALG_MD5_HMAC;
- break;
-
- case AUTH_ALGORITHM_HMAC_SHA1:
- authalg = SADB_AALG_SHA1_HMAC;
- break;
-
- default:
- loglog(RC_LOG_SERIOUS, "%s not implemented yet"
- , enum_show(&auth_alg_names, st->st_ah.attrs.auth));
- goto fail;
- }
-
- set_text_said(text_said, &dst.addr, ah_spi, SA_AH);
-
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ah_spi;
- said_next->satype = SADB_SATYPE_AH;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
- said_next->authalg = authalg;
- said_next->authkeylen = st->st_ah.keymat_len;
- said_next->authkey = ah_dst_keymat;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid;
- said_next->text_said = text_said;
-
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
-
- said_next++;
-
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
-
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- encapsulation = ENCAPSULATION_MODE_TUNNEL;
- }
-
- if (kernel_ops->inbound_eroute ? c->spd.eroute_owner == SOS_NOBODY
- : encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- /* If inbound, and policy does not specifie DISABLEARRIVALCHECK,
- * tell KLIPS to enforce the IP addresses appropriate for this tunnel.
- * Note reversed ends.
- * Not much to be done on failure.
- */
- if (inbound && (c->policy & POLICY_DISABLEARRIVALCHECK) == 0)
- {
- struct pfkey_proto_info proto_info[4];
- int i = 0;
-
- if (st->st_ipcomp.present)
- {
- proto_info[i].proto = IPPROTO_COMP;
- proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid + 2;
- i++;
- }
-
- if (st->st_esp.present)
- {
- proto_info[i].proto = IPPROTO_ESP;
- proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid + 1;
- i++;
- }
-
- if (st->st_ah.present)
- {
- proto_info[i].proto = IPPROTO_AH;
- proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid;
- i++;
- }
-
- proto_info[i].proto = 0;
-
- if (kernel_ops->inbound_eroute
- && encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- proto_info[0].encapsulation = ENCAPSULATION_MODE_TUNNEL;
- for (i = 1; proto_info[i].proto; i++)
- {
- proto_info[i].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
- }
-
- /* MCR - should be passed a spd_eroute structure here */
- (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , inner_spi, proto, satype, c->spd.this.protocol
- , proto_info, 0
- , ERO_ADD_INBOUND, "add inbound");
- }
- }
-
- /* If there are multiple SPIs, group them. */
-
- if (kernel_ops->grp_sa && said_next > &said[1])
- {
- struct kernel_sa *s;
-
- /* group SAs, two at a time, inner to outer (backwards in said[])
- * The grouping is by pairs. So if said[] contains ah esp ipip,
- * the grouping would be ipip:esp, esp:ah.
- */
- for (s = said; s < said_next-1; s++)
- {
- char
- text_said0[SATOT_BUF],
- text_said1[SATOT_BUF];
-
- /* group s[1] and s[0], in that order */
-
- set_text_said(text_said0, s[0].dst, s[0].spi, s[0].proto);
- set_text_said(text_said1, s[1].dst, s[1].spi, s[1].proto);
-
- DBG(DBG_KLIPS, DBG_log("grouping %s and %s", text_said1, text_said0));
-
- s[0].text_said = text_said0;
- s[1].text_said = text_said1;
-
- if (!kernel_ops->grp_sa(s + 1, s))
- goto fail;
- }
- /* could update said, but it will not be used */
- }
-
- return TRUE;
-
-fail:
- {
- /* undo the done SPIs */
- while (said_next-- != said)
- (void) del_spi(said_next->spi, said_next->proto
- , &src.addr, said_next->dst);
- return FALSE;
- }
-}
-
-/* teardown_ipsec_sa is a canibalized version of setup_ipsec_sa */
-
-static bool
-teardown_half_ipsec_sa(struct state *st, bool inbound)
-{
- /* We need to delete AH, ESP, and IP in IP SPIs.
- * But if there is more than one, they have been grouped
- * so deleting any one will do. So we just delete the
- * first one found. It may or may not be the only one.
- */
- struct connection *c = st->st_connection;
- struct {
- unsigned proto;
- struct ipsec_proto_info *info;
- } protos[4];
- int i;
- bool result;
-
- i = 0;
- if (kernel_ops->inbound_eroute && inbound
- && c->spd.eroute_owner == SOS_NOBODY)
- {
- (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , 256, IPSEC_PROTO_ANY, SADB_SATYPE_UNSPEC, c->spd.this.protocol
- , null_proto_info, 0
- , ERO_DEL_INBOUND, "delete inbound");
- }
-
- if (!kernel_ops->grp_sa)
- {
- if (st->st_ah.present)
- {
- protos[i].info = &st->st_ah;
- protos[i].proto = SA_AH;
- i++;
- }
-
- if (st->st_esp.present)
- {
- protos[i].info = &st->st_esp;
- protos[i].proto = SA_ESP;
- i++;
- }
-
- if (st->st_ipcomp.present)
- {
- protos[i].info = &st->st_ipcomp;
- protos[i].proto = SA_COMP;
- i++;
- }
- }
- else if (st->st_ah.present)
- {
- protos[i].info = &st->st_ah;
- protos[i].proto = SA_AH;
- i++;
- }
- else if (st->st_esp.present)
- {
- protos[i].info = &st->st_esp;
- protos[i].proto = SA_ESP;
- i++;
- }
- else
- {
- impossible(); /* neither AH nor ESP in outbound SA bundle! */
- }
- protos[i].proto = 0;
-
- result = TRUE;
- for (i = 0; protos[i].proto; i++)
- {
- unsigned proto = protos[i].proto;
- ipsec_spi_t spi;
- const ip_address *src, *dst;
-
- if (inbound)
- {
- spi = protos[i].info->our_spi;
- src = &c->spd.that.host_addr;
- dst = &c->spd.this.host_addr;
- }
- else
- {
- spi = protos[i].info->attrs.spi;
- src = &c->spd.this.host_addr;
- dst = &c->spd.that.host_addr;
- }
-
- result &= del_spi(spi, proto, src, dst);
- }
- return result;
-}
-
-/*
- * get information about a given sa
- */
-bool
-get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
-{
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
- struct connection *c = st->st_connection;
-
- *use_time = UNDEFINED_TIME;
-
- if (kernel_ops->get_sa == NULL || !st->st_esp.present)
- return FALSE;
-
- memset(&sa, 0, sizeof(sa));
- sa.proto = SA_ESP;
-
- if (inbound)
- {
- sa.src = &c->spd.that.host_addr;
- sa.dst = &c->spd.this.host_addr;
- sa.spi = st->st_esp.our_spi;
- }
- else
- {
- sa.src = &c->spd.this.host_addr;
- sa.dst = &c->spd.that.host_addr;
- sa.spi = st->st_esp.attrs.spi;
- }
- set_text_said(text_said, sa.dst, sa.spi, sa.proto);
-
- sa.text_said = text_said;
-
- DBG(DBG_KLIPS,
- DBG_log("get %s", text_said)
- )
- if (!kernel_ops->get_sa(&sa, bytes))
- return FALSE;
- DBG(DBG_KLIPS,
- DBG_log(" current: %d bytes", *bytes)
- )
-
- if (st->st_serialno == c->spd.eroute_owner)
- {
- DBG(DBG_KLIPS,
- DBG_log("get %sbound policy with reqid %u"
- , inbound? "in":"out", (u_int)c->spd.reqid + 1)
- )
- sa.transport_proto = c->spd.this.protocol;
- sa.encapsulation = st->st_esp.attrs.encapsulation;
-
- if (inbound)
- {
- sa.src_client = &c->spd.that.client;
- sa.dst_client = &c->spd.this.client;
- }
- else
- {
- sa.src_client = &c->spd.this.client;
- sa.dst_client = &c->spd.that.client;
- }
- if (!kernel_ops->get_policy(&sa, inbound, use_time))
- return FALSE;
- DBG(DBG_KLIPS,
- DBG_log(" use_time: %s", timetoa(use_time, FALSE))
- )
- }
- return TRUE;
-}
-
-const struct kernel_ops *kernel_ops;
-
-#endif /* KLIPS */
-
-void
-init_kernel(void)
-{
-#ifdef KLIPS
-
- if (no_klips)
- {
- kernel_ops = &noklips_kernel_ops;
- return;
- }
-
- init_pfkey();
-
- kernel_ops = &klips_kernel_ops;
-
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- {
- bool linux_ipsec = 0;
- struct stat buf;
-
- linux_ipsec = (stat("/proc/net/pfkey", &buf) == 0);
- if (linux_ipsec)
- {
- plog("Using Linux 2.6 IPsec interface code");
- kernel_ops = &linux_kernel_ops;
- }
- else
- {
- plog("Using KLIPS IPsec interface code");
- }
- }
-#endif
-
- if (kernel_ops->init)
- {
- kernel_ops->init();
- }
-
- /* register SA types that we can negotiate */
- can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
- kernel_ops->pfkey_register();
-
- if (!kernel_ops->policy_lifetime)
- {
- event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
- }
-#endif
-}
-
-/* Note: install_inbound_ipsec_sa is only used by the Responder.
- * The Responder will subsequently use install_ipsec_sa for the outbound.
- * The Initiator uses install_ipsec_sa to install both at once.
- */
-bool
-install_inbound_ipsec_sa(struct state *st)
-{
- struct connection *const c = st->st_connection;
-
- /* If our peer has a fixed-address client, check if we already
- * have a route for that client that conflicts. We will take this
- * as proof that that route and the connections using it are
- * obsolete and should be eliminated. Interestingly, this is
- * the only case in which we can tell that a connection is obsolete.
- */
- passert(c->kind == CK_PERMANENT || c->kind == CK_INSTANCE);
- if (c->spd.that.has_client)
- {
- for (;;)
- {
- struct spd_route *esr;
- struct connection *o = route_owner(c, &esr, NULL, NULL);
-
- if (o == NULL)
- break; /* nobody has a route */
-
- /* note: we ignore the client addresses at this end */
- if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr)
- && o->interface == c->interface)
- break; /* existing route is compatible */
-
- if (o->kind == CK_TEMPLATE && streq(o->name, c->name))
- break; /* ??? is this good enough?? */
-
- loglog(RC_LOG_SERIOUS, "route to peer's client conflicts with \"%s\" %s; releasing old connection to free the route"
- , o->name, ip_str(&o->spd.that.host_addr));
- release_connection(o, FALSE);
- }
- }
-
- DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa() checking if we can route"));
- /* check that we will be able to route and eroute */
- switch (could_route(c))
- {
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
- }
-
-#ifdef KLIPS
- /* (attempt to) actually set up the SAs */
- return setup_half_ipsec_sa(st, TRUE);
-#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa()"));
- return TRUE;
-#endif /* !KLIPS */
-}
-
-/* Install a route and then a prospective shunt eroute or an SA group eroute.
- * Assumption: could_route gave a go-ahead.
- * Any SA Group must have already been created.
- * On failure, steps will be unwound.
- */
-bool
-route_and_eroute(struct connection *c USED_BY_KLIPS
- , struct spd_route *sr USED_BY_KLIPS
- , struct state *st USED_BY_KLIPS)
-{
-#ifdef KLIPS
- struct spd_route *esr;
- struct spd_route *rosr;
- struct connection *ero /* who, if anyone, owns our eroute? */
- , *ro = route_owner(c, &rosr, &ero, &esr);
- bool eroute_installed = FALSE
- , firewall_notified = FALSE
- , route_installed = FALSE;
-
- struct connection *ero_top;
- struct bare_shunt **bspp;
-
- DBG(DBG_CONTROLMORE,
- DBG_log("route_and_eroute with c: %s (next: %s) ero:%s esr:{%p} ro:%s rosr:{%p} and state: %lu"
- , c->name
- , (c->policy_next ? c->policy_next->name : "none")
- , ero ? ero->name : "null"
- , esr
- , ro ? ro->name : "null"
- , rosr
- , st ? st->st_serialno : 0));
-
- /* look along the chain of policies for one with the same name */
- ero_top = ero;
-
-#if 0
- /* XXX - mcr this made sense before, and likely will make sense
- * again, so I'l leaving this to remind me what is up */
- if (ero!= NULL && ero->routing == RT_UNROUTED_KEYED)
- ero = NULL;
-
- for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
- if ((ero2->kind == CK_TEMPLATE || ero2->kind==CK_SECONDARY)
- && streq(ero2->name, c->name))
- break;
-#endif
-
- bspp = (ero == NULL)
- ? bare_shunt_ptr(&sr->this.client, &sr->that.client, sr->this.protocol)
- : NULL;
-
- /* install the eroute */
-
- passert(bspp == NULL || ero == NULL); /* only one non-NULL */
-
- if (bspp != NULL || ero != NULL)
- {
- /* We're replacing an eroute */
-
- /* if no state provided, then install a shunt for later */
- if (st == NULL)
- eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
- , ERO_REPLACE, "replace");
- else
- eroute_installed = sag_eroute(st, sr, ERO_REPLACE, "replace");
-
-#if 0
- /* XXX - MCR. I previously felt that this was a bogus check */
- if (ero != NULL && ero != c && esr != sr)
- {
- /* By elimination, we must be eclipsing ero. Check. */
- passert(ero->kind == CK_TEMPLATE && streq(ero->name, c->name));
- passert(LHAS(LELEM(RT_ROUTED_PROSPECTIVE) | LELEM(RT_ROUTED_ECLIPSED)
- , esr->routing));
- passert(samesubnet(&esr->this.client, &sr->this.client)
- && samesubnet(&esr->that.client, &sr->that.client));
- }
-#endif
- /* remember to free bspp iff we make it out of here alive */
- }
- else
- {
- /* we're adding an eroute */
-
- /* if no state provided, then install a shunt for later */
- if (st == NULL)
- eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
- , ERO_ADD, "add");
- else
- eroute_installed = sag_eroute(st, sr, ERO_ADD, "add");
- }
-
- /* notify the firewall of a new tunnel */
-
- if (eroute_installed)
- {
- /* do we have to notify the firewall? Yes, if we are installing
- * a tunnel eroute and the firewall wasn't notified
- * for a previous tunnel with the same clients. Any Previous
- * tunnel would have to be for our connection, so the actual
- * test is simple.
- */
- firewall_notified = st == NULL /* not a tunnel eroute */
- || sr->eroute_owner != SOS_NOBODY /* already notified */
- || do_command(c, sr, "up"); /* go ahead and notify */
- }
-
- /* install the route */
-
- DBG(DBG_CONTROL,
- DBG_log("route_and_eroute: firewall_notified: %s"
- , firewall_notified ? "true" : "false"));
- if (!firewall_notified)
- {
- /* we're in trouble -- don't do routing */
- }
- else if (ro == NULL)
- {
- /* a new route: no deletion required, but preparation is */
- (void) do_command(c, sr, "prepare"); /* just in case; ignore failure */
- route_installed = do_command(c, sr, "route");
- }
- else if (routed(sr->routing)
- || routes_agree(ro, c))
- {
- route_installed = TRUE; /* nothing to be done */
- }
- else
- {
- /* Some other connection must own the route
- * and the route must disagree. But since could_route
- * must have allowed our stealing it, we'll do so.
- *
- * A feature of LINUX allows us to install the new route
- * before deleting the old if the nexthops differ.
- * This reduces the "window of vulnerability" when packets
- * might flow in the clear.
- */
- if (sameaddr(&sr->this.host_nexthop, &esr->this.host_nexthop))
- {
- (void) do_command(ro, sr, "unroute");
- route_installed = do_command(c, sr, "route");
- }
- else
- {
- route_installed = do_command(c, sr, "route");
- (void) do_command(ro, sr, "unroute");
- }
-
- /* record unrouting */
- if (route_installed)
- {
- do {
- passert(!erouted(rosr->routing));
- rosr->routing = RT_UNROUTED;
-
- /* no need to keep old value */
- ro = route_owner(c, &rosr, NULL, NULL);
- } while (ro != NULL);
- }
- }
-
- /* all done -- clean up */
- if (route_installed)
- {
- /* Success! */
-
- if (bspp != NULL)
- {
- free_bare_shunt(bspp);
- }
- else if (ero != NULL && ero != c)
- {
- /* check if ero is an ancestor of c. */
- struct connection *ero2;
-
- for (ero2 = c; ero2 != NULL && ero2 != c; ero2 = ero2->policy_next)
- ;
-
- if (ero2 == NULL)
- {
- /* By elimination, we must be eclipsing ero. Checked above. */
- if (ero->spd.routing != RT_ROUTED_ECLIPSED)
- {
- ero->spd.routing = RT_ROUTED_ECLIPSED;
- eclipse_count++;
- }
- }
- }
-
- if (st == NULL)
- {
- passert(sr->eroute_owner == SOS_NOBODY);
- sr->routing = RT_ROUTED_PROSPECTIVE;
- }
- else
- {
- char cib[CONN_INST_BUF];
- sr->routing = RT_ROUTED_TUNNEL;
-
- DBG(DBG_CONTROL,
- DBG_log("route_and_eroute: instance \"%s\"%s, setting eroute_owner {spd=%p,sr=%p} to #%ld (was #%ld) (newest_ipsec_sa=#%ld)"
- , st->st_connection->name
- , (fmt_conn_instance(st->st_connection, cib), cib)
- , &st->st_connection->spd, sr
- , st->st_serialno
- , sr->eroute_owner
- , st->st_connection->newest_ipsec_sa));
- sr->eroute_owner = st->st_serialno;
- }
-
- return TRUE;
- }
- else
- {
- /* Failure! Unwind our work. */
- if (firewall_notified && sr->eroute_owner == SOS_NOBODY)
- (void) do_command(c, sr, "down");
-
- if (eroute_installed)
- {
- /* Restore original eroute, if we can.
- * Since there is nothing much to be done if the restoration
- * fails, ignore success or failure.
- */
- if (bspp != NULL)
- {
- /* Restore old bare_shunt.
- * I don't think that this case is very likely.
- * Normally a bare shunt would have been assigned
- * to a connection before we've gotten this far.
- */
- struct bare_shunt *bs = *bspp;
-
- (void) raw_eroute(&bs->said.dst /* should be useless */
- , &bs->ours
- , &bs->said.dst /* should be useless */
- , &bs->his
- , bs->said.spi /* network order */
- , SA_INT
- , SADB_X_SATYPE_INT
- , 0
- , null_proto_info
- , SHUNT_PATIENCE
- , ERO_REPLACE, "restore");
- }
- else if (ero != NULL)
- {
- /* restore ero's former glory */
- if (esr->eroute_owner == SOS_NOBODY)
- {
- /* note: normal or eclipse case */
- (void) shunt_eroute(ero, esr
- , esr->routing, ERO_REPLACE, "restore");
- }
- else
- {
- /* Try to find state that owned eroute.
- * Don't do anything if it cannot be found.
- * This case isn't likely since we don't run
- * the updown script when replacing a SA group
- * with its successor (for the same conn).
- */
- struct state *ost = state_with_serialno(esr->eroute_owner);
-
- if (ost != NULL)
- (void) sag_eroute(ost, esr, ERO_REPLACE, "restore");
- }
- }
- else
- {
- /* there was no previous eroute: delete whatever we installed */
- if (st == NULL)
- (void) shunt_eroute(c, sr
- , sr->routing, ERO_DELETE, "delete");
- else
- (void) sag_eroute(st, sr
- , ERO_DELETE, "delete");
- }
- }
-
- return FALSE;
- }
-#else /* !KLIPS */
- return TRUE;
-#endif /* !KLIPS */
-}
-
-bool
-install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
-{
-#ifdef KLIPS
- struct spd_route *sr;
-
- DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() for #%ld: %s"
- , st->st_serialno
- , inbound_also?
- "inbound and outbound" : "outbound only"));
-
- switch (could_route(st->st_connection))
- {
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
- }
-
- /* (attempt to) actually set up the SA group */
- if ((inbound_also && !setup_half_ipsec_sa(st, TRUE))
- || !setup_half_ipsec_sa(st, FALSE))
- return FALSE;
-
- for (sr = &st->st_connection->spd; sr != NULL; sr = sr->next)
- {
- DBG(DBG_CONTROL, DBG_log("sr for #%ld: %s"
- , st->st_serialno
- , enum_name(&routing_story, sr->routing)));
-
- /*
- * if the eroute owner is not us, then make it us.
- * See test co-terminal-02, pluto-rekey-01, pluto-unit-02/oppo-twice
- */
- pexpect(sr->eroute_owner == SOS_NOBODY
- || sr->routing >= RT_ROUTED_TUNNEL);
-
- if (sr->eroute_owner != st->st_serialno
- && sr->routing != RT_UNROUTED_KEYED)
- {
- if (!route_and_eroute(st->st_connection, sr, st))
- {
- delete_ipsec_sa(st, FALSE);
- /* XXX go and unroute any SRs that were successfully
- * routed already.
- */
- return FALSE;
- }
- }
- }
-#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() %s"
- , inbound_also? "inbound and oubound" : "outbound only"));
-
- switch (could_route(st->st_connection))
- {
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
- }
-
-
-#endif /* !KLIPS */
-
- return TRUE;
-}
-
-/* delete an IPSEC SA.
- * we may not succeed, but we bull ahead anyway because
- * we cannot do anything better by recognizing failure
- */
-void
-delete_ipsec_sa(struct state *st USED_BY_KLIPS, bool inbound_only USED_BY_KLIPS)
-{
-#ifdef KLIPS
- if (!inbound_only)
- {
- /* If the state is the eroute owner, we must adjust
- * the routing for the connection.
- */
- struct connection *c = st->st_connection;
- struct spd_route *sr;
-
- passert(st->st_connection);
-
- for (sr = &c->spd; sr; sr = sr->next)
- {
- if (sr->eroute_owner == st->st_serialno
- && sr->routing == RT_ROUTED_TUNNEL)
- {
- sr->eroute_owner = SOS_NOBODY;
-
- /* Routing should become RT_ROUTED_FAILURE,
- * but if POLICY_FAIL_NONE, then we just go
- * right back to RT_ROUTED_PROSPECTIVE as if no
- * failure happened.
- */
- sr->routing = (c->policy & POLICY_FAIL_MASK) == POLICY_FAIL_NONE
- ? RT_ROUTED_PROSPECTIVE : RT_ROUTED_FAILURE;
-
- (void) do_command(c, sr, "down");
- if ((c->policy & POLICY_DONT_REKEY)
- && c->kind == CK_INSTANCE)
- {
- /* in this special case, even if the connection
- * is still alive (due to an ISAKMP SA),
- * we get rid of routing.
- * Even though there is still an eroute, the c->routing
- * setting will convince unroute_connection to delete it.
- * unroute_connection would be upset if c->routing == RT_ROUTED_TUNNEL
- */
- unroute_connection(c);
- }
- else
- {
- (void) shunt_eroute(c, sr, sr->routing, ERO_REPLACE, "replace with shunt");
- }
- }
- }
- (void) teardown_half_ipsec_sa(st, FALSE);
- }
- (void) teardown_half_ipsec_sa(st, TRUE);
-#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("if I knew how, I'd eroute() and teardown_ipsec_sa()"));
-#endif /* !KLIPS */
-}
-#ifdef NAT_TRAVERSAL
-#ifdef KLIPS
-static bool update_nat_t_ipsec_esp_sa (struct state *st, bool inbound)
-{
- struct connection *c = st->st_connection;
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
- ip_address
- src = inbound? c->spd.that.host_addr : c->spd.this.host_addr,
- dst = inbound? c->spd.this.host_addr : c->spd.that.host_addr;
-
-
- ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
-
- u_int16_t
- natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port,
- natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
-
- set_text_said(text_said, &dst, esp_spi, SA_ESP);
-
- memset(&sa, 0, sizeof(sa));
- sa.spi = esp_spi;
- sa.src = &src;
- sa.dst = &dst;
- sa.text_said = text_said;
- sa.authalg = alg_info_esp_aa2sadb(st->st_esp.attrs.auth);
- sa.natt_sport = natt_sport;
- sa.natt_dport = natt_dport;
- sa.transid = st->st_esp.attrs.transid;
-
- return kernel_ops->add_sa(&sa, TRUE);
-
-}
-#endif
-
-bool update_ipsec_sa (struct state *st USED_BY_KLIPS)
-{
-#ifdef KLIPS
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)) {
- if ((st->st_esp.present) && (
- (!update_nat_t_ipsec_esp_sa (st, TRUE)) ||
- (!update_nat_t_ipsec_esp_sa (st, FALSE)))) {
- return FALSE;
- }
- }
- else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state)) {
- if ((st->st_esp.present) && (!update_nat_t_ipsec_esp_sa (st, FALSE))) {
- return FALSE;
- }
- }
- else {
- DBG_log("assert failed at %s:%d st_state=%d", __FILE__, __LINE__,
- st->st_state);
- return FALSE;
- }
- return TRUE;
-#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("if I knew how, I'd update_ipsec_sa()"));
- return TRUE;
-#endif /* !KLIPS */
-}
-#endif
-
-/* Check if there was traffic on given SA during the last idle_max
- * seconds. If TRUE, the SA was idle and DPD exchange should be performed.
- * If FALSE, DPD is not necessary. We also return TRUE for errors, as they
- * could mean that the SA is broken and needs to be replace anyway.
- */
-bool
-was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
-{
- static const char procname[] = "/proc/net/ipsec_spi";
- FILE *f;
- char buf[1024];
- u_int bytes;
- int ret = TRUE;
-
- passert(st != NULL);
-
- f = fopen(procname, "r");
- if (f == NULL)
- {
- /* Can't open the file, perhaps were are on 26sec? */
- time_t use_time;
-
- if (get_sa_info(st, TRUE, &bytes, &use_time)
- && use_time != UNDEFINED_TIME)
- {
- *idle_time = time(NULL) - use_time;
- ret = *idle_time >= idle_max;
- }
- }
- else
- {
- while (f != NULL)
- {
- char *line;
- char text_said[SATOT_BUF];
- u_int8_t proto = 0;
- ip_address dst;
- ip_said said;
- ipsec_spi_t spi = 0;
- static const char idle[] = "idle=";
-
- dst = st->st_connection->spd.this.host_addr; /* inbound SA */
- if (st->st_ah.present)
- {
- proto = SA_AH;
- spi = st->st_ah.our_spi;
- }
- if (st->st_esp.present)
- {
- proto = SA_ESP;
- spi = st->st_esp.our_spi;
- }
-
- if (proto == 0 && spi == 0)
- {
- ret = TRUE;
- break;
- }
-
- initsaid(&dst, spi, proto, &said);
- satot(&said, 'x', text_said, SATOT_BUF);
-
- line = fgets(buf, sizeof(buf), f);
- if (line == NULL)
- {
- /* Reached end of list */
- ret = TRUE;
- break;
- }
-
- if (strncmp(line, text_said, strlen(text_said)) == 0)
- {
- /* we found a match, now try to find idle= */
- char *p = strstr(line, idle);
-
- if (p == NULL)
- {
- /* SAs which haven't been used yet don't have it */
- ret = TRUE; /* it didn't have traffic */
- break;
- }
- p += sizeof(idle)-1;
- if (*p == '\0')
- {
- ret = TRUE; /* be paranoid */
- break;
- }
- if (sscanf(p, "%d", (int *) idle_time) <= 0)
- {
- ret = TRUE;
- break;
- }
- if (*idle_time >= idle_max)
- {
- ret = TRUE;
- break;
- }
- else
- {
- ret = FALSE;
- break;
- }
- }
- }
- fclose(f);
- }
- return ret;
-}
diff --git a/programs/pluto/kernel.h b/programs/pluto/kernel.h
deleted file mode 100644
index c01ff31f9..000000000
--- a/programs/pluto/kernel.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* declarations of routines that interface with the kernel's IPsec mechanism
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel.h,v 1.10 2006/03/08 22:12:37 as Exp $
- */
-
-#include "connections.h"
-
-extern bool no_klips; /* don't actually use KLIPS */
-extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
-
-#ifdef KLIPS
-/* Declare eroute things early enough for uses.
- *
- * Flags are encoded above the low-order byte of verbs.
- * "real" eroutes are only outbound. Inbound eroutes don't exist,
- * but an addflow with an INBOUND flag allows IPIP tunnels to be
- * limited to appropriate source and destination addresses.
- */
-
-#define ERO_MASK 0xFF
-#define ERO_FLAG_SHIFT 8
-
-#define ERO_DELETE SADB_X_DELFLOW
-#define ERO_ADD SADB_X_ADDFLOW
-#define ERO_REPLACE (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
-#define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
-#define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
-
-struct pfkey_proto_info {
- int proto;
- int encapsulation;
- unsigned reqid;
-};
-struct sadb_msg;
-
-struct kernel_sa {
- const ip_address *src;
- const ip_address *dst;
-
- const ip_subnet *src_client;
- const ip_subnet *dst_client;
-
- ipsec_spi_t spi;
- unsigned proto;
- unsigned satype;
- unsigned transport_proto;
- unsigned replay_window;
- unsigned reqid;
-
- unsigned authalg;
- unsigned authkeylen;
- char *authkey;
-
- unsigned encalg;
- unsigned enckeylen;
- char *enckey;
-
- unsigned compalg;
-
- int encapsulation;
-#ifdef NAT_TRAVERSAL
- u_int16_t natt_sport, natt_dport;
- u_int8_t transid, natt_type;
- ip_address *natt_oa;
-#endif
- const char *text_said;
-};
-
-struct kernel_ops {
- enum {
- KERNEL_TYPE_NONE,
- KERNEL_TYPE_KLIPS,
- KERNEL_TYPE_LINUX,
- } type;
- bool inbound_eroute;
- bool policy_lifetime;
- int *async_fdp;
-
- void (*init)(void);
- void (*pfkey_register)(void);
- void (*pfkey_register_response)(const struct sadb_msg *msg);
- void (*process_queue)(void);
- void (*process_msg)(void);
- bool (*raw_eroute)(const ip_address *this_host,
- const ip_subnet *this_client,
- const ip_address *that_host,
- const ip_subnet *that_client,
- ipsec_spi_t spi,
- unsigned int satype,
- unsigned int transport_proto,
- const struct pfkey_proto_info *proto_info,
- time_t use_lifetime,
- unsigned int op,
- const char *text_said);
- bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
- time_t *use_time);
- bool (*add_sa)(const struct kernel_sa *sa, bool replace);
- bool (*grp_sa)(const struct kernel_sa *sa_outer,
- const struct kernel_sa *sa_inner);
- bool (*del_sa)(const struct kernel_sa *sa);
- bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
- ipsec_spi_t (*get_spi)(const ip_address *src,
- const ip_address *dst,
- int proto,
- bool tunnel_mode,
- unsigned reqid,
- ipsec_spi_t min,
- ipsec_spi_t max,
- const char *text_said);
-};
-
-
-extern const struct kernel_ops *kernel_ops;
-
-/* information from /proc/net/ipsec_eroute */
-
-struct eroute_info {
- unsigned long count;
- ip_subnet ours;
- ip_subnet his;
- ip_address dst;
- ip_said said;
- int transport_proto;
- struct eroute_info *next;
-};
-
-extern struct eroute_info *orphaned_holds;
-
-extern void show_shunt_status(void);
-#endif
-
-/* A netlink header defines EM_MAXRELSPIS, the max number of SAs in a group.
- * Is there a PF_KEY equivalent?
- */
-#ifndef EM_MAXRELSPIS
-# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
-#endif
-
-extern void record_and_initiate_opportunistic(const ip_subnet *
- , const ip_subnet *
- , int transport_proto
- , const char *why);
-
-extern void init_kernel(void);
-
-extern void scan_proc_shunts(void);
-
-extern bool trap_connection(struct connection *c);
-extern void unroute_connection(struct connection *c);
-
-extern bool has_bare_hold(const ip_address *src, const ip_address *dst
- , int transport_proto);
-
-extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst
- , policy_prio_t policy_prio
- , ipsec_spi_t shunt_spi /* in host order! */
- , bool repl
- , unsigned int transport_proto
- , const char *why);
-
-extern bool assign_hold(struct connection *c
- , struct spd_route *sr
- , int transport_proto
- , const ip_address *src, const ip_address *dst);
-
-extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective);
-
-
-struct state; /* forward declaration of tag */
-extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid
- , int proto
- , struct spd_route *sr
- , bool tunnel_mode);
-extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode);
-
-extern bool install_inbound_ipsec_sa(struct state *st);
-extern bool install_ipsec_sa(struct state *st, bool inbound_also);
-extern void delete_ipsec_sa(struct state *st, bool inbound_only);
-extern bool route_and_eroute(struct connection *c
- , struct spd_route *sr
- , struct state *st);
-extern bool was_eroute_idle(struct state *st, time_t idle_max
- , time_t *idle_time);
-extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes
- , time_t *use_time);
-
-#ifdef NAT_TRAVERSAL
-extern bool update_ipsec_sa(struct state *st);
-#endif
diff --git a/programs/pluto/kernel_alg.c b/programs/pluto/kernel_alg.c
deleted file mode 100644
index 920a879d7..000000000
--- a/programs/pluto/kernel_alg.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/* Kernel runtime algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_alg.c,v 1.9 2005/08/17 16:31:24 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <sys/queue.h>
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "spdb.h"
-#include "kernel.h"
-#include "kernel_alg.h"
-#include "alg_info.h"
-
-#ifndef NO_PLUTO
-#include "log.h"
-#include "whack.h"
-#include "db_ops.h"
-#else
-/*
- * macros/functions for compilation without pluto (eg: spi for manual conns)
- */
-extern int debug;
-#include <assert.h>
-#define passert(x) assert(x)
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define plog(x, args...) fprintf(stderr, x "\n" , ##args);
-#endif /* NO_PLUTO */
-/* ALG storage */
-static struct sadb_alg esp_aalg[SADB_AALG_MAX+1];
-static struct sadb_alg esp_ealg[SADB_EALG_MAX+1];
-static int esp_ealg_num = 0;
-static int esp_aalg_num = 0;
-
-#define ESP_EALG_PRESENT(algo) (((algo)<=SADB_EALG_MAX)&&(esp_ealg[(algo)].sadb_alg_id==(algo)))
-#define ESP_EALG_FOR_EACH_UPDOWN(algo) \
- for (algo=SADB_EALG_MAX; algo >0 ; algo--) \
- if (ESP_EALG_PRESENT(algo))
-#define ESP_AALG_PRESENT(algo) ((algo<=SADB_AALG_MAX)&&(esp_aalg[(algo)].sadb_alg_id==(algo)))
-#define ESP_AALG_FOR_EACH_UPDOWN(algo) \
- for (algo=SADB_AALG_MAX; algo >0 ; algo--) \
- if (ESP_AALG_PRESENT(algo))
-
-static struct sadb_alg*
-sadb_alg_ptr (int satype, int exttype, int alg_id, int rw)
-{
- struct sadb_alg *alg_p = NULL;
-
- switch (exttype)
- {
- case SADB_EXT_SUPPORTED_AUTH:
- if (alg_id > SADB_AALG_MAX)
- return NULL;
- break;
- case SADB_EXT_SUPPORTED_ENCRYPT:
- if (alg_id > SADB_EALG_MAX)
- return NULL;
- break;
- default:
- return NULL;
- }
-
- switch (satype)
- {
- case SADB_SATYPE_ESP:
- alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
- &esp_ealg[alg_id] : &esp_aalg[alg_id];
- /* get for write: increment elem count */
- if (rw)
- {
- (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
- esp_ealg_num++ : esp_aalg_num++;
- }
- break;
- case SADB_SATYPE_AH:
- default:
- return NULL;
- }
-
- return alg_p;
-}
-
-const struct sadb_alg *
-kernel_alg_sadb_alg_get(int satype, int exttype, int alg_id)
-{
- return sadb_alg_ptr(satype, exttype, alg_id, 0);
-}
-
-/*
- * Forget previous registration
- */
-static void
-kernel_alg_init(void)
-{
- DBG(DBG_KLIPS,
- DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)",
- &esp_aalg, (int)sizeof (esp_aalg),
- &esp_ealg, (int)sizeof (esp_ealg))
- )
- memset (&esp_aalg, 0, sizeof (esp_aalg));
- memset (&esp_ealg, 0, sizeof (esp_ealg));
- esp_ealg_num=esp_aalg_num = 0;
-}
-
-static int
-kernel_alg_add(int satype, int exttype, const struct sadb_alg *sadb_alg)
-{
- struct sadb_alg *alg_p = NULL;
- int alg_id = sadb_alg->sadb_alg_id;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d",
- satype, exttype, sadb_alg->sadb_alg_id)
- )
- if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1)))
- return -1;
-
- /* This logic "mimics" KLIPS: first algo implementation will be used */
- if (alg_p->sadb_alg_id)
- {
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_add(): discarding already setup "
- "satype=%d, exttype=%d, alg_id=%d",
- satype, exttype, sadb_alg->sadb_alg_id)
- )
- return 0;
- }
- *alg_p = *sadb_alg;
- return 1;
-}
-
-bool
-kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len,
- struct alg_info_esp *alg_info __attribute__((unused)))
-{
- struct sadb_alg *alg_p = NULL;
-
- /*
- * test #1: encrypt algo must be present
- */
- int ret = ESP_EALG_PRESENT(alg_id);
- if (!ret) goto out;
-
- alg_p = &esp_ealg[alg_id];
-
- /*
- * test #2: if key_len specified, it must be in range
- */
- if (key_len
- && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits))
- {
- plog("kernel_alg_db_add() key_len not in range: alg_id=%d, "
- "key_len=%d, alg_minbits=%d, alg_maxbits=%d"
- , alg_id, key_len
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits);
- ret = FALSE;
- }
-
-out:
- if (ret)
- {
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_ok(%d,%d): "
- "alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "res=%d, ret=%d"
- , alg_id, key_len
- , alg_p->sadb_alg_id
- , alg_p->sadb_alg_ivlen
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- , alg_p->sadb_alg_reserved
- , ret);
- )
- }
- else
- {
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len);
- )
- }
- return ret;
-}
-
-/*
- * ML: make F_STRICT logic consider enc,auth algorithms
- */
-#ifndef NO_PLUTO
-bool
-kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, struct alg_info_esp *alg_info)
-{
- int ealg_insecure;
-
- /*
- * key_len passed comes from esp_attrs read from peer
- * For many older algoritms (eg 3DES) this key_len is fixed
- * and get passed as 0.
- * ... then get default key_len
- */
- if (key_len == 0)
- key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE;
-
- /*
- * simple test to toss low key_len, will accept it only
- * if specified in "esp" string
- */
- ealg_insecure = (key_len < 128) ;
-
- if (ealg_insecure
- || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT))
- {
- int i;
- struct esp_info *esp_info;
-
- if (alg_info)
- {
- ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
- {
- if (esp_info->esp_ealg_id == ealg
- && (esp_info->esp_ealg_keylen == 0 || key_len == 0
- || esp_info->esp_ealg_keylen == key_len)
- && esp_info->esp_aalg_id == aalg)
- {
- if (ealg_insecure)
- {
- loglog(RC_LOG_SERIOUS
- , "You should NOT use insecure ESP algorithms [%s (%d)]!"
- , enum_name(&esp_transformid_names, ealg), key_len);
- }
- return TRUE;
- }
- }
- }
- plog("IPSec Transform [%s (%d), %s] refused due to %s",
- enum_name(&esp_transformid_names, ealg), key_len,
- enum_name(&auth_alg_names, aalg),
- ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag");
- return FALSE;
- }
- return TRUE;
-}
-#endif /* NO_PLUTO */
-
-/*
- * Load kernel_alg arrays from /proc
- * used in manual mode from klips/utils/spi.c
- */
-int
-kernel_alg_proc_read(void)
-{
- int satype;
- int supp_exttype;
- int alg_id, ivlen, minbits, maxbits;
- struct sadb_alg sadb_alg;
- int ret;
- char buf[128];
-
- FILE *fp=fopen("/proc/net/pf_key_supported", "r");
-
- if (!fp)
- return -1;
-
- kernel_alg_init();
-
- while (fgets(buf, sizeof(buf), fp))
- {
- if (buf[0] != ' ') /* skip titles */
- continue;
-
- sscanf(buf, "%d %d %d %d %d %d"
- ,&satype, &supp_exttype
- , &alg_id, &ivlen
- , &minbits, &maxbits);
-
- switch (satype)
- {
- case SADB_SATYPE_ESP:
- switch(supp_exttype)
- {
- case SADB_EXT_SUPPORTED_AUTH:
- case SADB_EXT_SUPPORTED_ENCRYPT:
- sadb_alg.sadb_alg_id = alg_id;
- sadb_alg.sadb_alg_ivlen = ivlen;
- sadb_alg.sadb_alg_minbits = minbits;
- sadb_alg.sadb_alg_maxbits = maxbits;
- ret = kernel_alg_add(satype, supp_exttype, &sadb_alg);
- DBG(DBG_CRYPT,
- DBG_log("kernel_alg_proc_read() alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "ret=%d"
- , sadb_alg.sadb_alg_id
- , sadb_alg.sadb_alg_ivlen
- , sadb_alg.sadb_alg_minbits
- , sadb_alg.sadb_alg_maxbits
- , ret)
- )
- }
- default:
- continue;
- }
- }
- fclose(fp);
- return 0;
-}
-
-/*
- * Load kernel_alg arrays pluto's SADB_REGISTER
- * user by pluto/kernel.c
- */
-
-void
-kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen)
-{
- /* Trick: one 'type-mangle-able' pointer to ease offset/assign */
- union {
- const struct sadb_msg *msg;
- const struct sadb_supported *supported;
- const struct sadb_ext *ext;
- const struct sadb_alg *alg;
- const char *ch;
- } sadb;
-
- int satype;
- int msglen;
- int i = 0;
-
- /* Initialize alg arrays */
- kernel_alg_init();
- satype = msg_buf->sadb_msg_satype;
- sadb.msg = msg_buf;
- msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN;
- msglen -= sizeof(struct sadb_msg);
- buflen -= sizeof(struct sadb_msg);
- passert(buflen > 0);
-
- sadb.msg++;
-
- while(msglen)
- {
- int supp_exttype = sadb.supported->sadb_supported_exttype;
- int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
- "sadb_msg_len=%d sadb_supported_len=%d"
- , satype==SADB_SATYPE_ESP? "ESP" : "AH"
- , msg_buf->sadb_msg_len, supp_len)
- )
- sadb.supported++;
- msglen -= supp_len;
- buflen -= supp_len;
- passert(buflen >= 0);
-
- for (supp_len -= sizeof(struct sadb_supported);
- supp_len;
- supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++)
- {
- int ret = kernel_alg_add(satype, supp_exttype, sadb.alg);
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
- "alg[%d], exttype=%d, satype=%d, alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "res=%d, ret=%d"
- , satype==SADB_SATYPE_ESP? "ESP" : "AH"
- , i
- , supp_exttype
- , satype
- , sadb.alg->sadb_alg_id
- , sadb.alg->sadb_alg_ivlen
- , sadb.alg->sadb_alg_minbits
- , sadb.alg->sadb_alg_maxbits
- , sadb.alg->sadb_alg_reserved
- , ret)
- )
- }
- }
-}
-
-u_int
-kernel_alg_esp_enc_keylen(u_int alg_id)
-{
- u_int keylen = 0;
-
- if (!ESP_EALG_PRESENT(alg_id))
- goto none;
-
- keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE;
-
- switch (alg_id)
- {
- /*
- * this is veryUgly[TM]
- * Peer should have sent KEY_LENGTH attribute for ESP_AES
- * but if not do force it to 128 instead of using sadb_alg_maxbits
- * from kernel.
- */
- case ESP_AES:
- keylen = 128/BITS_PER_BYTE;
- break;
- }
-
-none:
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_keylen():"
- "alg_id=%d, keylen=%d",
- alg_id, keylen)
- )
- return keylen;
-}
-
-struct sadb_alg *
-kernel_alg_esp_sadb_alg(u_int alg_id)
-{
- struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id))
- ? &esp_ealg[alg_id] : NULL;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p"
- , alg_id, sadb_alg)
- )
- return sadb_alg;
-}
-
-#ifndef NO_PLUTO
-void kernel_alg_list(void)
-{
- u_int sadb_id;
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered ESP Encryption Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++)
- {
- if (ESP_EALG_PRESENT(sadb_id))
- {
- struct sadb_alg *alg_p = &esp_ealg[sadb_id];
-
- whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d"
- , sadb_id
- , enum_name(&esp_transformid_names, sadb_id)
- , alg_p->sadb_alg_ivlen
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- );
- }
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered ESP Authentication Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++)
- {
- if (ESP_AALG_PRESENT(sadb_id))
- {
- u_int aaid = alg_info_esp_sadb2aa(sadb_id);
- struct sadb_alg *alg_p = &esp_aalg[sadb_id];
-
- whack_log(RC_COMMENT, "#%-5d %s, keylen: %d-%d"
- , aaid
- , enum_name(&auth_alg_names, aaid)
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- );
- }
- }
-}
-
-void
-kernel_alg_show_connection(struct connection *c, const char *instance)
-{
- char buf[256];
- struct state *st;
-
- if (c->alg_info_esp)
- {
- alg_info_snprint(buf, sizeof(buf), (struct alg_info *)c->alg_info_esp);
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithms wanted: %s"
- , c->name
- , instance
- , buf);
- }
- if (c->alg_info_esp)
- {
- alg_info_snprint_esp(buf, sizeof(buf), c->alg_info_esp);
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithms loaded: %s"
- , c->name
- , instance
- , buf);
- }
- st = state_with_serialno(c->newest_ipsec_sa);
- if (st && st->st_esp.present)
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithm newest: %s_%d-%s; pfsgroup=%s"
- , c->name
- , instance
- , enum_show(&esp_transformid_names, st->st_esp.attrs.transid)
- +4 /* strlen("ESP_") */
- , st->st_esp.attrs.key_len
- , enum_show(&auth_alg_names, st->st_esp.attrs.auth)+
- +15 /* strlen("AUTH_ALGORITHM_") */
- , c->policy & POLICY_PFS ?
- c->alg_info_esp->esp_pfsgroup ?
- enum_show(&oakley_group_names,
- c->alg_info_esp->esp_pfsgroup)
- +13 /*strlen("OAKLEY_GROUP_")*/
- : "<Phase1>"
- : "<N/A>"
- );
-}
-#endif /* NO_PLUTO */
-
-bool
-kernel_alg_esp_auth_ok(u_int auth,
- struct alg_info_esp *alg_info __attribute__((unused)))
-{
- return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth));
-}
-
-u_int
-kernel_alg_esp_auth_keylen(u_int auth)
-{
- u_int sadb_aalg = alg_info_esp_aa2sadb(auth);
-
- u_int a_keylen = (sadb_aalg)
- ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE
- : 0;
-
- DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING,
- DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): "
- "a_keylen=%d", auth, sadb_aalg, a_keylen)
- )
- return a_keylen;
-}
-
-struct esp_info *
-kernel_alg_esp_info(int transid, int auth)
-{
- int sadb_aalg, sadb_ealg;
- static struct esp_info ei_buf;
-
- sadb_ealg = transid;
- sadb_aalg = alg_info_esp_aa2sadb(auth);
-
- if (!ESP_EALG_PRESENT(sadb_ealg))
- goto none;
- if (!ESP_AALG_PRESENT(sadb_aalg))
- goto none;
-
- memset(&ei_buf, 0, sizeof (ei_buf));
- ei_buf.transid = transid;
- ei_buf.auth = auth;
-
- /* don't return "default" keylen because this value is used from
- * setup_half_ipsec_sa() to "validate" keylen
- * In effect, enckeylen will be used as "max" value
- */
- ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE;
- ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE;
- ei_buf.encryptalg = sadb_ealg;
- ei_buf.authalg = sadb_aalg;
-
- DBG(DBG_PARSING,
- DBG_log("kernel_alg_esp_info():"
- "transid=%d, auth=%d, ei=%p, "
- "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d",
- transid, auth, &ei_buf,
- (int)ei_buf.enckeylen, (int)ei_buf.authkeylen,
- ei_buf.encryptalg, ei_buf.authalg)
- )
- return &ei_buf;
-
-none:
- DBG(DBG_PARSING,
- DBG_log("kernel_alg_esp_info():"
- "transid=%d, auth=%d, ei=NULL",
- transid, auth)
- )
- return NULL;
-}
-
-#ifndef NO_PLUTO
-static void
-kernel_alg_policy_algorithms(struct esp_info *esp_info)
-{
- u_int ealg_id = esp_info->esp_ealg_id;
-
- switch(ealg_id)
- {
- case 0:
- case ESP_DES:
- case ESP_3DES:
- case ESP_NULL:
- case ESP_CAST:
- break;
- default:
- if (!esp_info->esp_ealg_keylen)
- {
- /* algos that need KEY_LENGTH
- *
- * Note: this is a very dirty hack ;-)
- * Idea: Add a key_length_needed attribute to
- * esp_ealg ??
- */
- esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits;
- }
- }
-}
-
-static bool
-kernel_alg_db_add(struct db_context *db_ctx, struct esp_info *esp_info, lset_t policy)
-{
- u_int ealg_id, aalg_id;
-
- ealg_id = esp_info->esp_ealg_id;
-
- if (!ESP_EALG_PRESENT(ealg_id))
- {
- DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id);
- return FALSE;
- }
-
- if (!(policy & POLICY_AUTHENTICATE)) /* skip ESP auth attrs for AH */
- {
- aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id);
-
- if (!ESP_AALG_PRESENT(aalg_id))
- {
- DBG_log("kernel_alg_db_add() kernel auth "
- "aalg_id=%d not present", aalg_id);
- return FALSE;
- }
- }
-
- /* do algo policy */
- kernel_alg_policy_algorithms(esp_info);
-
- /* open new transformation */
- db_trans_add(db_ctx, ealg_id);
-
- /* add ESP auth attr */
- if (!(policy & POLICY_AUTHENTICATE))
- db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id);
-
- /* add keylegth if specified in esp= string */
- if (esp_info->esp_ealg_keylen)
- db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen);
-
- return TRUE;
-}
-
-/*
- * Create proposal with runtime kernel algos, merging
- * with passed proposal if not NULL
- *
- * for now this function does free() previous returned
- * malloced pointer (this quirk allows easier spdb.c change)
- */
-struct db_context *
-kernel_alg_db_new(struct alg_info_esp *alg_info, lset_t policy )
-{
- const struct esp_info *esp_info;
- struct esp_info tmp_esp_info;
- struct db_context *ctx_new=NULL;
- struct db_trans *t;
- struct db_prop *prop;
- u_int trans_cnt;
- int tn = 0;
-
- if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */
- return NULL;
-
- trans_cnt = esp_ealg_num * esp_aalg_num;
- DBG(DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() initial trans_cnt=%d"
- , trans_cnt)
- )
-
- /* pass aprox. number of transforms and attributes */
- ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2);
-
- /*
- * Loop: for each element (struct esp_info) of alg_info,
- * if kernel support is present then build the transform (and attrs)
- * if NULL alg_info, propose everything ...
- */
-
- if (alg_info)
- {
- int i;
-
- ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
- {
- tmp_esp_info = *esp_info;
- kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
- }
- }
- else
- {
- u_int ealg_id;
-
- ESP_EALG_FOR_EACH_UPDOWN(ealg_id)
- {
- u_int aalg_id;
-
- tmp_esp_info.esp_ealg_id = ealg_id;
- tmp_esp_info.esp_ealg_keylen = 0;
-
- for (aalg_id = 1; aalg_id <= SADB_AALG_MAX; aalg_id++)
- {
- if (ESP_AALG_PRESENT(aalg_id))
- {
- tmp_esp_info.esp_aalg_id = alg_info_esp_sadb2aa(aalg_id);
- tmp_esp_info.esp_aalg_keylen = 0;
- kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
- }
- }
- }
- }
-
- prop = db_prop_get(ctx_new);
-
- DBG(DBG_CONTROL|DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() "
- "will return p_new->protoid=%d, p_new->trans_cnt=%d"
- , prop->protoid, prop->trans_cnt)
- )
-
- for (t = prop->trans, tn = 0; tn < prop->trans_cnt; tn++)
- {
- DBG(DBG_CONTROL|DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() "
- " trans[%d]: transid=%d, attr_cnt=%d, "
- "attrs[0].type=%d, attrs[0].val=%d"
- , tn
- , t[tn].transid, t[tn].attr_cnt
- , t[tn].attrs[0].type, t[tn].attrs[0].val)
- )
- }
- return ctx_new;
-}
-#endif /* NO_PLUTO */
diff --git a/programs/pluto/kernel_alg.h b/programs/pluto/kernel_alg.h
deleted file mode 100644
index 483e97da1..000000000
--- a/programs/pluto/kernel_alg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Kernel runtime algorithm handling interface definitions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_alg.h,v 1.5 2005/08/17 16:31:24 as Exp $
- */
-
-#ifndef _KERNEL_ALG_H
-#define _KERNEL_ALG_H
-
-#include "alg_info.h"
-#include "spdb.h"
-
-/* status info */
-extern void kernel_alg_show_status(void);
-void kernel_alg_show_connection(struct connection *c, const char *instance);
-
-/* Registration messages from pluto */
-extern void kernel_alg_register_pfkey(const struct sadb_msg *msg, int buflen);
-
-/* ESP interface */
-extern struct sadb_alg *kernel_alg_esp_sadb_alg(u_int alg_id);
-extern u_int kernel_alg_esp_ivlen(u_int alg_id);
-extern bool kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len, struct alg_info_esp *nfo);
-extern bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, struct alg_info_esp *alg_info);
-extern u_int kernel_alg_esp_enc_keylen(u_int alg_id);
-extern bool kernel_alg_esp_auth_ok(u_int auth, struct alg_info_esp *nfo);
-extern u_int kernel_alg_esp_auth_keylen(u_int auth);
-extern int kernel_alg_proc_read(void);
-extern void kernel_alg_list(void);
-
-/* get sadb_alg for passed args */
-extern const struct sadb_alg * kernel_alg_sadb_alg_get(int satype, int exttype, int alg_id);
-
-extern struct db_context * kernel_alg_db_new(struct alg_info_esp *ai, lset_t policy);
-struct esp_info * kernel_alg_esp_info(int esp_id, int auth_id);
-#endif /* _KERNEL_ALG_H */
diff --git a/programs/pluto/kernel_netlink.c b/programs/pluto/kernel_netlink.c
deleted file mode 100644
index fd43c4653..000000000
--- a/programs/pluto/kernel_netlink.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/* netlink interface to the kernel's IPsec mechanism
- * Copyright (C) 2003 Herbert Xu.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_netlink.c,v 1.24 2006/03/10 14:49:43 as Exp $
- */
-
-#if defined(linux) && defined(KERNEL26_SUPPORT)
-
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <unistd.h>
-
-#include "kameipsec.h"
-#include "linux26/rtnetlink.h"
-#include "linux26/xfrm.h"
-
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "kernel.h"
-#include "kernel_netlink.h"
-#include "kernel_pfkey.h"
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-#include "kernel_alg.h"
-
-/* Minimum priority number in SPD used by pluto. */
-#define MIN_SPD_PRIORITY 1024
-
-static int netlinkfd = NULL_FD;
-static int netlink_bcast_fd = NULL_FD;
-
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
-
-static sparse_names xfrm_type_names = {
- NE(NLMSG_NOOP),
- NE(NLMSG_ERROR),
- NE(NLMSG_DONE),
- NE(NLMSG_OVERRUN),
-
- NE(XFRM_MSG_NEWSA),
- NE(XFRM_MSG_DELSA),
- NE(XFRM_MSG_GETSA),
-
- NE(XFRM_MSG_NEWPOLICY),
- NE(XFRM_MSG_DELPOLICY),
- NE(XFRM_MSG_GETPOLICY),
-
- NE(XFRM_MSG_ALLOCSPI),
- NE(XFRM_MSG_ACQUIRE),
- NE(XFRM_MSG_EXPIRE),
-
- NE(XFRM_MSG_UPDPOLICY),
- NE(XFRM_MSG_UPDSA),
-
- NE(XFRM_MSG_POLEXPIRE),
-
- NE(XFRM_MSG_MAX),
-
- { 0, sparse_end }
-};
-
-#undef NE
-
-/* Authentication algorithms */
-static sparse_names aalg_list = {
- { SADB_X_AALG_NULL, "digest_null" },
- { SADB_AALG_MD5_HMAC, "md5" },
- { SADB_AALG_SHA1_HMAC, "sha1" },
- { SADB_AALG_SHA2_256_HMAC, "sha256" },
- { SADB_AALG_SHA2_384_HMAC, "sha384" },
- { SADB_AALG_SHA2_512_HMAC, "sha512" },
- { SADB_AALG_RIPEMD_160_HMAC, "ripemd160" },
- { SADB_X_AALG_NULL, "null" },
- { 0, sparse_end }
-};
-
-/* Encryption algorithms */
-static sparse_names ealg_list = {
- { SADB_EALG_NULL, "cipher_null" },
- { SADB_EALG_DES_CBC, "des" },
- { SADB_EALG_3DES_CBC, "des3_ede" },
- { SADB_EALG_IDEA_CBC, "idea" },
- { SADB_EALG_CAST_CBC, "cast128" },
- { SADB_EALG_BLOWFISH_CBC, "blowfish" },
- { SADB_EALG_AES_CBC, "aes" },
- { SADB_X_EALG_SERPENT_CBC, "serpent" },
- { SADB_X_EALG_TWOFISH_CBC, "twofish" },
- { 0, sparse_end }
-};
-
-/* Compression algorithms */
-static sparse_names calg_list = {
- { SADB_X_CALG_DEFLATE, "deflate" },
- { SADB_X_CALG_LZS, "lzs" },
- { SADB_X_CALG_LZJH, "lzjh" },
- { 0, sparse_end }
-};
-
-/** ip2xfrm - Take an IP address and convert to an xfrm.
- *
- * @param addr ip_address
- * @param xaddr xfrm_address_t - IPv[46] Address from addr is copied here.
- */
-static void
-ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
-{
- if (addr->u.v4.sin_family == AF_INET)
- {
- xaddr->a4 = addr->u.v4.sin_addr.s_addr;
- }
- else
- {
- memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
- }
-}
-
-/** init_netlink - Initialize the netlink inferface. Opens the sockets and
- * then binds to the broadcast socket.
- */
-static void
-init_netlink(void)
-{
- struct sockaddr_nl addr;
-
- netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
-
- if (netlinkfd < 0)
- exit_log_errno((e, "socket() in init_netlink()"));
-
- if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
-
- netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
-
- if (netlink_bcast_fd < 0)
- exit_log_errno((e, "socket() for bcast in init_netlink()"));
-
- if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
-
- if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
- exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
-
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = getpid();
- addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
- if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
-}
-
-/** send_netlink_msg
- *
- * @param hdr - Data to be sent.
- * @param rbuf - Return Buffer - contains data returned from the send.
- * @param rbuf_len - Length of rbuf
- * @param description - String - user friendly description of what is
- * being attempted. Used for diagnostics
- * @param text_said - String
- * @return bool True if the message was succesfully sent.
- */
-static bool
-send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
-, const char *description, const char *text_said)
-{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- char data[1024];
- } rsp;
-
- size_t len;
- ssize_t r;
- struct sockaddr_nl addr;
- static uint32_t seq;
-
- if (no_klips)
- {
- return TRUE;
- }
-
- hdr->nlmsg_seq = ++seq;
- len = hdr->nlmsg_len;
- do {
- r = write(netlinkfd, hdr, len);
- } while (r < 0 && errno == EINTR);
- if (r < 0)
- {
- log_errno((e
- , "netlink write() of %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
- }
- else if ((size_t)r != len)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink write() of %s message"
- " for %s %s truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)len);
- return FALSE;
- }
-
- for (;;) {
- socklen_t alen;
-
- alen = sizeof(addr);
- r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
- if (r < 0)
- {
- if (errno == EINTR)
- {
- continue;
- }
- log_errno((e
- , "netlink recvfrom() of response to our %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
- }
- else if ((size_t) r < sizeof(rsp.n))
- {
- plog("netlink read truncated message: %ld bytes; ignore message"
- , (long) r);
- continue;
- }
- else if (addr.nl_pid != 0)
- {
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("netlink: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- continue;
- }
- else if (rsp.n.nlmsg_seq != seq)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
- , rsp.n.nlmsg_seq, seq
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
- continue;
- }
- break;
- }
-
- if (rsp.n.nlmsg_len > (size_t) r)
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long) len, (unsigned long) rsp.n.nlmsg_len);
- return FALSE;
- }
- else if (rsp.n.nlmsg_type != NLMSG_ERROR
- && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was of wrong type (%s)"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
- return FALSE;
- }
- else if (rbuf)
- {
- if ((size_t) r > rbuf_len)
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was too long: %ld > %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)rbuf_len);
- return FALSE;
- }
- memcpy(rbuf, &rsp, r);
- return TRUE;
- }
- else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink response for %s %s included errno %d: %s"
- , description, text_said
- , -rsp.e.error
- , strerror(-rsp.e.error));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/** netlink_policy -
- *
- * @param hdr - Data to check
- * @param enoent_ok - Boolean - OK or not OK.
- * @param text_said - String
- * @return boolean
- */
-static bool
-netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
-{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- } rsp;
- int error;
-
- rsp.n.nlmsg_type = NLMSG_ERROR;
- if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
- {
- return FALSE;
- }
-
- error = -rsp.e.error;
- if (!error)
- {
- return TRUE;
- }
-
- if (error == ENOENT && enoent_ok)
- {
- return TRUE;
- }
-
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink %s response for flow %s included errno %d: %s"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , text_said
- , error
- , strerror(error));
- return FALSE;
-}
-
-/** netlink_raw_eroute
- *
- * @param this_host ip_address
- * @param this_client ip_subnet
- * @param that_host ip_address
- * @param that_client ip_subnet
- * @param spi
- * @param proto int (Currently unused) Contains protocol (u=tcp, 17=udp, etc...)
- * @param transport_proto int (Currently unused) 0=tunnel, 1=transport
- * @param satype int
- * @param proto_info
- * @param lifetime (Currently unused)
- * @param ip int
- * @return boolean True if successful
- */
-static bool
-netlink_raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info
- , time_t use_lifetime UNUSED
- , unsigned int op
- , const char *text_said)
-{
- struct {
- struct nlmsghdr n;
- union {
- struct xfrm_userpolicy_info p;
- struct xfrm_userpolicy_id id;
- } u;
- char data[1024];
- } req;
- int shift;
- int dir;
- int family;
- int policy;
- bool ok;
- bool enoent_ok;
-
- policy = IPSEC_POLICY_IPSEC;
-
- if (satype == SADB_X_SATYPE_INT)
- {
- /* shunt route */
- switch (ntohl(spi))
- {
- case SPI_PASS:
- policy = IPSEC_POLICY_NONE;
- break;
- case SPI_DROP:
- case SPI_REJECT:
- default:
- policy = IPSEC_POLICY_DISCARD;
- break;
- case SPI_TRAP:
- case SPI_TRAPSUBNET:
- case SPI_HOLD:
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- return TRUE;
- }
- break;
- }
- }
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-
- family = that_client->addr.u.v4.sin_family;
- shift = (family == AF_INET) ? 5 : 7;
-
- req.u.p.sel.sport = portof(&this_client->addr);
- req.u.p.sel.dport = portof(&that_client->addr);
- req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
- req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
- ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
- ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
- req.u.p.sel.prefixlen_s = this_client->maskbits;
- req.u.p.sel.prefixlen_d = that_client->maskbits;
- req.u.p.sel.proto = transport_proto;
- req.u.p.sel.family = family;
-
- dir = XFRM_POLICY_OUT;
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- dir = XFRM_POLICY_IN;
- }
-
- if ((op & ERO_MASK) == ERO_DELETE)
- {
- req.u.id.dir = dir;
- req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
- }
- else
- {
- int src, dst;
-
- req.u.p.dir = dir;
-
- src = req.u.p.sel.prefixlen_s;
- dst = req.u.p.sel.prefixlen_d;
- if (dir != XFRM_POLICY_OUT) {
- src = req.u.p.sel.prefixlen_d;
- dst = req.u.p.sel.prefixlen_s;
- }
- req.u.p.priority = MIN_SPD_PRIORITY
- + (((2 << shift) - src) << shift)
- + (2 << shift) - dst;
-
- req.u.p.action = XFRM_POLICY_ALLOW;
- if (policy == IPSEC_POLICY_DISCARD)
- {
- req.u.p.action = XFRM_POLICY_BLOCK;
- }
- req.u.p.lft.soft_use_expires_seconds = use_lifetime;
- req.u.p.lft.soft_byte_limit = XFRM_INF;
- req.u.p.lft.soft_packet_limit = XFRM_INF;
- req.u.p.lft.hard_byte_limit = XFRM_INF;
- req.u.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
- if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
- {
- req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
- }
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
- }
-
- if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
- {
- struct rtattr *attr;
- struct xfrm_user_tmpl tmpl[4];
- int i;
-
- memset(tmpl, 0, sizeof(tmpl));
- for (i = 0; proto_info[i].proto; i++)
- {
- tmpl[i].reqid = proto_info[i].reqid;
- tmpl[i].id.proto = proto_info[i].proto;
- tmpl[i].optional =
- proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
- tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
- tmpl[i].mode =
- proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
-
- if (!tmpl[i].mode)
- {
- continue;
- }
-
- ip2xfrm(this_host, &tmpl[i].saddr);
- ip2xfrm(that_host, &tmpl[i].id.daddr);
- }
-
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
- attr->rta_type = XFRMA_TMPL;
- attr->rta_len = i * sizeof(tmpl[0]);
- memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
- attr->rta_len = RTA_LENGTH(attr->rta_len);
- req.n.nlmsg_len += attr->rta_len;
- }
-
- enoent_ok = FALSE;
- if (op == ERO_DEL_INBOUND)
- {
- enoent_ok = TRUE;
- }
- else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
- {
- enoent_ok = TRUE;
- }
-
- ok = netlink_policy(&req.n, enoent_ok, text_said);
- switch (dir)
- {
- case XFRM_POLICY_IN:
- if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
- {
- req.u.id.dir = XFRM_POLICY_FWD;
- }
- else if (!ok)
- {
- break;
- }
- else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
- && satype != SADB_X_SATYPE_INT)
- {
- break;
- }
- else
- {
- req.u.p.dir = XFRM_POLICY_FWD;
- }
- ok &= netlink_policy(&req.n, enoent_ok, text_said);
- break;
- }
-
- return ok;
-}
-
-/** netlink_add_sa - Add an SA into the kernel SPDB via netlink
- *
- * @param sa Kernel SA to add/modify
- * @param replace boolean - true if this replaces an existing SA
- * @return bool True if successfull
- */
-static bool
-netlink_add_sa(const struct kernel_sa *sa, bool replace)
-{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_info p;
- char data[1024];
- } req;
- struct rtattr *attr;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
-
- ip2xfrm(sa->src, &req.p.saddr);
- ip2xfrm(sa->dst, &req.p.id.daddr);
-
- req.p.id.spi = sa->spi;
- req.p.id.proto = satype2proto(sa->satype);
- req.p.family = sa->src->u.v4.sin_family;
- req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
- req.p.replay_window = sa->replay_window;
- req.p.reqid = sa->reqid;
- req.p.lft.soft_byte_limit = XFRM_INF;
- req.p.lft.soft_packet_limit = XFRM_INF;
- req.p.lft.hard_byte_limit = XFRM_INF;
- req.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
-
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
-
- if (sa->authalg)
- {
- struct xfrm_algo algo;
- const char *name;
-
- name = sparse_name(aalg_list, sa->authalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
- , sa->authalg);
- return FALSE;
- }
-
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
-
- attr->rta_type = XFRMA_ALG_AUTH;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
-
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
- , sa->authkeylen);
-
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
-
- if (sa->encalg)
- {
- struct xfrm_algo algo;
- const char *name;
-
- name = sparse_name(ealg_list, sa->encalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
- , sa->encalg);
- return FALSE;
- }
-
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
-
- attr->rta_type = XFRMA_ALG_CRYPT;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
-
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
- , sa->enckeylen);
-
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
-
- if (sa->compalg)
- {
- struct xfrm_algo algo;
- const char *name;
-
- name = sparse_name(calg_list, sa->compalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
- , sa->compalg);
- return FALSE;
- }
-
- strcpy(algo.alg_name, name);
- algo.alg_key_len = 0;
-
- attr->rta_type = XFRMA_ALG_COMP;
- attr->rta_len = RTA_LENGTH(sizeof(algo));
-
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
-
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
-
-#ifdef NAT_TRAVERSAL
- if (sa->natt_type)
- {
- struct xfrm_encap_tmpl natt;
-
- natt.encap_type = sa->natt_type;
- natt.encap_sport = ntohs(sa->natt_sport);
- natt.encap_dport = ntohs(sa->natt_dport);
- memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
-
- attr->rta_type = XFRMA_ENCAP;
- attr->rta_len = RTA_LENGTH(sizeof(natt));
-
- memcpy(RTA_DATA(attr), &natt, sizeof(natt));
-
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
-#endif
-
- return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
-}
-
-/** netlink_del_sa - Delete an SA from the Kernel
- *
- * @param sa Kernel SA to be deleted
- * @return bool True if successfull
- */
-static bool
-netlink_del_sa(const struct kernel_sa *sa)
-{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- char data[1024];
- } req;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = XFRM_MSG_DELSA;
-
- ip2xfrm(sa->dst, &req.id.daddr);
-
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
-
- return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
-}
-
-static bool
-netlink_error(const char *req_type, const struct nlmsghdr *n
-, const struct nlmsgerr *e, int rsp_size)
-{
- if (n->nlmsg_type == NLMSG_ERROR)
- {
- DBG(DBG_KLIPS,
- DBG_log("%s returned with errno %d: %s"
- , req_type
- , -e->error
- , strerror(-e->error))
- )
- return TRUE;
- }
- if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
- {
- plog("%s returned message with length %lu < %lu bytes"
- , req_type
- , (unsigned long) n->nlmsg_len
- , (unsigned long) rsp_size);
- return TRUE;
- }
- return FALSE;
-}
-
-static bool
-netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
-{
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
-
- req.id.sel.sport = portof(&sa->src_client->addr);
- req.id.sel.dport = portof(&sa->dst_client->addr);
- req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
- req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
- ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
- ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
- req.id.sel.prefixlen_s = sa->src_client->maskbits;
- req.id.sel.prefixlen_d = sa->dst_client->maskbits;
- req.id.sel.proto = sa->transport_proto;
- req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
-
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
-
- *use_time = (time_t)rsp.u.info.curlft.use_time;
-
- if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- time_t use_time_fwd;
-
- req.id.dir = XFRM_POLICY_FWD;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
-
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
-
- use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
- *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
- }
- return TRUE;
-}
-
-
-/** netlink_get_sa - Get information about an SA from the Kernel
- *
- * @param sa Kernel SA to be queried
- * @return bool True if successfull
- */
-static bool
-netlink_get_sa(const struct kernel_sa *sa, u_int *bytes)
-{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETSA;
-
- ip2xfrm(sa->dst, &req.id.daddr);
-
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
- return FALSE;
-
- if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
-
- *bytes = (u_int) rsp.u.info.curlft.bytes;
-
- return TRUE;
-}
-
-static void
-linux_pfkey_register_response(const struct sadb_msg *msg)
-{
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_ESP:
-#ifndef NO_KERNEL_ALG
- kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-#endif
- break;
- case SADB_X_SATYPE_IPCOMP:
- can_do_IPcomp = TRUE;
- break;
- default:
- break;
- }
-}
-
-/** linux_pfkey_register - Register via PFKEY our capabilities
- *
- */
-static void
-linux_pfkey_register(void)
-{
- pfkey_register_proto(SADB_SATYPE_AH, "AH");
- pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
- pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
- pfkey_close();
-}
-
-/** Create ip_address out of xfrm_address_t.
- *
- * @param family
- * @param src xfrm formatted IP address
- * @param dst ip_address formatted destination
- * @return err_t NULL if okay, otherwise an error
- */
-static err_t
-xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
-{
- switch (family)
- {
- case AF_INET: /* IPv4 */
- case AF_UNSPEC: /* Unspecified, we assume IPv4 */
- initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
- return NULL;
- case AF_INET6: /* IPv6 */
- initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
- return NULL;
- default:
- return "unknown address family";
- }
-}
-
-/* Create a pair of ip_address's out of xfrm_sel.
- *
- * @param sel xfrm selector
- * @param src ip_address formatted source
- * @param dst ip_address formatted destination
- * @return err_t NULL if okay, otherwise an error
- */
-static err_t
-xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
- , ip_address *src
- , ip_address *dst)
-{
- int family;
- err_t ugh;
-
- family = sel->family;
-
- if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
- || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
- return ugh;
-
- /* family has been verified in xfrm_to_ip_address. */
- if (family == AF_INET)
- {
- src->u.v4.sin_port = sel->sport;
- dst->u.v4.sin_port = sel->dport;
- }
- else
- {
- src->u.v6.sin6_port = sel->sport;
- dst->u.v6.sin6_port = sel->dport;
- }
-
- return NULL;
-}
-
-static void
-netlink_acquire(struct nlmsghdr *n)
-{
- struct xfrm_user_acquire *acquire;
- ip_address src, dst;
- ip_subnet ours, his;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
- {
- plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*acquire));
- return;
- }
-
- acquire = NLMSG_DATA(n);
- transport_proto = acquire->sel.proto;
-
- /* XXX also the type of src/dst should be checked to make sure
- * that they aren't v4 to v6 or something goofy
- */
-
- if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
- && !(ugh = addrtosubnet(&src, &ours))
- && !(ugh = addrtosubnet(&dst, &his)))
- record_and_initiate_opportunistic(&ours, &his, transport_proto
- , "%acquire-netlink");
-
- if (ugh != NULL)
- plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
-}
-
-static void
-netlink_shunt_expire(struct xfrm_userpolicy_info *pol)
-{
- ip_address src, dst;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- transport_proto = pol->sel.proto;
-
- if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
- {
- plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
- return;
- }
-
- replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
- , "delete expired bare shunt");
-}
-
-static void
-netlink_policy_expire(struct nlmsghdr *n)
-{
- struct xfrm_user_polexpire *upe;
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info pol;
- } u;
- char data[1024];
- } rsp;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
- {
- plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*upe));
- return;
- }
-
- upe = NLMSG_DATA(n);
- req.id.dir = upe->pol.dir;
- req.id.index = upe->pol.index;
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
-
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return;
-
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
- return;
-
- if (req.id.index != rsp.u.pol.index)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced: "
- "dir=%d, oldindex=%d, newindex=%d"
- , req.id.dir, req.id.index, rsp.u.pol.index));
- return;
- }
-
- if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced "
- " and you have won the lottery: "
- "dir=%d, index=%d"
- , req.id.dir, req.id.index));
- return;
- }
-
- switch (upe->pol.dir)
- {
- case XFRM_POLICY_OUT:
- netlink_shunt_expire(&rsp.u.pol);
- break;
- }
-}
-
-static bool
-netlink_get(void)
-{
- struct {
- struct nlmsghdr n;
- char data[1024];
- } rsp;
- ssize_t r;
- struct sockaddr_nl addr;
- socklen_t alen;
-
- alen = sizeof(addr);
- r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
- if (r < 0)
- {
- if (errno == EAGAIN)
- return FALSE;
- if (errno != EINTR)
- log_errno((e, "recvfrom() failed in netlink_get"));
- return TRUE;
- }
- else if ((size_t) r < sizeof(rsp.n))
- {
- plog("netlink_get read truncated message: %ld bytes; ignore message"
- , (long) r);
- return TRUE;
- }
- else if (addr.nl_pid != 0)
- {
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("netlink_get: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- return TRUE;
- }
- else if ((size_t) r != rsp.n.nlmsg_len)
- {
- plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
- , (long) r
- , (unsigned long) rsp.n.nlmsg_len);
- return TRUE;
- }
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get: %s message"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
-
- switch (rsp.n.nlmsg_type)
- {
- case XFRM_MSG_ACQUIRE:
- netlink_acquire(&rsp.n);
- break;
- case XFRM_MSG_POLEXPIRE:
- netlink_policy_expire(&rsp.n);
- break;
- default:
- /* ignored */
- break;
- }
-
- return TRUE;
-}
-
-static void
-netlink_process_msg(void)
-{
- while (netlink_get())
- ;
-}
-
-static ipsec_spi_t
-netlink_get_spi(const ip_address *src
-, const ip_address *dst
-, int proto
-, bool tunnel_mode
-, unsigned reqid
-, ipsec_spi_t min
-, ipsec_spi_t max
-, const char *text_said)
-{
- struct {
- struct nlmsghdr n;
- struct xfrm_userspi_info spi;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info sa;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
-
- ip2xfrm(src, &req.spi.info.saddr);
- ip2xfrm(dst, &req.spi.info.id.daddr);
- req.spi.info.mode = tunnel_mode;
- req.spi.info.reqid = reqid;
- req.spi.info.id.proto = proto;
- req.spi.info.family = src->u.v4.sin_family;
- req.spi.min = min;
- req.spi.max = max;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
- return 0;
-
- if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
- return 0;
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get_spi: allocated 0x%x for %s"
- , ntohl(rsp.u.sa.id.spi), text_said));
- return rsp.u.sa.id.spi;
-}
-
-const struct kernel_ops linux_kernel_ops = {
- type: KERNEL_TYPE_LINUX,
- inbound_eroute: 1,
- policy_lifetime: 1,
- async_fdp: &netlink_bcast_fd,
-
- init: init_netlink,
- pfkey_register: linux_pfkey_register,
- pfkey_register_response: linux_pfkey_register_response,
- process_msg: netlink_process_msg,
- raw_eroute: netlink_raw_eroute,
- get_policy: netlink_get_policy,
- add_sa: netlink_add_sa,
- del_sa: netlink_del_sa,
- get_sa: netlink_get_sa,
- process_queue: NULL,
- grp_sa: NULL,
- get_spi: netlink_get_spi,
-};
-#endif /* linux && KLIPS */
diff --git a/programs/pluto/kernel_netlink.h b/programs/pluto/kernel_netlink.h
deleted file mode 100644
index 1b5f42e48..000000000
--- a/programs/pluto/kernel_netlink.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* declarations of routines that interface with the kernel's pfkey mechanism
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- * Copyright (C) 2003 Herbert Xu
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_netlink.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#if defined(KLIPS) && defined(linux)
-extern const struct kernel_ops linux_kernel_ops;
-#endif
diff --git a/programs/pluto/kernel_noklips.c b/programs/pluto/kernel_noklips.c
deleted file mode 100644
index 570bb0470..000000000
--- a/programs/pluto/kernel_noklips.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* interface to fake kernel interface, used for testing pluto in-vitro.
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
- * Copyright (C) 2003 Herbert Xu.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_noklips.c,v 1.5 2006/02/04 00:01:22 as Exp $
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "kernel.h"
-#include "kernel_noklips.h"
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-void
-init_noklips(void)
-{
- return;
-}
-
-/* asynchronous messages from our queue */
-static void
-noklips_dequeue(void)
-{
-}
-
-/* asynchronous messages directly from PF_KEY socket */
-static void
-noklips_event(void)
-{
-}
-
-static void
-noklips_register_response(const struct sadb_msg *msg UNUSED)
-{
-}
-
-static void
-noklips_register(void)
-{
-}
-
-static bool
-noklips_raw_eroute(const ip_address *this_host UNUSED
- , const ip_subnet *this_client UNUSED
- , const ip_address *that_host UNUSED
- , const ip_subnet *that_client UNUSED
- , ipsec_spi_t spi UNUSED
- , unsigned int satype UNUSED
- , unsigned int transport_proto UNUSED
- , const struct pfkey_proto_info *proto_info UNUSED
- , time_t use_lifetime UNUSED
- , unsigned int op UNUSED
- , const char *text_said UNUSED)
-{
- return TRUE;
-}
-
-static bool
-noklips_add_sa(const struct kernel_sa *sa UNUSED
- , bool replace UNUSED)
-{
- return TRUE;
-}
-
-static bool
-noklips_grp_sa(const struct kernel_sa *sa0 UNUSED
- , const struct kernel_sa *sa1 UNUSED)
-{
- return TRUE;
-}
-
-static bool
-noklips_del_sa(const struct kernel_sa *sa UNUSED)
-{
- return TRUE;
-}
-
-
-const struct kernel_ops noklips_kernel_ops = {
- type: KERNEL_TYPE_NONE,
- async_fdp: NULL,
-
- init: init_noklips,
- pfkey_register: noklips_register,
- pfkey_register_response: noklips_register_response,
- process_queue: noklips_dequeue,
- process_msg: noklips_event,
- raw_eroute: noklips_raw_eroute,
- add_sa: noklips_add_sa,
- grp_sa: noklips_grp_sa,
- del_sa: noklips_del_sa,
- get_sa: NULL,
- get_spi: NULL,
- inbound_eroute: FALSE,
- policy_lifetime: FALSE
-};
diff --git a/programs/pluto/kernel_noklips.h b/programs/pluto/kernel_noklips.h
deleted file mode 100644
index fe4e77ec4..000000000
--- a/programs/pluto/kernel_noklips.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* declarations of routines that interface with the kernel's pfkey mechanism
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- * Copyright (C) 2003 Herbert Xu
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_noklips.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-extern void init_noklips(void);
-extern const struct kernel_ops noklips_kernel_ops;
diff --git a/programs/pluto/kernel_pfkey.c b/programs/pluto/kernel_pfkey.c
deleted file mode 100644
index 76bfbaf9a..000000000
--- a/programs/pluto/kernel_pfkey.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/* pfkey interface to the kernel's IPsec mechanism
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- * Copyright (C) 2003 Herbert Xu.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_pfkey.c,v 1.8 2006/02/04 00:01:22 as Exp $
- */
-
-#ifdef KLIPS
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "kernel.h"
-#include "kernel_pfkey.h"
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-#ifdef NAT_TRAVERSAL
-#include "demux.h"
-#include "nat_traversal.h"
-#endif
-
-#include "alg_info.h"
-#include "kernel_alg.h"
-
-
-static int pfkeyfd = NULL_FD;
-
-typedef u_int32_t pfkey_seq_t;
-static pfkey_seq_t pfkey_seq = 0; /* sequence number for our PF_KEY messages */
-
-static pid_t pid;
-
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
-
-static sparse_names pfkey_type_names = {
- NE(SADB_RESERVED),
- NE(SADB_GETSPI),
- NE(SADB_UPDATE),
- NE(SADB_ADD),
- NE(SADB_DELETE),
- NE(SADB_GET),
- NE(SADB_ACQUIRE),
- NE(SADB_REGISTER),
- NE(SADB_EXPIRE),
- NE(SADB_FLUSH),
- NE(SADB_DUMP),
- NE(SADB_X_PROMISC),
- NE(SADB_X_PCHANGE),
- NE(SADB_X_GRPSA),
- NE(SADB_X_ADDFLOW),
- NE(SADB_X_DELFLOW),
- NE(SADB_X_DEBUG),
-#ifdef NAT_TRAVERSAL
- NE(SADB_X_NAT_T_NEW_MAPPING),
-#endif
- NE(SADB_MAX),
- { 0, sparse_end }
-};
-
-#ifdef NEVER /* not needed yet */
-static sparse_names pfkey_ext_names = {
- NE(SADB_EXT_RESERVED),
- NE(SADB_EXT_SA),
- NE(SADB_EXT_LIFETIME_CURRENT),
- NE(SADB_EXT_LIFETIME_HARD),
- NE(SADB_EXT_LIFETIME_SOFT),
- NE(SADB_EXT_ADDRESS_SRC),
- NE(SADB_EXT_ADDRESS_DST),
- NE(SADB_EXT_ADDRESS_PROXY),
- NE(SADB_EXT_KEY_AUTH),
- NE(SADB_EXT_KEY_ENCRYPT),
- NE(SADB_EXT_IDENTITY_SRC),
- NE(SADB_EXT_IDENTITY_DST),
- NE(SADB_EXT_SENSITIVITY),
- NE(SADB_EXT_PROPOSAL),
- NE(SADB_EXT_SUPPORTED_AUTH),
- NE(SADB_EXT_SUPPORTED_ENCRYPT),
- NE(SADB_EXT_SPIRANGE),
- NE(SADB_X_EXT_KMPRIVATE),
- NE(SADB_X_EXT_SATYPE2),
- NE(SADB_X_EXT_SA2),
- NE(SADB_X_EXT_ADDRESS_DST2),
- NE(SADB_X_EXT_ADDRESS_SRC_FLOW),
- NE(SADB_X_EXT_ADDRESS_DST_FLOW),
- NE(SADB_X_EXT_ADDRESS_SRC_MASK),
- NE(SADB_X_EXT_ADDRESS_DST_MASK),
- NE(SADB_X_EXT_DEBUG),
- { 0, sparse_end }
-};
-#endif /* NEVER */
-
-#undef NE
-
-void
-init_pfkey(void)
-{
- pid = getpid();
-
- /* open PF_KEY socket */
-
- pfkeyfd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
-
- if (pfkeyfd == -1)
- exit_log_errno((e, "socket() in init_pfkeyfd()"));
-
-#ifdef NEVER /* apparently unsupported! */
- if (fcntl(pfkeyfd, F_SETFL, O_NONBLOCK) != 0)
- exit_log_errno((e, "fcntl(O_NONBLOCK) in init_pfkeyfd()"));
-#endif
- if (fcntl(pfkeyfd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_pfkeyfd()"));
-
- DBG(DBG_KLIPS,
- DBG_log("process %u listening for PF_KEY_V2 on file descriptor %d", (unsigned)pid, pfkeyfd));
-}
-
-/* Kinds of PF_KEY message from the kernel:
- * - response to a request from us
- * + ACK/NAK
- * + Register: indicates transforms supported by kernel
- * + SPI requested by getspi
- * - Acquire, requesting us to deal with trapped clear packet
- * - expiration of of one of our SAs
- * - messages to other processes
- *
- * To minimize the effect on the event-driven structure of Pluto,
- * responses are dealt with synchronously. We hope that the Kernel
- * produces them synchronously. We must "read ahead" in the PF_KEY
- * stream, saving Acquire and Expiry messages that are encountered.
- * We ignore messages to other processes.
- */
-
-typedef union {
- unsigned char bytes[PFKEYv2_MAX_MSGSIZE];
- struct sadb_msg msg;
- } pfkey_buf;
-
-/* queue of unprocessed PF_KEY messages input from kernel
- * Note that the pfkey_buf may be partly allocated, reflecting
- * the variable length nature of the messages. So the link field
- * must come first.
- */
-typedef struct pfkey_item {
- struct pfkey_item *next;
- pfkey_buf buf;
- } pfkey_item;
-
-static pfkey_item *pfkey_iq_head = NULL; /* oldest */
-static pfkey_item *pfkey_iq_tail; /* youngest */
-
-static bool
-pfkey_input_ready(void)
-{
- fd_set readfds;
- int ndes;
- struct timeval tm;
-
- tm.tv_sec = 0; /* don't wait at all */
- tm.tv_usec = 0;
-
- FD_ZERO(&readfds); /* we only care about pfkeyfd */
- FD_SET(pfkeyfd, &readfds);
-
- do {
- ndes = select(pfkeyfd + 1, &readfds, NULL, NULL, &tm);
- } while (ndes == -1 && errno == EINTR);
-
- if (ndes < 0)
- {
- log_errno((e, "select() failed in pfkey_get()"));
- return FALSE;
- }
-
- if (ndes == 0)
- return FALSE; /* nothing to read */
-
- passert(ndes == 1 && FD_ISSET(pfkeyfd, &readfds));
- return TRUE;
-}
-
-/* get a PF_KEY message from kernel.
- * Returns TRUE is message found, FALSE if no message pending,
- * and aborts or keeps trying when an error is encountered.
- * The only validation of the message is that the message length
- * received matches that in the message header, and that the message
- * is for this process.
- */
-static bool
-pfkey_get(pfkey_buf *buf)
-{
- for (;;)
- {
- /* len must be less than PFKEYv2_MAX_MSGSIZE,
- * so it should fit in an int. We use this fact when printing it.
- */
- ssize_t len;
-
- if (!pfkey_input_ready())
- return FALSE;
-
- len = read(pfkeyfd, buf->bytes, sizeof(buf->bytes));
-
- if (len < 0)
- {
- if (errno == EAGAIN)
- return FALSE;
-
- log_errno((e, "read() failed in pfkey_get()"));
- return FALSE;
- }
- else if ((size_t) len < sizeof(buf->msg))
- {
- plog("pfkey_get read truncated PF_KEY message: %d bytes; ignoring message"
- , (int) len);
- }
- else if ((size_t) len != buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN)
- {
- plog("pfkey_get read PF_KEY message with length %d that doesn't equal sadb_msg_len %u * %u; ignoring message"
- , (int) len
- , (unsigned) buf->msg.sadb_msg_len
- , (unsigned) IPSEC_PFKEYv2_ALIGN);
- }
- else if (!(buf->msg.sadb_msg_pid == (unsigned)pid
- || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_ACQUIRE)
- || (buf->msg.sadb_msg_type == SADB_REGISTER)
-#ifdef NAT_TRAVERSAL
- || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING)
-#endif
- ))
- {
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("pfkey_get: ignoring PF_KEY %s message %u for process %u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid));
- }
- else
- {
- DBG(DBG_KLIPS,
- DBG_log("pfkey_get: %s message %u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_seq));
- return TRUE;
- }
- }
-}
-
-/* get a response to a specific message */
-static bool
-pfkey_get_response(pfkey_buf *buf, pfkey_seq_t seq)
-{
- while (pfkey_get(buf))
- {
- if (buf->msg.sadb_msg_pid == (unsigned)pid
- && buf->msg.sadb_msg_seq == seq)
- {
- return TRUE;
- }
- else
- {
- /* Not for us: queue it. */
- size_t bl = buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
- pfkey_item *it = alloc_bytes(offsetof(pfkey_item, buf) + bl, "pfkey_item");
-
- memcpy(&it->buf, buf, bl);
-
- it->next = NULL;
- if (pfkey_iq_head == NULL)
- {
- pfkey_iq_head = it;
- }
- else
- {
- pfkey_iq_tail->next = it;
- }
- pfkey_iq_tail = it;
- }
- }
- return FALSE;
-}
-
-/* Process a SADB_REGISTER message from the kernel.
- * This will be a response to one of ours, but it may be asynchronous
- * (if kernel modules are loaded and unloaded).
- * Some sanity checking has already been performed.
- */
-static void
-klips_pfkey_register_response(const struct sadb_msg *msg)
-{
- /* Find out what the kernel can support.
- * In fact, the only question at the moment
- * is whether it can support IPcomp.
- * So we ignore the rest.
- * ??? we really should pay attention to what transforms are supported.
- */
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_AH:
- break;
- case SADB_SATYPE_ESP:
-#ifndef NO_KERNEL_ALG
- kernel_alg_register_pfkey(msg, sizeof (pfkey_buf));
-#endif
- break;
- case SADB_X_SATYPE_COMP:
- /* ??? There ought to be an extension to list the
- * supported algorithms, but RFC 2367 doesn't
- * list one for IPcomp. KLIPS uses SADB_X_CALG_DEFLATE.
- * Since we only implement deflate, we'll assume this.
- */
- can_do_IPcomp = TRUE;
- break;
- case SADB_X_SATYPE_IPIP:
- break;
- default:
- break;
- }
-}
-
-/* Processs a SADB_ACQUIRE message from KLIPS.
- * Try to build an opportunistic connection!
- * See RFC 2367 "PF_KEY Key Management API, Version 2" 3.1.6
- * <base, address(SD), (address(P)), (identity(SD),) (sensitivity,) proposal>
- * - extensions for source and data IP addresses
- * - optional extensions for identity [not useful for us?]
- * - optional extension for sensitivity [not useful for us?]
- * - expension for proposal [not useful for us?]
- *
- * ??? We must use the sequence number in creating an SA.
- * We actually need to create up to 4 SAs each way. Which one?
- * I guess it depends on the protocol present in the sadb_msg_satype.
- * For now, we'll ignore this requirement.
- *
- * ??? We need some mechanism to make sure that multiple ACQUIRE messages
- * don't cause a whole bunch of redundant negotiations.
- */
-static void
-process_pfkey_acquire(pfkey_buf *buf, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
- struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
- int src_proto = srcx->sadb_address_proto;
- int dst_proto = dstx->sadb_address_proto;
- ip_address *src = (ip_address*)&srcx[1];
- ip_address *dst = (ip_address*)&dstx[1];
- ip_subnet ours, his;
- err_t ugh = NULL;
-
- /* assumption: we're only catching our own outgoing packets
- * so source is our end and destination is the other end.
- * Verifying this is not actually convenient.
- *
- * This stylized control structure yields a complaint or
- * desired results. For compactness, a pointer value is
- * treated as a boolean. Logically, the structure is:
- * keep going as long as things are OK.
- */
- if (buf->msg.sadb_msg_pid == 0 /* we only wish to hear from kernel */
- && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ")
- && !(ugh = addrtypeof(src) == addrtypeof(dst)? NULL : "conflicting address types")
- && !(ugh = addrtosubnet(src, &ours))
- && !(ugh = addrtosubnet(dst, &his)))
- record_and_initiate_opportunistic(&ours, &his, src_proto, "%acquire");
-
- if (ugh != NULL)
- plog("SADB_ACQUIRE message from KLIPS malformed: %s", ugh);
-
-}
-
-/* Handle PF_KEY messages from the kernel that are not dealt with
- * synchronously. In other words, all but responses to PF_KEY messages
- * that we sent.
- */
-static void
-pfkey_async(pfkey_buf *buf)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- if (pfkey_msg_parse(&buf->msg, NULL, extensions, EXT_BITS_OUT))
- {
- plog("pfkey_async:"
- " unparseable PF_KEY message:"
- " %s len=%d, errno=%d, seq=%d, pid=%d; message ignored"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_len
- , buf->msg.sadb_msg_errno
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid);
- }
- else
- {
- DBG(DBG_CONTROL | DBG_KLIPS, DBG_log("pfkey_async:"
- " %s len=%u, errno=%u, satype=%u, seq=%u, pid=%u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_len
- , buf->msg.sadb_msg_errno
- , buf->msg.sadb_msg_satype
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid));
-
- switch (buf->msg.sadb_msg_type)
- {
- case SADB_REGISTER:
- kernel_ops->pfkey_register_response(&buf->msg);
- break;
- case SADB_ACQUIRE:
- /* to simulate loss of ACQUIRE, delete this call */
- process_pfkey_acquire(buf, extensions);
- break;
-#ifdef NAT_TRAVERSAL
- case SADB_X_NAT_T_NEW_MAPPING:
- process_pfkey_nat_t_new_mapping(&(buf->msg), extensions);
- break;
-#endif
- default:
- /* ignored */
- break;
- }
- }
-}
-
-/* asynchronous messages from our queue */
-static void
-pfkey_dequeue(void)
-{
- while (pfkey_iq_head != NULL)
- {
- pfkey_item *it = pfkey_iq_head;
-
- pfkey_async(&it->buf);
- pfkey_iq_head = it->next;
- pfree(it);
- }
-
- /* Handle any orphaned holds, but only if no pfkey input is pending.
- * For each, we initiate Opportunistic.
- * note: we don't need to advance the pointer because
- * record_and_initiate_opportunistic will remove the current
- * record each time we call it.
- */
- while (orphaned_holds != NULL && !pfkey_input_ready())
- record_and_initiate_opportunistic(&orphaned_holds->ours
- , &orphaned_holds->his
- , orphaned_holds->transport_proto
- , "%hold found-pfkey");
-
-}
-
-/* asynchronous messages directly from PF_KEY socket */
-static void
-pfkey_event(void)
-{
- pfkey_buf buf;
-
- if (pfkey_get(&buf))
- pfkey_async(&buf);
-}
-
-static bool
-pfkey_build(int error
-, const char *description
-, const char *text_said
-, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- if (error == 0)
- {
- return TRUE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "building of %s %s failed, code %d"
- , description, text_said, error);
- pfkey_extensions_free(extensions);
- return FALSE;
- }
-}
-
-/* pfkey_extensions_init + pfkey_build + pfkey_msg_hdr_build */
-static bool
-pfkey_msg_start(u_int8_t msg_type
-, u_int8_t satype
-, const char *description
-, const char *text_said
-, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- pfkey_extensions_init(extensions);
- return pfkey_build(pfkey_msg_hdr_build(&extensions[0], msg_type
- , satype, 0, ++pfkey_seq, pid)
- , description, text_said, extensions);
-}
-
-/* pfkey_build + pfkey_address_build */
-static bool
-pfkeyext_address(u_int16_t exttype
-, const ip_address *address
-, const char *description
-, const char *text_said
-, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- /* the following variable is only needed to silence
- * a warning caused by the fact that the argument
- * to sockaddrof is NOT pointer to const!
- */
- ip_address t = *address;
-
- return pfkey_build(pfkey_address_build(extensions + exttype
- , exttype, 0, 0, sockaddrof(&t))
- , description, text_said, extensions);
-}
-
-/* pfkey_build + pfkey_x_protocol_build */
-static bool
-pfkeyext_protocol(int transport_proto
-, const char *description
-, const char *text_said
-, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- return (transport_proto == 0)? TRUE
- : pfkey_build(
- pfkey_x_protocol_build(extensions + SADB_X_EXT_PROTOCOL, transport_proto)
- , description, text_said, extensions);
-}
-
-
-/* Finish (building, sending, accepting response for) PF_KEY message.
- * If response isn't NULL, the response from the kernel will be
- * placed there (and its errno field will not be examined).
- * Returns TRUE iff all appears well.
- */
-static bool
-finish_pfkey_msg(struct sadb_ext *extensions[SADB_EXT_MAX + 1]
-, const char *description
-, const char *text_said
-, pfkey_buf *response)
-{
- struct sadb_msg *pfkey_msg;
- bool success = TRUE;
- int error;
-
- error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
-
- if (error != 0)
- {
- loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d"
- , description, text_said, error);
- success = FALSE;
- }
- else
- {
- size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
-
- DBG(DBG_KLIPS,
- DBG_log("finish_pfkey_msg: %s message %u for %s %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said);
- DBG_dump(NULL, (void *) pfkey_msg, len));
-
- if (!no_klips)
- {
- ssize_t r = write(pfkeyfd, pfkey_msg, len);
-
- if (r != (ssize_t)len)
- {
- if (r < 0)
- {
- log_errno((e
- , "pfkey write() of %s message %u"
- " for %s %s failed"
- , sparse_val_show(pfkey_type_names
- , pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said));
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: pfkey write() of %s message %u"
- " for %s %s truncated: %ld instead of %ld"
- , sparse_val_show(pfkey_type_names
- , pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said
- , (long)r, (long)len);
- }
- success = FALSE;
-
- /* if we were compiled with debugging, but we haven't already
- * dumped the KLIPS command, do so.
- */
-#ifdef DEBUG
- if ((cur_debugging & DBG_KLIPS) == 0)
- DBG_dump(NULL, (void *) pfkey_msg, len);
-#endif
- }
- else
- {
- /* Check response from KLIPS.
- * It ought to be an echo, perhaps with additional info.
- * If the caller wants it, response will point to space.
- */
- pfkey_buf b;
- pfkey_buf *bp = response != NULL? response : &b;
-
- if (!pfkey_get_response(bp, ((struct sadb_msg *) extensions[0])->sadb_msg_seq))
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: no response to our PF_KEY %s message for %s %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said);
- success = FALSE;
- }
- else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type)
- {
- loglog(RC_LOG_SERIOUS
- , "FreeS/WAN ERROR: response to our PF_KEY %s message for %s %s was of wrong type (%s)"
- , sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said
- , sparse_val_show(pfkey_type_names, bp->msg.sadb_msg_type));
- success = FALSE;
- }
- else if (response == NULL && bp->msg.sadb_msg_errno != 0)
- {
- /* KLIPS is signalling a problem */
- loglog(RC_LOG_SERIOUS
- , "ERROR: PF_KEY %s response for %s %s included errno %u: %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said
- , (unsigned) bp->msg.sadb_msg_errno
- , strerror(bp->msg.sadb_msg_errno));
- success = FALSE;
- }
- }
- }
- }
-
- /* all paths must exit this way to free resources */
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- return success;
-}
-
-/* register SA types that can be negotiated */
-void
-pfkey_register_proto(unsigned satype, const char *satypename)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- pfkey_buf pfb;
-
- if (!(pfkey_msg_start(SADB_REGISTER
- , satype
- , satypename, NULL, extensions)
- && finish_pfkey_msg(extensions, satypename, "", &pfb)))
- {
- /* ??? should this be loglog */
- plog("no KLIPS support for %s", satypename);
- }
- else
- {
- kernel_ops->pfkey_register_response(&pfb.msg);
- DBG(DBG_KLIPS,
- DBG_log("%s registered with kernel.", satypename));
- }
-}
-
-static void
-klips_pfkey_register(void)
-{
- pfkey_register_proto(SADB_SATYPE_AH, "AH");
- pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
- can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
- pfkey_register_proto(SADB_X_SATYPE_COMP, "IPCOMP");
- pfkey_register_proto(SADB_X_SATYPE_IPIP, "IPIP");
-}
-
-static bool
-pfkey_raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info UNUSED
- , time_t use_lifetime UNUSED
- , unsigned int op
- , const char *text_said)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- ip_address
- sflow_ska,
- dflow_ska,
- smask_ska,
- dmask_ska;
- int sport = ntohs(portof(&this_client->addr));
- int dport = ntohs(portof(&that_client->addr));
-
- networkof(this_client, &sflow_ska);
- maskof(this_client, &smask_ska);
- setportof(sport ? ~0:0, &smask_ska);
-
- networkof(that_client, &dflow_ska);
- maskof(that_client, &dmask_ska);
- setportof(dport ? ~0:0, &dmask_ska);
-
- if (!pfkey_msg_start(op & ERO_MASK, satype
- , "pfkey_msg_hdr flow", text_said, extensions))
- {
- return FALSE;
- }
-
- if (op != ERO_DELETE)
- {
- if (!(pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , spi /* in network order */
- , 0, 0, 0, 0, op >> ERO_FLAG_SHIFT)
- , "pfkey_sa add flow", text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, this_host
- , "pfkey_addr_s add flow", text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, that_host
- , "pfkey_addr_d add flow", text_said
- , extensions)))
- {
- return FALSE;
- }
- }
-
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_FLOW, &sflow_ska
- , "pfkey_addr_sflow", text_said, extensions))
- {
- return FALSE;
- }
-
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_FLOW, &dflow_ska
- , "pfkey_addr_dflow", text_said, extensions))
- {
- return FALSE;
- }
-
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_MASK, &smask_ska
- , "pfkey_addr_smask", text_said, extensions))
- {
- return FALSE;
- }
-
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_MASK, &dmask_ska
- , "pfkey_addr_dmask", text_said, extensions))
- {
- return FALSE;
- }
-
- if (!pfkeyext_protocol(transport_proto
- , "pfkey_x_protocol", text_said, extensions))
- {
- return FALSE;
- }
-
- return finish_pfkey_msg(extensions, "flow", text_said, NULL);
-}
-
-static bool
-pfkey_add_sa(const struct kernel_sa *sa, bool replace)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- return pfkey_msg_start(replace ? SADB_UPDATE : SADB_ADD, sa->satype
- , "pfkey_msg_hdr Add SA", sa->text_said, extensions)
-
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa->spi /* in network order */
- , sa->replay_window, SADB_SASTATE_MATURE
- , sa->authalg, sa->encalg ? sa->encalg: sa->compalg, 0)
- , "pfkey_sa Add SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
- , "pfkey_addr_s Add SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
- , "pfkey_addr_d Add SA", sa->text_said, extensions)
-
- && (sa->authkeylen == 0
- || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_AUTH]
- , SADB_EXT_KEY_AUTH, sa->authkeylen * BITS_PER_BYTE
- , sa->authkey)
- , "pfkey_key_a Add SA", sa->text_said, extensions))
-
- && (sa->enckeylen == 0
- || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_ENCRYPT]
- , SADB_EXT_KEY_ENCRYPT, sa->enckeylen * BITS_PER_BYTE
- , sa->enckey)
- , "pfkey_key_e Add SA", sa->text_said, extensions))
-
-#ifdef NAT_TRAVERSAL
- && (sa->natt_type == 0
- || pfkey_build(pfkey_x_nat_t_type_build(
- &extensions[SADB_X_EXT_NAT_T_TYPE], sa->natt_type),
- "pfkey_nat_t_type Add ESP SA", sa->text_said, extensions))
- && (sa->natt_sport == 0
- || pfkey_build(pfkey_x_nat_t_port_build(
- &extensions[SADB_X_EXT_NAT_T_SPORT], SADB_X_EXT_NAT_T_SPORT,
- sa->natt_sport), "pfkey_nat_t_sport Add ESP SA", sa->text_said,
- extensions))
- && (sa->natt_dport == 0
- || pfkey_build(pfkey_x_nat_t_port_build(
- &extensions[SADB_X_EXT_NAT_T_DPORT], SADB_X_EXT_NAT_T_DPORT,
- sa->natt_dport), "pfkey_nat_t_dport Add ESP SA", sa->text_said,
- extensions))
- && (sa->natt_type == 0 || isanyaddr(sa->natt_oa)
- || pfkeyext_address(SADB_X_EXT_NAT_T_OA, sa->natt_oa
- , "pfkey_nat_t_oa Add ESP SA", sa->text_said, extensions))
-#endif
-
- && finish_pfkey_msg(extensions, "Add SA", sa->text_said, NULL);
-
-}
-
-static bool
-pfkey_grp_sa(const struct kernel_sa *sa0, const struct kernel_sa *sa1)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- return pfkey_msg_start(SADB_X_GRPSA, sa1->satype
- , "pfkey_msg_hdr group", sa1->text_said, extensions)
-
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa1->spi /* in network order */
- , 0, 0, 0, 0, 0)
- , "pfkey_sa group", sa1->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa1->dst
- , "pfkey_addr_d group", sa1->text_said, extensions)
-
- && pfkey_build(pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2]
- , sa0->satype)
- , "pfkey_satype group", sa0->text_said, extensions)
-
- && pfkey_build(pfkey_sa_build(&extensions[SADB_X_EXT_SA2]
- , SADB_X_EXT_SA2
- , sa0->spi /* in network order */
- , 0, 0, 0, 0, 0)
- , "pfkey_sa2 group", sa0->text_said, extensions)
-
- && pfkeyext_address(SADB_X_EXT_ADDRESS_DST2, sa0->dst
- , "pfkey_addr_d2 group", sa0->text_said, extensions)
-
- && finish_pfkey_msg(extensions, "group", sa1->text_said, NULL);
-}
-
-static bool
-pfkey_del_sa(const struct kernel_sa *sa)
-{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- return pfkey_msg_start(SADB_DELETE, proto2satype(sa->proto)
- , "pfkey_msg_hdr delete SA", sa->text_said, extensions)
-
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa->spi /* in host order */
- , 0, SADB_SASTATE_MATURE, 0, 0, 0)
- , "pfkey_sa delete SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
- , "pfkey_addr_s delete SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
- , "pfkey_addr_d delete SA", sa->text_said, extensions)
-
- && finish_pfkey_msg(extensions, "Delete SA", sa->text_said, NULL);
-}
-
-void
-pfkey_close(void)
-{
- while (pfkey_iq_head != NULL)
- {
- pfkey_item *it = pfkey_iq_head;
-
- pfkey_iq_head = it->next;
- pfree(it);
- }
-
- close(pfkeyfd);
- pfkeyfd = NULL_FD;
-}
-
-const struct kernel_ops klips_kernel_ops = {
- type: KERNEL_TYPE_KLIPS,
- async_fdp: &pfkeyfd,
-
- pfkey_register: klips_pfkey_register,
- pfkey_register_response: klips_pfkey_register_response,
- process_queue: pfkey_dequeue,
- process_msg: pfkey_event,
- raw_eroute: pfkey_raw_eroute,
- add_sa: pfkey_add_sa,
- grp_sa: pfkey_grp_sa,
- del_sa: pfkey_del_sa,
- get_sa: NULL,
- get_spi: NULL,
- inbound_eroute: FALSE,
- policy_lifetime: FALSE,
- init: NULL
-};
-#endif /* KLIPS */
diff --git a/programs/pluto/kernel_pfkey.h b/programs/pluto/kernel_pfkey.h
deleted file mode 100644
index 9dbcdd341..000000000
--- a/programs/pluto/kernel_pfkey.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* declarations of routines that interface with the kernel's pfkey mechanism
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- * Copyright (C) 2003 Herbert Xu
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: kernel_pfkey.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#ifdef KLIPS
-extern void init_pfkey(void);
-extern void pfkey_register_proto(unsigned satype, const char *satypename);
-extern void pfkey_close(void);
-extern const struct kernel_ops klips_kernel_ops;
-#endif
diff --git a/programs/pluto/keys.c b/programs/pluto/keys.c
deleted file mode 100644
index 39726f424..000000000
--- a/programs/pluto/keys.c
+++ /dev/null
@@ -1,1516 +0,0 @@
-/* mechanisms for preshared keys (public, private, and preshared secrets)
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: keys.c,v 1.26 2007/01/10 00:36:19 as Exp $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <glob.h>
-#ifndef GLOB_ABORTED
-# define GLOB_ABORTED GLOB_ABEND /* fix for old versions */
-#endif
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "id.h"
-#include "x509.h"
-#include "pgp.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "state.h"
-#include "lex.h"
-#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-#include "timer.h"
-#include "fetch.h"
-#include "xauth.h"
-
-const char *shared_secrets_file = SHARED_SECRETS_FILE;
-
-typedef struct id_list id_list_t;
-
-struct id_list {
- struct id id;
- id_list_t *next;
-};
-
-typedef struct secret secret_t;
-
-struct secret {
- id_list_t *ids;
- enum PrivateKeyKind kind;
- union {
- chunk_t preshared_secret;
- RSA_private_key_t RSA_private_key;
- xauth_t xauth_secret;
- smartcard_t *smartcard;
- } u;
- secret_t *next;
-};
-
-static pubkey_t*
-allocate_RSA_public_key(const cert_t cert)
-{
- pubkey_t *pk = alloc_thing(pubkey_t, "pubkey");
- chunk_t e, n;
-
- switch (cert.type)
- {
- case CERT_PGP:
- e = cert.u.pgp->publicExponent;
- n = cert.u.pgp->modulus;
- break;
- case CERT_X509_SIGNATURE:
- e = cert.u.x509->publicExponent;
- n = cert.u.x509->modulus;
- break;
- default:
- plog("RSA public key allocation error");
- }
-
- init_RSA_public_key(&pk->u.rsa, e, n);
- DBG(DBG_RAW,
- RSA_show_public_key(&pk->u.rsa)
- )
-
- pk->alg = PUBKEY_ALG_RSA;
- pk->id = empty_id;
- pk->issuer = empty_chunk;
- pk->serial = empty_chunk;
-
- return pk;
-}
-
-/*
- * free a public key struct
- */
-static void
-free_public_key(pubkey_t *pk)
-{
- free_id_content(&pk->id);
- freeanychunk(pk->issuer);
- freeanychunk(pk->serial);
-
- /* algorithm-specific freeing */
- switch (pk->alg)
- {
- case PUBKEY_ALG_RSA:
- free_RSA_public_content(&pk->u.rsa);
- break;
- default:
- bad_case(pk->alg);
- }
- pfree(pk);
-}
-
-secret_t *secrets = NULL;
-
-/* find the struct secret associated with the combination of
- * me and the peer. We match the Id (if none, the IP address).
- * Failure is indicated by a NULL.
- */
-static const secret_t *
-get_secret(const struct connection *c, enum PrivateKeyKind kind, bool asym)
-{
- enum { /* bits */
- match_default = 01,
- match_him = 02,
- match_me = 04
- };
-
- unsigned int best_match = 0;
- secret_t *best = NULL;
- secret_t *s;
- const struct id *my_id = &c->spd.this.id
- , *his_id = &c->spd.that.id;
- struct id rw_id;
-
- /* is there a certificate assigned to this connection? */
- if (kind == PPK_RSA && c->spd.this.cert.type != CERT_NONE)
- {
- pubkey_t *my_public_key = allocate_RSA_public_key(c->spd.this.cert);
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == kind &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &my_public_key->u.rsa))
- {
- best = s;
- break; /* we have found the private key - no sense in searching further */
- }
- }
- free_public_key(my_public_key);
- return best;
- }
-
- if (his_id_was_instantiated(c))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- rw_id.kind = c->spd.that.id.kind;
- rw_id.name = empty_chunk;
- happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
- his_id = &rw_id;
- }
-#ifdef NAT_TRAVERSAL
- else if (kind == PPK_PSK
- && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK))
- && ((c->kind == CK_TEMPLATE && c->spd.that.id.kind == ID_NONE) ||
- (c->kind == CK_INSTANCE && id_is_ipaddr(&c->spd.that.id))))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- rw_id.kind = ID_IPV4_ADDR;
- happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
- his_id = &rw_id;
- }
-#endif
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == kind)
- {
- unsigned int match = 0;
-
- if (s->ids == NULL)
- {
- /* a default (signified by lack of ids):
- * accept if no more specific match found
- */
- match = match_default;
- }
- else
- {
- /* check if both ends match ids */
- id_list_t *i;
-
- for (i = s->ids; i != NULL; i = i->next)
- {
- if (same_id(my_id, &i->id))
- match |= match_me;
-
- if (same_id(his_id, &i->id))
- match |= match_him;
- }
-
- /* If our end matched the only id in the list,
- * default to matching any peer.
- * A more specific match will trump this.
- */
- if (match == match_me
- && s->ids->next == NULL)
- match |= match_default;
- }
-
- switch (match)
- {
- case match_me:
- /* if this is an asymmetric (eg. public key) system,
- * allow this-side-only match to count, even if
- * there are other ids in the list.
- */
- if (!asym)
- break;
- /* FALLTHROUGH */
- case match_default: /* default all */
- case match_me | match_default: /* default peer */
- case match_me | match_him: /* explicit */
- if (match == best_match)
- {
- /* two good matches are equally good:
- * do they agree?
- */
- bool same = FALSE;
-
- switch (kind)
- {
- case PPK_PSK:
- same = s->u.preshared_secret.len == best->u.preshared_secret.len
- && memcmp(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len) == 0;
- break;
- case PPK_RSA:
- /* Dirty trick: since we have code to compare
- * RSA public keys, but not private keys, we
- * make the assumption that equal public keys
- * mean equal private keys. This ought to work.
- */
- same = same_RSA_public_key(&s->u.RSA_private_key.pub
- , &best->u.RSA_private_key.pub);
- break;
- default:
- bad_case(kind);
- }
- if (!same)
- {
- loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with distinct secrets match endpoints:"
- " first secret used");
- best = s; /* list is backwards: take latest in list */
- }
- }
- else if (match > best_match)
- {
- /* this is the best match so far */
- best_match = match;
- best = s;
- }
- }
- }
- }
- return best;
-}
-
-/* find the appropriate preshared key (see get_secret).
- * Failure is indicated by a NULL pointer.
- * Note: the result is not to be freed by the caller.
- */
-const chunk_t *
-get_preshared_secret(const struct connection *c)
-{
- const secret_t *s = get_secret(c, PPK_PSK, FALSE);
-
- DBG(DBG_PRIVATE,
- if (s == NULL)
- DBG_log("no Preshared Key Found");
- else
- DBG_dump_chunk("Preshared Key", s->u.preshared_secret);
- )
- return s == NULL? NULL : &s->u.preshared_secret;
-}
-
-/* check the existence of an RSA private key matching an RSA public
- * key contained in an X.509 or OpenPGP certificate
- */
-bool
-has_private_key(cert_t cert)
-{
- secret_t *s;
- bool has_key = FALSE;
- pubkey_t *pubkey = allocate_RSA_public_key(cert);
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_RSA &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &pubkey->u.rsa))
- {
- has_key = TRUE;
- break;
- }
- }
- free_public_key(pubkey);
- return has_key;
-}
-
-/*
- * get the matching RSA private key belonging to a given X.509 certificate
- */
-const RSA_private_key_t*
-get_x509_private_key(const x509cert_t *cert)
-{
- secret_t *s;
- const RSA_private_key_t *pri = NULL;
- const cert_t c = {CERT_X509_SIGNATURE, {cert}};
-
- pubkey_t *pubkey = allocate_RSA_public_key(c);
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_RSA &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &pubkey->u.rsa))
- {
- pri = &s->u.RSA_private_key;
- break;
- }
- }
- free_public_key(pubkey);
- return pri;
-}
-
-/* find the appropriate RSA private key (see get_secret).
- * Failure is indicated by a NULL pointer.
- */
-const RSA_private_key_t *
-get_RSA_private_key(const struct connection *c)
-{
- const secret_t *s = get_secret(c, PPK_RSA, TRUE);
-
- return s == NULL? NULL : &s->u.RSA_private_key;
-}
-
-/* digest a secrets file
- *
- * The file is a sequence of records. A record is a maximal sequence of
- * tokens such that the first, and only the first, is in the first column
- * of a line.
- *
- * Tokens are generally separated by whitespace and are key words, ids,
- * strings, or data suitable for ttodata(3). As a nod to convention,
- * a trailing ":" on what would otherwise be a token is taken as a
- * separate token. If preceded by whitespace, a "#" is taken as starting
- * a comment: it and the rest of the line are ignored.
- *
- * One kind of record is an include directive. It starts with "include".
- * The filename is the only other token in the record.
- * If the filename does not start with /, it is taken to
- * be relative to the directory containing the current file.
- *
- * The other kind of record describes a key. It starts with a
- * sequence of ids and ends with key information. Each id
- * is an IP address, a Fully Qualified Domain Name (which will immediately
- * be resolved), or @FQDN which will be left as a name.
- *
- * The key part can be in several forms.
- *
- * The old form of the key is still supported: a simple
- * quoted strings (with no escapes) is taken as a preshred key.
- *
- * The new form starts the key part with a ":".
- *
- * For Preshared Key, use the "PSK" keyword, and follow it by a string
- * or a data token suitable for ttodata(3).
- *
- * For RSA Private Key, use the "RSA" keyword, followed by a
- * brace-enclosed list of key field keywords and data values.
- * The data values are large integers to be decoded by ttodata(3).
- * The fields are a subset of those used by BIND 8.2 and have the
- * same names.
- */
-
-/* parse PSK from file */
-static err_t
-process_psk_secret(chunk_t *psk)
-{
- err_t ugh = NULL;
-
- if (*tok == '"' || *tok == '\'')
- {
- clonetochunk(*psk, tok+1, flp->cur - tok - 2, "PSK");
- (void) shift();
- }
- else
- {
- char buf[BUF_LEN]; /* limit on size of binary representation of key */
- size_t sz;
-
- ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
- , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
- if (ugh != NULL)
- {
- /* ttodata didn't like PSK data */
- ugh = builddiag("PSK data malformed (%s): %s", ugh, tok);
- }
- else
- {
- clonetochunk(*psk, buf, sz, "PSK");
- (void) shift();
- }
- }
- return ugh;
-}
-
-/* Parse fields of RSA private key.
- * A braced list of keyword and value pairs.
- * At the moment, each field is required, in order.
- * The fields come from BIND 8.2's representation
- */
-static err_t
-process_rsa_secret(RSA_private_key_t *rsak)
-{
- char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
- const struct fld *p;
-
- /* save bytes of Modulus and PublicExponent for keyid calculation */
- unsigned char ebytes[sizeof(buf)];
- unsigned char *eb_next = ebytes;
- chunk_t pub_bytes[2];
- chunk_t *pb_next = &pub_bytes[0];
-
- for (p = RSA_private_field; p < &RSA_private_field[RSA_PRIVATE_FIELD_ELEMENTS]; p++)
- {
- size_t sz;
- err_t ugh;
-
- if (!shift())
- {
- return "premature end of RSA key";
- }
- else if (!tokeqword(p->name))
- {
- return builddiag("%s keyword not found where expected in RSA key"
- , p->name);
- }
- else if (!(shift()
- && (!tokeq(":") || shift()))) /* ignore optional ":" */
- {
- return "premature end of RSA key";
- }
- else if (NULL != (ugh = ttodatav(tok, flp->cur - tok
- , 0, buf, sizeof(buf), &sz, diag_space, sizeof(diag_space)
- , TTODATAV_SPACECOUNTS)))
- {
- /* in RSA key, ttodata didn't like */
- return builddiag("RSA data malformed (%s): %s", ugh, tok);
- }
- else
- {
- MP_INT *n = (MP_INT *) ((char *)rsak + p->offset);
-
- n_to_mpz(n, buf, sz);
- if (pb_next < &pub_bytes[elemsof(pub_bytes)])
- {
- if (eb_next - ebytes + sz > sizeof(ebytes))
- return "public key takes too many bytes";
-
- setchunk(*pb_next, eb_next, sz);
- memcpy(eb_next, buf, sz);
- eb_next += sz;
- pb_next++;
- }
-#if 0 /* debugging info that compromises security */
- {
- size_t sz = mpz_sizeinbase(n, 16);
- char buf[RSA_MAX_OCTETS * 2 + 2]; /* ought to be big enough */
-
- passert(sz <= sizeof(buf));
- mpz_get_str(buf, 16, n);
-
- loglog(RC_LOG_SERIOUS, "%s: %s", p->name, buf);
- }
-#endif
- }
- }
-
- /* We require an (indented) '}' and the end of the record.
- * We break down the test so that the diagnostic will be
- * more helpful. Some people don't seem to wish to indent
- * the brace!
- */
- if (!shift() || !tokeq("}"))
- {
- return "malformed end of RSA private key -- indented '}' required";
- }
- else if (shift())
- {
- return "malformed end of RSA private key -- unexpected token after '}'";
- }
- else
- {
- unsigned bits = mpz_sizeinbase(&rsak->pub.n, 2);
-
- rsak->pub.k = (bits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
- rsak->pub.keyid[0] = '\0'; /* in case of splitkeytoid failure */
- splitkeytoid(pub_bytes[1].ptr, pub_bytes[1].len
- , pub_bytes[0].ptr, pub_bytes[0].len
- , rsak->pub.keyid, sizeof(rsak->pub.keyid));
- return RSA_private_key_sanity(rsak);
- }
-}
-
-/* process rsa key file protected with optional passphrase which can either be
- * read from ipsec.secrets or prompted for by using whack
- */
-static err_t
-process_rsa_keyfile(RSA_private_key_t *rsak, int whackfd)
-{
- char filename[BUF_LEN];
- prompt_pass_t pass;
-
- memset(filename,'\0', BUF_LEN);
- memset(pass.secret,'\0', sizeof(pass.secret));
- pass.prompt = FALSE;
- pass.fd = whackfd;
-
- /* we expect the filename of a PKCS#1 private key file */
-
- if (*tok == '"' || *tok == '\'') /* quoted filename */
- memcpy(filename, tok+1, flp->cur - tok - 2);
- else
- memcpy(filename, tok, flp->cur - tok);
-
- if (shift())
- {
- /* we expect an appended passphrase or passphrase prompt*/
- if (tokeqword("%prompt"))
- {
- if (pass.fd == NULL_FD)
- return "RSA private key file -- enter passphrase using 'ipsec secrets'";
- pass.prompt = TRUE;
- }
- else
- {
- char *passphrase = tok;
- size_t len = flp->cur - passphrase;
-
- if (*tok == '"' || *tok == '\'') /* quoted passphrase */
- {
- passphrase++;
- len -= 2;
- }
- if (len > PROMPT_PASS_LEN)
- return "RSA private key file -- passphrase exceeds 64 characters";
-
- memcpy(pass.secret, passphrase, len);
- }
- if (shift())
- return "RSA private key file -- unexpected token after passphrase";
- }
- return load_rsa_private_key(filename, &pass, rsak);
-}
-
-/*
- * process xauth secret read from ipsec.secrets
- */
-static err_t
-process_xauth(secret_t *s)
-{
- chunk_t user_name;
-
- s->kind = PPK_XAUTH;
-
- if (!shift())
- return "missing xauth user name";
- if (*tok == '"' || *tok == '\'') /* quoted user name */
- {
- user_name.ptr = tok + 1;
- user_name.len = flp->cur - tok - 2;
- }
- else
- {
- user_name.ptr = tok;
- user_name.len = flp->cur - tok;
- }
- plog(" loaded xauth credentials of user '%.*s'"
- , user_name.len
- , user_name.ptr);
- clonetochunk(s->u.xauth_secret.user_name
- , user_name.ptr, user_name.len, "xauth user name");
-
- if (!shift())
- return "missing xauth user password";
- return process_psk_secret(&s->u.xauth_secret.user_password);
-}
-
-/* get XAUTH secret from chained secrets lists
- * only one entry is currently supported
- */
-static bool
-xauth_get_secret(xauth_t *xauth_secret)
-{
- secret_t *s;
- bool found = FALSE;
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
- {
- if (found)
- {
- plog("found multiple xauth secrets - first selected");
- }
- else
- {
- found = TRUE;
- *xauth_secret = s->u.xauth_secret;
- }
- }
- }
- return found;
-}
-
-/*
- * find a matching secret
- */
-static bool
-xauth_verify_secret(const xauth_t *xauth_secret)
-{
- bool found = FALSE;
- secret_t *s;
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
- {
- if (!same_chunk(xauth_secret->user_name, s->u.xauth_secret.user_name))
- continue;
- found = TRUE;
- if (same_chunk(xauth_secret->user_password, s->u.xauth_secret.user_password))
- return TRUE;
- }
- }
- plog("xauth user '%.*s' %s"
- , xauth_secret->user_name.len, xauth_secret->user_name.ptr
- , found? "sent wrong password":"not found");
- return FALSE;
-}
-
-/*
- * the global xauth_module struct is defined here
- */
-xauth_module_t xauth_module;
-
-/*
- * assign the default xauth functions to any null function pointers
- */
-void
-xauth_defaults(void)
-{
- if (xauth_module.get_secret == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module: using default get_secret() function")
- )
- xauth_module.get_secret = xauth_get_secret;
- }
- if (xauth_module.verify_secret == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module: using default verify_secret() function")
- )
- xauth_module.verify_secret = xauth_verify_secret;
- }
-};
-
-/*
- * process pin read from ipsec.secrets or prompted for it using whack
- */
-static err_t
-process_pin(secret_t *s, int whackfd)
-{
- smartcard_t *sc;
- const char *pin_status = "no pin";
-
- s->kind = PPK_PIN;
-
- /* looking for the smartcard keyword */
- if (!shift() || strncmp(tok, SCX_TOKEN, strlen(SCX_TOKEN)) != 0)
- return "PIN keyword must be followed by %smartcard<reader>:<id>";
-
- sc = scx_add(scx_parse_number_slot_id(tok + strlen(SCX_TOKEN)));
- s->u.smartcard = sc;
- scx_share(sc);
- if (sc->pin.ptr != NULL)
- {
- scx_release_context(sc);
- scx_free_pin(&sc->pin);
- }
- sc->valid = FALSE;
-
- if (!shift())
- return "PIN statement must be terminated either by <pin code>, %pinpad or %prompt";
-
- if (tokeqword("%prompt"))
- {
- shift();
- /* if whackfd exists, whack will be used to prompt for a pin */
- if (whackfd != NULL_FD)
- pin_status = scx_get_pin(sc, whackfd) ? "valid pin" : "invalid pin";
- else
- pin_status = "pin entry via prompt";
- }
- else if (tokeqword("%pinpad"))
- {
- shift();
- /* pin will be entered via pin pad during verification */
- clonetochunk(sc->pin, "", 0, "empty pin");
- sc->pinpad = TRUE;
- sc->valid = TRUE;
- pin_status = "pin entry via pad";
- if (pkcs11_keep_state)
- scx_verify_pin(sc);
- }
- else
- {
- /* we read the pin directly from ipsec.secrets */
- err_t ugh = process_psk_secret(&sc->pin);
- if (ugh != NULL)
- return ugh;
- /* verify the pin */
- pin_status = scx_verify_pin(sc) ? "valid PIN" : "invalid PIN";
- }
-#ifdef SMARTCARD
- {
- char buf[BUF_LEN];
-
- if (sc->any_slot)
- snprintf(buf, BUF_LEN, "any slot");
- else
- snprintf(buf, BUF_LEN, "slot: %lu", sc->slot);
-
- plog(" %s for #%d (%s, id: %s)"
- , pin_status, sc->number, scx_print_slot(sc, ""), sc->id);
- }
-#else
- plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
-#endif
- return NULL;
-}
-
-static void
-process_secret(secret_t *s, int whackfd)
-{
- err_t ugh = NULL;
-
- s->kind = PPK_PSK; /* default */
- if (*tok == '"' || *tok == '\'')
- {
- /* old PSK format: just a string */
- ugh = process_psk_secret(&s->u.preshared_secret);
- }
- else if (tokeqword("psk"))
- {
- /* preshared key: quoted string or ttodata format */
- ugh = !shift()? "unexpected end of record in PSK"
- : process_psk_secret(&s->u.preshared_secret);
- }
- else if (tokeqword("rsa"))
- {
- /* RSA key: the fun begins.
- * A braced list of keyword and value pairs.
- */
- s->kind = PPK_RSA;
- if (!shift())
- {
- ugh = "bad RSA key syntax";
- }
- else if (tokeq("{"))
- {
- ugh = process_rsa_secret(&s->u.RSA_private_key);
- }
- else
- {
- ugh = process_rsa_keyfile(&s->u.RSA_private_key, whackfd);
- }
- }
- else if (tokeqword("xauth"))
- {
- ugh = process_xauth(s);
- }
- else if (tokeqword("pin"))
- {
- ugh = process_pin(s, whackfd);
- }
- else
- {
- ugh = builddiag("unrecognized key format: %s", tok);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s"
- , flp->filename, flp->lino, ugh);
- pfree(s);
- }
- else if (flushline("expected record boundary in key"))
- {
- /* gauntlet has been run: install new secret */
- lock_certs_and_keys("process_secret");
- s->next = secrets;
- secrets = s;
- unlock_certs_and_keys("process_secrets");
- }
-}
-
-static void process_secrets_file(const char *file_pat, int whackfd); /* forward declaration */
-
-static void
-process_secret_records(int whackfd)
-{
- /* read records from ipsec.secrets and load them into our table */
- for (;;)
- {
- (void)flushline(NULL); /* silently ditch leftovers, if any */
- if (flp->bdry == B_file)
- break;
-
- flp->bdry = B_none; /* eat the Record Boundary */
- (void)shift(); /* get real first token */
-
- if (tokeqword("include"))
- {
- /* an include directive */
- char fn[MAX_TOK_LEN]; /* space for filename (I hope) */
- char *p = fn;
- char *end_prefix = strrchr(flp->filename, '/');
-
- if (!shift())
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of include directive"
- , flp->filename, flp->lino);
- continue; /* abandon this record */
- }
-
- /* if path is relative and including file's pathname has
- * a non-empty dirname, prefix this path with that dirname.
- */
- if (tok[0] != '/' && end_prefix != NULL)
- {
- size_t pl = end_prefix - flp->filename + 1;
-
- /* "clamp" length to prevent problems now;
- * will be rediscovered and reported later.
- */
- if (pl > sizeof(fn))
- pl = sizeof(fn);
- memcpy(fn, flp->filename, pl);
- p += pl;
- }
- if (flp->cur - tok >= &fn[sizeof(fn)] - p)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: include pathname too long"
- , flp->filename, flp->lino);
- continue; /* abandon this record */
- }
- strcpy(p, tok);
- (void) shift(); /* move to Record Boundary, we hope */
- if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename"))
- {
- process_secrets_file(fn, whackfd);
- tok = NULL; /* correct, but probably redundant */
- }
- }
- else
- {
- /* expecting a list of indices and then the key info */
- secret_t *s = alloc_thing(secret_t, "secret");
-
- s->ids = NULL;
- s->kind = PPK_PSK; /* default */
- setchunk(s->u.preshared_secret, NULL, 0);
- s->next = NULL;
-
- for (;;)
- {
- if (tok[0] == '"' || tok[0] == '\'')
- {
- /* found key part */
- process_secret(s, whackfd);
- break;
- }
- else if (tokeq(":"))
- {
- /* found key part */
- shift(); /* discard explicit separator */
- process_secret(s, whackfd);
- break;
- }
- else
- {
- /* an id
- * See RFC2407 IPsec Domain of Interpretation 4.6.2
- */
- struct id id;
- err_t ugh;
-
- if (tokeq("%any"))
- {
- id = empty_id;
- id.kind = ID_IPV4_ADDR;
- ugh = anyaddr(AF_INET, &id.ip_addr);
- }
- else if (tokeq("%any6"))
- {
- id = empty_id;
- id.kind = ID_IPV6_ADDR;
- ugh = anyaddr(AF_INET6, &id.ip_addr);
- }
- else
- {
- ugh = atoid(tok, &id, FALSE);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR \"%s\" line %d: index \"%s\" %s"
- , flp->filename, flp->lino, tok, ugh);
- }
- else
- {
- id_list_t *i = alloc_thing(id_list_t
- , "id_list");
-
- i->id = id;
- unshare_id_content(&i->id);
- i->next = s->ids;
- s->ids = i;
- /* DBG_log("id type %d: %s %.*s", i->kind, ip_str(&i->ip_addr), (int)i->name.len, i->name.ptr); */
- }
- if (!shift())
- {
- /* unexpected Record Boundary or EOF */
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of id list"
- , flp->filename, flp->lino);
- break;
- }
- }
- }
- }
- }
-}
-
-static int
-globugh(const char *epath, int eerrno)
-{
- log_errno_routine(eerrno, "problem with secrets file \"%s\"", epath);
- return 1; /* stop glob */
-}
-
-static void
-process_secrets_file(const char *file_pat, int whackfd)
-{
- struct file_lex_position pos;
- char **fnp;
- glob_t globbuf;
-
- pos.depth = flp == NULL? 0 : flp->depth + 1;
-
- if (pos.depth > 10)
- {
- loglog(RC_LOG_SERIOUS, "preshared secrets file \"%s\" nested too deeply", file_pat);
- return;
- }
-
- /* do globbing */
- {
- int r = glob(file_pat, GLOB_ERR, globugh, &globbuf);
-
- if (r != 0)
- {
- switch (r)
- {
- case GLOB_NOSPACE:
- loglog(RC_LOG_SERIOUS, "out of space processing secrets filename \"%s\"", file_pat);
- break;
- case GLOB_ABORTED:
- break; /* already logged */
- case GLOB_NOMATCH:
- loglog(RC_LOG_SERIOUS, "no secrets filename matched \"%s\"", file_pat);
- break;
- default:
- loglog(RC_LOG_SERIOUS, "unknown glob error %d", r);
- break;
- }
- globfree(&globbuf);
- return;
- }
- }
-
- /* for each file... */
- for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
- {
- if (lexopen(&pos, *fnp, FALSE))
- {
- plog("loading secrets from \"%s\"", *fnp);
- (void) flushline("file starts with indentation (continuation notation)");
- process_secret_records(whackfd);
- lexclose();
- }
- }
-
- globfree(&globbuf);
-}
-
-void
-free_preshared_secrets(void)
-{
- lock_certs_and_keys("free_preshared_secrets");
-
- if (secrets != NULL)
- {
- secret_t *s, *ns;
-
- plog("forgetting secrets");
-
- for (s = secrets; s != NULL; s = ns)
- {
- id_list_t *i, *ni;
-
- ns = s->next; /* grab before freeing s */
- for (i = s->ids; i != NULL; i = ni)
- {
- ni = i->next; /* grab before freeing i */
- free_id_content(&i->id);
- pfree(i);
- }
- switch (s->kind)
- {
- case PPK_PSK:
- pfree(s->u.preshared_secret.ptr);
- break;
- case PPK_RSA:
- free_RSA_private_content(&s->u.RSA_private_key);
- break;
- case PPK_XAUTH:
- pfree(s->u.xauth_secret.user_name.ptr);
- pfree(s->u.xauth_secret.user_password.ptr);
- break;
- case PPK_PIN:
- scx_release(s->u.smartcard);
- break;
- default:
- bad_case(s->kind);
- }
- pfree(s);
- }
- secrets = NULL;
- }
-
- unlock_certs_and_keys("free_preshard_secrets");
-}
-
-void
-load_preshared_secrets(int whackfd)
-{
- free_preshared_secrets();
- (void) process_secrets_file(shared_secrets_file, whackfd);
-}
-
-/* public key machinery
- * Note: caller must set dns_auth_level.
- */
-
-pubkey_t *
-public_key_from_rsa(const RSA_public_key_t *k)
-{
- pubkey_t *p = alloc_thing(pubkey_t, "pubkey");
-
- p->id = empty_id; /* don't know, doesn't matter */
- p->issuer = empty_chunk;
- p->serial = empty_chunk;
- p->alg = PUBKEY_ALG_RSA;
-
- memcpy(p->u.rsa.keyid, k->keyid, sizeof(p->u.rsa.keyid));
- p->u.rsa.k = k->k;
- mpz_init_set(&p->u.rsa.e, &k->e);
- mpz_init_set(&p->u.rsa.n, &k->n);
-
- /* note that we return a 1 reference count upon creation:
- * invariant: recount > 0.
- */
- p->refcnt = 1;
- time(&p->installed_time);
- return p;
-}
-
-/* Free a public key record.
- * As a convenience, this returns a pointer to next.
- */
-pubkey_list_t *
-free_public_keyentry(pubkey_list_t *p)
-{
- pubkey_list_t *nxt = p->next;
-
- if (p->key != NULL)
- unreference_key(&p->key);
- pfree(p);
- return nxt;
-}
-
-void
-free_public_keys(pubkey_list_t **keys)
-{
- while (*keys != NULL)
- *keys = free_public_keyentry(*keys);
-}
-
-/* root of chained public key list */
-
-pubkey_list_t *pubkeys = NULL; /* keys from ipsec.conf */
-
-void
-free_remembered_public_keys(void)
-{
- free_public_keys(&pubkeys);
-}
-
-/* transfer public keys from *keys list to front of pubkeys list */
-void
-transfer_to_public_keys(struct gw_info *gateways_from_dns
-#ifdef USE_KEYRR
-, pubkey_list_t **keys
-#endif /* USE_KEYRR */
-)
-{
- {
- struct gw_info *gwp;
-
- for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- pubkey_list_t *pl = alloc_thing(pubkey_list_t, "from TXT");
-
- pl->key = gwp->key; /* note: this is a transfer */
- gwp->key = NULL; /* really, it is! */
- pl->next = pubkeys;
- pubkeys = pl;
- }
- }
-
-#ifdef USE_KEYRR
- {
- pubkey_list_t **pp = keys;
-
- while (*pp != NULL)
- pp = &(*pp)->next;
- *pp = pubkeys;
- pubkeys = *keys;
- *keys = NULL;
- }
-#endif /* USE_KEYRR */
-}
-
-/* decode of RSA pubkey chunk
- * - format specified in RFC 2537 RSA/MD5 Keys and SIGs in the DNS
- * - exponent length in bytes (1 or 3 octets)
- * + 1 byte if in [1, 255]
- * + otherwise 0x00 followed by 2 bytes of length
- * - exponent
- * - modulus
- */
-err_t
-unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey)
-{
- chunk_t exp;
- chunk_t mod;
-
- if (pubkey->len < 3)
- return "RSA public key blob way to short"; /* not even room for length! */
-
- if (pubkey->ptr[0] != 0x00)
- {
- setchunk(exp, pubkey->ptr + 1, pubkey->ptr[0]);
- }
- else
- {
- setchunk(exp, pubkey->ptr + 3
- , (pubkey->ptr[1] << BITS_PER_BYTE) + pubkey->ptr[2]);
- }
-
- if (pubkey->len - (exp.ptr - pubkey->ptr) < exp.len + RSA_MIN_OCTETS_RFC)
- return "RSA public key blob too short";
-
- mod.ptr = exp.ptr + exp.len;
- mod.len = &pubkey->ptr[pubkey->len] - mod.ptr;
-
- if (mod.len < RSA_MIN_OCTETS)
- return RSA_MIN_OCTETS_UGH;
-
- if (mod.len > RSA_MAX_OCTETS)
- return RSA_MAX_OCTETS_UGH;
-
- init_RSA_public_key(rsa, exp, mod);
- rsa->k = mpz_sizeinbase(&rsa->n, 2); /* size in bits, for a start */
- rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */
- DBG(DBG_RAW,
- RSA_show_public_key(rsa)
- )
-
- if (rsa->k != mod.len)
- {
- mpz_clear(&rsa->e);
- mpz_clear(&rsa->n);
- return "RSA modulus shorter than specified";
- }
-
- return NULL;
-}
-
-static void
-install_public_key(pubkey_t *pk, pubkey_list_t **head)
-{
- pubkey_list_t *p = alloc_thing(pubkey_list_t, "pubkey entry");
-
- unshare_id_content(&pk->id);
-
- /* copy issuer dn */
- if (pk->issuer.ptr != NULL)
- pk->issuer.ptr = clone_bytes(pk->issuer.ptr, pk->issuer.len, "issuer dn");
-
- /* copy serial number */
- if (pk->serial.ptr != NULL)
- pk->serial.ptr = clone_bytes(pk->serial.ptr, pk->serial.len, "serialNumber");
-
- /* store the time the public key was installed */
- time(&pk->installed_time);
-
- /* install new key at front */
- p->key = reference_key(pk);
- p->next = *head;
- *head = p;
-}
-
-
-void
-delete_public_keys(const struct id *id, enum pubkey_alg alg
-, chunk_t issuer, chunk_t serial)
-{
- pubkey_list_t **pp, *p;
- pubkey_t *pk;
-
- for (pp = &pubkeys; (p = *pp) != NULL; )
- {
- pk = p->key;
-
- if (same_id(id, &pk->id) && pk->alg == alg
- && (issuer.ptr == NULL || pk->issuer.ptr == NULL
- || same_dn(issuer, pk->issuer))
- && same_serial(serial, pk->serial))
- *pp = free_public_keyentry(p);
- else
- pp = &p->next;
- }
-}
-
-pubkey_t *
-reference_key(pubkey_t *pk)
-{
- pk->refcnt++;
- return pk;
-}
-
-void
-unreference_key(pubkey_t **pkp)
-{
- pubkey_t *pk = *pkp;
- char b[BUF_LEN];
-
- if (pk == NULL)
- return;
-
- /* print stuff */
- DBG(DBG_CONTROLMORE,
- idtoa(&pk->id, b, sizeof(b));
- DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt)
- )
-
- /* cancel out the pointer */
- *pkp = NULL;
-
- passert(pk->refcnt != 0);
- pk->refcnt--;
- if (pk->refcnt == 0)
- free_public_key(pk);
-}
-
-err_t
-add_public_key(const struct id *id
-, enum dns_auth_level dns_auth_level
-, enum pubkey_alg alg
-, const chunk_t *key
-, pubkey_list_t **head)
-{
- pubkey_t *pk = alloc_thing(pubkey_t, "pubkey");
-
- /* first: algorithm-specific decoding of key chunk */
- switch (alg)
- {
- case PUBKEY_ALG_RSA:
- {
- err_t ugh = unpack_RSA_public_key(&pk->u.rsa, key);
-
- if (ugh != NULL)
- {
- pfree(pk);
- return ugh;
- }
- }
- break;
- default:
- bad_case(alg);
- }
-
- pk->id = *id;
- pk->dns_auth_level = dns_auth_level;
- pk->alg = alg;
- pk->until_time = UNDEFINED_TIME;
- pk->issuer = empty_chunk;
- pk->serial = empty_chunk;
-
- install_public_key(pk, head);
- return NULL;
-}
-
-/* extract id and public key from x.509 certificate and
- * insert it into a pubkeyrec
- */
-void
-add_x509_public_key(x509cert_t *cert , time_t until
- , enum dns_auth_level dns_auth_level)
-{
- generalName_t *gn;
- pubkey_t *pk;
- cert_t c = { CERT_X509_SIGNATURE, {cert} };
-
- /* we support RSA only */
- if (cert->subjectPublicKeyAlgorithm != PUBKEY_ALG_RSA)
- return;
-
- /* ID type: ID_DER_ASN1_DN (X.509 subject field) */
- pk = allocate_RSA_public_key(c);
- pk->id.kind = ID_DER_ASN1_DN;
- pk->id.name = cert->subject;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- pk->issuer = cert->issuer;
- pk->serial = cert->serialNumber;
- delete_public_keys(&pk->id, pk->alg, pk->issuer, pk->serial);
- install_public_key(pk, &pubkeys);
-
- gn = cert->subjectAltName;
-
- while (gn != NULL) /* insert all subjectAltNames */
- {
- struct id id = empty_id;
-
- gntoid(&id, gn);
- if (id.kind != ID_NONE)
- {
- pk = allocate_RSA_public_key(c);
- pk->id = id;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- pk->issuer = cert->issuer;
- pk->serial = cert->serialNumber;
- delete_public_keys(&pk->id, pk->alg, pk->issuer, pk->serial);
- install_public_key(pk, &pubkeys);
- }
- gn = gn->next;
- }
-}
-
-/* extract id and public key from OpenPGP certificate and
- * insert it into a pubkeyrec
- */
-void
-add_pgp_public_key(pgpcert_t *cert , time_t until
- , enum dns_auth_level dns_auth_level)
-{
- pubkey_t *pk;
- cert_t c;
-
- c.type = CERT_PGP;
- c.u.pgp = cert;
-
- /* we support RSA only */
- if (cert->pubkeyAlg != PUBKEY_ALG_RSA)
- {
- plog(" RSA public keys supported only");
- return;
- }
-
- pk = allocate_RSA_public_key(c);
- pk->id.kind = ID_KEY_ID;
- pk->id.name.ptr = cert->fingerprint;
- pk->id.name.len = PGP_FINGERPRINT_SIZE;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- delete_public_keys(&pk->id, pk->alg, empty_chunk, empty_chunk);
- install_public_key(pk, &pubkeys);
-}
-
-/* when a X.509 certificate gets revoked, all instances of
- * the corresponding public key must be removed
- */
-void
-remove_x509_public_key(const x509cert_t *cert)
-{
- const cert_t c = {CERT_X509_SIGNATURE, {cert}};
- pubkey_list_t *p, **pp;
- pubkey_t *revoked_pk;
-
- revoked_pk = allocate_RSA_public_key(c);
- p = pubkeys;
- pp = &pubkeys;
-
- while(p != NULL)
- {
- if (same_RSA_public_key(&p->key->u.rsa, &revoked_pk->u.rsa))
- {
- /* remove p from list and free memory */
- *pp = free_public_keyentry(p);
- loglog(RC_LOG_SERIOUS,
- "invalid RSA public key deleted");
- }
- else
- {
- pp = &p->next;
- }
- p =*pp;
- }
- free_public_key(revoked_pk);
-}
-
-/*
- * list all public keys in the chained list
- */
-void list_public_keys(bool utc)
-{
- pubkey_list_t *p = pubkeys;
-
- if (p != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Public Keys:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (p != NULL)
- {
- pubkey_t *key = p->key;
-
- if (key->alg == PUBKEY_ALG_RSA)
- {
- char buf[BUF_LEN];
- char expires_buf[TIMETOA_BUF];
-
- idtoa(&key->id, buf, BUF_LEN);
- strcpy(expires_buf, timetoa(&key->until_time, utc));
- whack_log(RC_COMMENT, "%s, %4d RSA Key %s, until %s %s",
-
- timetoa(&key->installed_time, utc), 8*key->u.rsa.k, key->u.rsa.keyid,
- expires_buf,
- check_expiry(key->until_time, PUBKEY_WARNING_INTERVAL, TRUE));
- whack_log(RC_COMMENT," %s '%s'",
- enum_show(&ident_names, key->id.kind), buf);
- if (key->issuer.len > 0)
- {
- dntoa(buf, BUF_LEN, key->issuer);
- whack_log(RC_COMMENT," issuer: '%s'", buf);
- }
- if (key->serial.len > 0)
- {
- datatot(key->serial.ptr, key->serial.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT," serial: %s", buf);
- }
- }
- p = p->next;
- }
-}
diff --git a/programs/pluto/keys.h b/programs/pluto/keys.h
deleted file mode 100644
index 2f6216b93..000000000
--- a/programs/pluto/keys.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* mechanisms for preshared keys (public, private, and preshared secrets)
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: keys.h,v 1.8 2007/01/10 00:36:19 as Exp $
- */
-
-#ifndef _KEYS_H
-#define _KEYS_H
-
-#include <gmp.h> /* GNU Multi-Precision library */
-
-#include "pkcs1.h"
-#include "certs.h"
-
-#ifndef SHARED_SECRETS_FILE
-# define SHARED_SECRETS_FILE "/etc/ipsec.secrets"
-#endif
-
-const char *shared_secrets_file;
-
-extern void load_preshared_secrets(int whackfd);
-extern void free_preshared_secrets(void);
-
-enum PrivateKeyKind {
- PPK_PSK,
- /* PPK_DSS, */ /* not implemented */
- PPK_RSA,
- PPK_XAUTH,
- PPK_PIN
-};
-
-extern void xauth_defaults(void);
-
-/* forward declaration */
-struct connection;
-
-extern const chunk_t *get_preshared_secret(const struct connection *c);
-extern err_t unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey);
-extern const RSA_private_key_t *get_RSA_private_key(const struct connection *c);
-extern const RSA_private_key_t *get_x509_private_key(const x509cert_t *cert);
-
-/* public key machinery */
-
-typedef struct pubkey pubkey_t;
-
-struct pubkey {
- struct id id;
- unsigned refcnt; /* reference counted! */
- enum dns_auth_level dns_auth_level;
- char *dns_sig;
- time_t installed_time
- , last_tried_time
- , last_worked_time
- , until_time;
- chunk_t issuer;
- chunk_t serial;
- enum pubkey_alg alg;
- union {
- RSA_public_key_t rsa;
- } u;
-};
-
-typedef struct pubkey_list pubkey_list_t;
-
-struct pubkey_list {
- pubkey_t *key;
- pubkey_list_t *next;
-};
-
-extern pubkey_list_t *pubkeys; /* keys from ipsec.conf or from certs */
-
-extern pubkey_t *public_key_from_rsa(const RSA_public_key_t *k);
-extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p);
-extern void free_public_keys(pubkey_list_t **keys);
-extern void free_remembered_public_keys(void);
-extern void delete_public_keys(const struct id *id, enum pubkey_alg alg
- , chunk_t issuer, chunk_t serial);
-
-extern pubkey_t *reference_key(pubkey_t *pk);
-extern void unreference_key(pubkey_t **pkp);
-
-
-extern err_t add_public_key(const struct id *id
- , enum dns_auth_level dns_auth_level
- , enum pubkey_alg alg
- , const chunk_t *key
- , pubkey_list_t **head);
-
-extern bool has_private_key(cert_t cert);
-extern void add_x509_public_key(x509cert_t *cert, time_t until
- , enum dns_auth_level dns_auth_level);
-extern void add_pgp_public_key(pgpcert_t *cert, time_t until
- , enum dns_auth_level dns_auth_level);
-extern void remove_x509_public_key(const x509cert_t *cert);
-extern void list_public_keys(bool utc);
-
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
-extern void transfer_to_public_keys(struct gw_info *gateways_from_dns
-#ifdef USE_KEYRR
- , pubkey_list_t **keys
-#endif /* USE_KEYRR */
- );
-
-#endif /* _KEYS_H */
diff --git a/programs/pluto/lex.c b/programs/pluto/lex.c
deleted file mode 100644
index 5c811725a..000000000
--- a/programs/pluto/lex.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* lexer (lexical analyzer) for control files
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: lex.c,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-#include "lex.h"
-
-struct file_lex_position *flp = NULL;
-
-/* Open a file for lexical processing.
- * new_flp and name must point into storage with will live
- * at least until the file is closed.
- */
-bool
-lexopen(struct file_lex_position *new_flp, const char *name, bool optional)
-{
- FILE *f = fopen(name, "r");
-
- if (f == NULL)
- {
- if (!optional || errno != ENOENT)
- log_errno((e, "could not open \"%s\"", name));
- return FALSE;
- }
- else
- {
- new_flp->previous = flp;
- flp = new_flp;
- flp->filename = name;
- flp->fp = f;
- flp->lino = 0;
- flp->bdry = B_none;
-
- flp->cur = flp->buffer; /* nothing loaded yet */
- flp->under = *flp->cur = '\0';
-
- (void) shift(); /* prime tok */
- return TRUE;
- }
-}
-
-void
-lexclose(void)
-{
- fclose(flp->fp);
- flp = flp->previous;
-}
-
-/* Token decoding: shift() loads the next token into tok.
- * Iff a token starts at the left margin, it is considered
- * to be the first in a record. We create a special condition,
- * Record Boundary (analogous to EOF), just before such a token.
- * We are unwilling to shift through a record boundary:
- * it must be overridden first.
- * Returns FALSE iff Record Boundary or EOF (i.e. no token);
- * tok will then be NULL.
- */
-
-char *tok;
-#define tokeq(s) (streq(tok, (s)))
-#define tokeqword(s) (strcasecmp(tok, (s)) == 0)
-
-bool
-shift(void)
-{
- char *p = flp->cur;
- char *sor = NULL; /* start of record for any new lines */
-
- passert(flp->bdry == B_none);
-
- *p = flp->under;
- flp->under = '\0';
-
- for (;;)
- {
- switch (*p)
- {
- case '\0': /* end of line */
- case '#': /* comment to end of line: treat as end of line */
- /* get the next line */
- if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
- {
- flp->bdry = B_file;
- tok = flp->cur = NULL;
- return FALSE;
- }
- else
- {
- /* strip trailing whitespace, including \n */
-
- for (p = flp->buffer+strlen(flp->buffer)-1
- ; p>flp->buffer && isspace(p[-1]); p--)
- ;
- *p = '\0';
-
- flp->lino++;
- sor = p = flp->buffer;
- }
- break; /* try again for a token */
-
- case ' ': /* whitespace */
- case '\t':
- p++;
- break; /* try again for a token */
-
- case '"': /* quoted token */
- case '\'':
- if (p != sor)
- {
- /* we have a quoted token: note and advance to its end */
- tok = p;
- p = strchr(p+1, *p);
- if (p == NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
- , flp->filename, flp->lino);
- p = tok + strlen(tok);
- }
- else
- {
- p++; /* include delimiter in token */
- }
-
- /* remember token delimiter and replace with '\0' */
- flp->under = *p;
- *p = '\0';
- flp->cur = p;
- return TRUE;
- }
- /* FALL THROUGH */
- default:
- if (p != sor)
- {
- /* we seem to have a token: note and advance to its end */
- tok = p;
-
- if (p[0] == '0' && p[1] == 't')
- {
- /* 0t... token goes to end of line */
- p += strlen(p);
- }
- else
- {
- /* "ordinary" token: up to whitespace or end of line */
- do {
- p++;
- } while (*p != '\0' && !isspace(*p))
- ;
-
- /* fudge to separate ':' from a preceding adjacent token */
- if (p-1 > tok && p[-1] == ':')
- p--;
- }
-
- /* remember token delimiter and replace with '\0' */
- flp->under = *p;
- *p = '\0';
- flp->cur = p;
- return TRUE;
- }
-
- /* we have a start-of-record: return it, deferring "real" token */
- flp->bdry = B_record;
- tok = NULL;
- flp->under = *p;
- flp->cur = p;
- return FALSE;
- }
- }
-}
-
-/* ensures we are at a Record (or File) boundary, optionally warning if not */
-
-bool
-flushline(const char *m)
-{
- if (flp->bdry != B_none)
- {
- return TRUE;
- }
- else
- {
- if (m != NULL)
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
- do ; while (shift());
- return FALSE;
- }
-}
diff --git a/programs/pluto/lex.h b/programs/pluto/lex.h
deleted file mode 100644
index fb6c15236..000000000
--- a/programs/pluto/lex.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* lexer (lexical analyzer) for control files
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: lex.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-#define MAX_TOK_LEN 2048 /* includes terminal '\0' */
-struct file_lex_position
-{
- int depth; /* how deeply we are nested */
- const char *filename;
- FILE *fp;
- enum { B_none, B_record, B_file } bdry; /* current boundary */
- int lino; /* line number in file */
- char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
- char *cur; /* cursor */
- char under; /* except in shift(): character orignally at *cur */
- struct file_lex_position *previous;
-};
-
-extern struct file_lex_position *flp;
-
-extern bool lexopen(struct file_lex_position *new_flp, const char *name, bool optional);
-extern void lexclose(void);
-
-
-/* Token decoding: shift() loads the next token into tok.
- * Iff a token starts at the left margin, it is considered
- * to be the first in a record. We create a special condition,
- * Record Boundary (analogous to EOF), just before such a token.
- * We are unwilling to shift through a record boundary:
- * it must be overridden first.
- * Returns FALSE iff Record Boundary or EOF (i.e. no token);
- * tok will then be NULL.
- */
-
-extern char *tok;
-#define tokeq(s) (streq(tok, (s)))
-#define tokeqword(s) (strcasecmp(tok, (s)) == 0)
-
-extern bool shift(void);
-extern bool flushline(const char *m);
diff --git a/programs/pluto/linux26/netlink.h b/programs/pluto/linux26/netlink.h
deleted file mode 100644
index 6b0896da6..000000000
--- a/programs/pluto/linux26/netlink.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef __LINUX_NETLINK_H
-#define __LINUX_NETLINK_H
-
-#include <stdint.h>
-#include <sys/socket.h> /* for sa_family_t */
-
-#define NETLINK_ROUTE 0 /* Routing/device hook */
-#define NETLINK_SKIP 1 /* Reserved for ENskip */
-#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
-#define NETLINK_FIREWALL 3 /* Firewalling hook */
-#define NETLINK_TCPDIAG 4 /* TCP socket monitoring */
-#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
-#define NETLINK_XFRM 6 /* ipsec */
-#define NETLINK_ARPD 8
-#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */
-#define NETLINK_IP6_FW 13
-#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
-#define NETLINK_TAPBASE 16 /* 16 to 31 are ethertap */
-
-#define MAX_LINKS 32
-
-struct sockaddr_nl
-{
- sa_family_t nl_family; /* AF_NETLINK */
- unsigned short nl_pad; /* zero */
- uint32_t nl_pid; /* process pid */
- uint32_t nl_groups; /* multicast groups mask */
-};
-
-struct nlmsghdr
-{
- uint32_t nlmsg_len; /* Length of message including header */
- uint16_t nlmsg_type; /* Message content */
- uint16_t nlmsg_flags; /* Additional flags */
- uint32_t nlmsg_seq; /* Sequence number */
- uint32_t nlmsg_pid; /* Sending process PID */
-};
-
-/* Flags values */
-
-#define NLM_F_REQUEST 1 /* It is request message. */
-#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */
-#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
-#define NLM_F_ECHO 8 /* Echo this request */
-
-/* Modifiers to GET request */
-#define NLM_F_ROOT 0x100 /* specify tree root */
-#define NLM_F_MATCH 0x200 /* return all matching */
-#define NLM_F_ATOMIC 0x400 /* atomic GET */
-#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
-
-/* Modifiers to NEW request */
-#define NLM_F_REPLACE 0x100 /* Override existing */
-#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
-#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
-#define NLM_F_APPEND 0x800 /* Add to end of list */
-
-/*
- 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
- 4.4BSD CHANGE NLM_F_REPLACE
-
- True CHANGE NLM_F_CREATE|NLM_F_REPLACE
- Append NLM_F_CREATE
- Check NLM_F_EXCL
- */
-
-#define NLMSG_ALIGNTO 4
-#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
-#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr)))
-#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
-#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
-#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
- (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
-#define NLMSG_OK(nlh,len) ((len) > 0 && (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
- (nlh)->nlmsg_len <= (len))
-#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
-
-#define NLMSG_NOOP 0x1 /* Nothing. */
-#define NLMSG_ERROR 0x2 /* Error */
-#define NLMSG_DONE 0x3 /* End of a dump */
-#define NLMSG_OVERRUN 0x4 /* Data lost */
-
-struct nlmsgerr
-{
- int error;
- struct nlmsghdr msg;
-};
-
-#define NET_MAJOR 36 /* Major 36 is reserved for networking */
-#endif /* __LINUX_NETLINK_H */
diff --git a/programs/pluto/linux26/rtnetlink.h b/programs/pluto/linux26/rtnetlink.h
deleted file mode 100644
index 341bc1f86..000000000
--- a/programs/pluto/linux26/rtnetlink.h
+++ /dev/null
@@ -1,562 +0,0 @@
-#ifndef __LINUX_RTNETLINK_H
-#define __LINUX_RTNETLINK_H
-
-#include "netlink.h"
-#include <stdint.h>
-
-#define RTNL_DEBUG 1
-
-
-/****
- * Routing/neighbour discovery messages.
- ****/
-
-/* Types of messages */
-
-#define RTM_BASE 0x10
-
-#define RTM_NEWLINK (RTM_BASE+0)
-#define RTM_DELLINK (RTM_BASE+1)
-#define RTM_GETLINK (RTM_BASE+2)
-#define RTM_SETLINK (RTM_BASE+3)
-
-#define RTM_NEWADDR (RTM_BASE+4)
-#define RTM_DELADDR (RTM_BASE+5)
-#define RTM_GETADDR (RTM_BASE+6)
-
-#define RTM_NEWROUTE (RTM_BASE+8)
-#define RTM_DELROUTE (RTM_BASE+9)
-#define RTM_GETROUTE (RTM_BASE+10)
-
-#define RTM_NEWNEIGH (RTM_BASE+12)
-#define RTM_DELNEIGH (RTM_BASE+13)
-#define RTM_GETNEIGH (RTM_BASE+14)
-
-#define RTM_NEWRULE (RTM_BASE+16)
-#define RTM_DELRULE (RTM_BASE+17)
-#define RTM_GETRULE (RTM_BASE+18)
-
-#define RTM_NEWQDISC (RTM_BASE+20)
-#define RTM_DELQDISC (RTM_BASE+21)
-#define RTM_GETQDISC (RTM_BASE+22)
-
-#define RTM_NEWTCLASS (RTM_BASE+24)
-#define RTM_DELTCLASS (RTM_BASE+25)
-#define RTM_GETTCLASS (RTM_BASE+26)
-
-#define RTM_NEWTFILTER (RTM_BASE+28)
-#define RTM_DELTFILTER (RTM_BASE+29)
-#define RTM_GETTFILTER (RTM_BASE+30)
-
-#define RTM_MAX (RTM_BASE+31)
-
-/*
- Generic structure for encapsulation optional route information.
- It is reminiscent of sockaddr, but with sa_family replaced
- with attribute type.
- */
-
-struct rtattr
-{
- unsigned short rta_len;
- unsigned short rta_type;
-};
-
-/* Macros to handle rtattributes */
-
-#define RTA_ALIGNTO 4
-#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
-#define RTA_OK(rta,len) ((len) > 0 && (rta)->rta_len >= sizeof(struct rtattr) && \
- (rta)->rta_len <= (len))
-#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
- (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
-#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
-#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
-#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
-#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
-
-
-
-
-/******************************************************************************
- * Definitions used in routing table administation.
- ****/
-
-struct rtmsg
-{
- unsigned char rtm_family;
- unsigned char rtm_dst_len;
- unsigned char rtm_src_len;
- unsigned char rtm_tos;
-
- unsigned char rtm_table; /* Routing table id */
- unsigned char rtm_protocol; /* Routing protocol; see below */
- unsigned char rtm_scope; /* See below */
- unsigned char rtm_type; /* See below */
-
- unsigned rtm_flags;
-};
-
-/* rtm_type */
-
-enum
-{
- RTN_UNSPEC,
- RTN_UNICAST, /* Gateway or direct route */
- RTN_LOCAL, /* Accept locally */
- RTN_BROADCAST, /* Accept locally as broadcast,
- send as broadcast */
- RTN_ANYCAST, /* Accept locally as broadcast,
- but send as unicast */
- RTN_MULTICAST, /* Multicast route */
- RTN_BLACKHOLE, /* Drop */
- RTN_UNREACHABLE, /* Destination is unreachable */
- RTN_PROHIBIT, /* Administratively prohibited */
- RTN_THROW, /* Not in this table */
- RTN_NAT, /* Translate this address */
- RTN_XRESOLVE, /* Use external resolver */
-};
-
-#define RTN_MAX RTN_XRESOLVE
-
-
-/* rtm_protocol */
-
-#define RTPROT_UNSPEC 0
-#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
- not used by current IPv4 */
-#define RTPROT_KERNEL 2 /* Route installed by kernel */
-#define RTPROT_BOOT 3 /* Route installed during boot */
-#define RTPROT_STATIC 4 /* Route installed by administrator */
-
-/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
- they just passed from user and back as is.
- It will be used by hypothetical multiple routing daemons.
- Note that protocol values should be standardized in order to
- avoid conflicts.
- */
-
-#define RTPROT_GATED 8 /* Apparently, GateD */
-#define RTPROT_RA 9 /* RDISC/ND router advertisments */
-#define RTPROT_MRT 10 /* Merit MRT */
-#define RTPROT_ZEBRA 11 /* Zebra */
-#define RTPROT_BIRD 12 /* BIRD */
-#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
-
-/* rtm_scope
-
- Really it is not scope, but sort of distance to the destination.
- NOWHERE are reserved for not existing destinations, HOST is our
- local addresses, LINK are destinations, located on directly attached
- link and UNIVERSE is everywhere in the Universe.
-
- Intermediate values are also possible f.e. interior routes
- could be assigned a value between UNIVERSE and LINK.
-*/
-
-enum rt_scope_t
-{
- RT_SCOPE_UNIVERSE=0,
-/* User defined values */
- RT_SCOPE_SITE=200,
- RT_SCOPE_LINK=253,
- RT_SCOPE_HOST=254,
- RT_SCOPE_NOWHERE=255
-};
-
-/* rtm_flags */
-
-#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
-#define RTM_F_CLONED 0x200 /* This route is cloned */
-#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
-
-/* Reserved table identifiers */
-
-enum rt_class_t
-{
- RT_TABLE_UNSPEC=0,
-/* User defined values */
- RT_TABLE_DEFAULT=253,
- RT_TABLE_MAIN=254,
- RT_TABLE_LOCAL=255
-};
-#define RT_TABLE_MAX RT_TABLE_LOCAL
-
-
-
-/* Routing message attributes */
-
-enum rtattr_type_t
-{
- RTA_UNSPEC,
- RTA_DST,
- RTA_SRC,
- RTA_IIF,
- RTA_OIF,
- RTA_GATEWAY,
- RTA_PRIORITY,
- RTA_PREFSRC,
- RTA_METRICS,
- RTA_MULTIPATH,
- RTA_PROTOINFO,
- RTA_FLOW,
- RTA_CACHEINFO,
- RTA_SESSION,
-};
-
-#define RTA_MAX RTA_SESSION
-
-#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
-#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
-
-/* RTM_MULTIPATH --- array of struct rtnexthop.
- *
- * "struct rtnexthop" describres all necessary nexthop information,
- * i.e. parameters of path to a destination via this nextop.
- *
- * At the moment it is impossible to set different prefsrc, mtu, window
- * and rtt for different paths from multipath.
- */
-
-struct rtnexthop
-{
- unsigned short rtnh_len;
- unsigned char rtnh_flags;
- unsigned char rtnh_hops;
- int rtnh_ifindex;
-};
-
-/* rtnh_flags */
-
-#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
-#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
-#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
-
-/* Macros to handle hexthops */
-
-#define RTNH_ALIGNTO 4
-#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
-#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
- ((int)(rtnh)->rtnh_len) <= (len))
-#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
-#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
-#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
-#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
-
-/* RTM_CACHEINFO */
-
-struct rta_cacheinfo
-{
- uint32_t rta_clntref;
- uint32_t rta_lastuse;
- int32_t rta_expires;
- uint32_t rta_error;
- uint32_t rta_used;
-
-#define RTNETLINK_HAVE_PEERINFO 1
- uint32_t rta_id;
- uint32_t rta_ts;
- uint32_t rta_tsage;
-};
-
-/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
-
-enum
-{
- RTAX_UNSPEC,
-#define RTAX_UNSPEC RTAX_UNSPEC
- RTAX_LOCK,
-#define RTAX_LOCK RTAX_LOCK
- RTAX_MTU,
-#define RTAX_MTU RTAX_MTU
- RTAX_WINDOW,
-#define RTAX_WINDOW RTAX_WINDOW
- RTAX_RTT,
-#define RTAX_RTT RTAX_RTT
- RTAX_RTTVAR,
-#define RTAX_RTTVAR RTAX_RTTVAR
- RTAX_SSTHRESH,
-#define RTAX_SSTHRESH RTAX_SSTHRESH
- RTAX_CWND,
-#define RTAX_CWND RTAX_CWND
- RTAX_ADVMSS,
-#define RTAX_ADVMSS RTAX_ADVMSS
- RTAX_REORDERING,
-#define RTAX_REORDERING RTAX_REORDERING
-};
-
-#define RTAX_MAX RTAX_REORDERING
-
-struct rta_session
-{
- uint8_t proto;
-
- union {
- struct {
- uint16_t sport;
- uint16_t dport;
- } ports;
-
- struct {
- uint8_t type;
- uint8_t code;
- uint16_t ident;
- } icmpt;
-
- uint32_t spi;
- } u;
-};
-
-
-/*********************************************************
- * Interface address.
- ****/
-
-struct ifaddrmsg
-{
- unsigned char ifa_family;
- unsigned char ifa_prefixlen; /* The prefix length */
- unsigned char ifa_flags; /* Flags */
- unsigned char ifa_scope; /* See above */
- int ifa_index; /* Link index */
-};
-
-enum
-{
- IFA_UNSPEC,
- IFA_ADDRESS,
- IFA_LOCAL,
- IFA_LABEL,
- IFA_BROADCAST,
- IFA_ANYCAST,
- IFA_CACHEINFO
-};
-
-#define IFA_MAX IFA_CACHEINFO
-
-/* ifa_flags */
-
-#define IFA_F_SECONDARY 0x01
-#define IFA_F_TEMPORARY IFA_F_SECONDARY
-
-#define IFA_F_DEPRECATED 0x20
-#define IFA_F_TENTATIVE 0x40
-#define IFA_F_PERMANENT 0x80
-
-struct ifa_cacheinfo
-{
- int32_t ifa_prefered;
- int32_t ifa_valid;
-};
-
-
-#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
-#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
-
-/*
- Important comment:
- IFA_ADDRESS is prefix address, rather than local interface address.
- It makes no difference for normally configured broadcast interfaces,
- but for point-to-point IFA_ADDRESS is DESTINATION address,
- local address is supplied in IFA_LOCAL attribute.
- */
-
-/**************************************************************
- * Neighbour discovery.
- ****/
-
-struct ndmsg
-{
- unsigned char ndm_family;
- unsigned char ndm_pad1;
- unsigned short ndm_pad2;
- int ndm_ifindex; /* Link index */
- uint16_t ndm_state;
- uint8_t ndm_flags;
- uint8_t ndm_type;
-};
-
-enum
-{
- NDA_UNSPEC,
- NDA_DST,
- NDA_LLADDR,
- NDA_CACHEINFO
-};
-
-#define NDA_MAX NDA_CACHEINFO
-
-#define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
-#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
-
-/*
- * Neighbor Cache Entry Flags
- */
-
-#define NTF_PROXY 0x08 /* == ATF_PUBL */
-#define NTF_ROUTER 0x80
-
-/*
- * Neighbor Cache Entry States.
- */
-
-#define NUD_INCOMPLETE 0x01
-#define NUD_REACHABLE 0x02
-#define NUD_STALE 0x04
-#define NUD_DELAY 0x08
-#define NUD_PROBE 0x10
-#define NUD_FAILED 0x20
-
-/* Dummy states */
-#define NUD_NOARP 0x40
-#define NUD_PERMANENT 0x80
-#define NUD_NONE 0x00
-
-
-struct nda_cacheinfo
-{
- uint32_t ndm_confirmed;
- uint32_t ndm_used;
- uint32_t ndm_updated;
- uint32_t ndm_refcnt;
-};
-
-/****
- * General form of address family dependent message.
- ****/
-
-struct rtgenmsg
-{
- unsigned char rtgen_family;
-};
-
-/*****************************************************************
- * Link layer specific messages.
- ****/
-
-/* struct ifinfomsg
- * passes link level specific information, not dependent
- * on network protocol.
- */
-
-struct ifinfomsg
-{
- unsigned char ifi_family;
- unsigned char __ifi_pad;
- unsigned short ifi_type; /* ARPHRD_* */
- int ifi_index; /* Link index */
- unsigned ifi_flags; /* IFF_* flags */
- unsigned ifi_change; /* IFF_* change mask */
-};
-
-enum
-{
- IFLA_UNSPEC,
- IFLA_ADDRESS,
- IFLA_BROADCAST,
- IFLA_IFNAME,
- IFLA_MTU,
- IFLA_LINK,
- IFLA_QDISC,
- IFLA_STATS,
- IFLA_COST,
-#define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
-#define IFLA_PRIORITY IFLA_PRIORITY
- IFLA_MASTER,
-#define IFLA_MASTER IFLA_MASTER
- IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-#define IFLA_WIRELESS IFLA_WIRELESS
-};
-
-
-#define IFLA_MAX IFLA_WIRELESS
-
-#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
-#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-
-/* ifi_flags.
-
- IFF_* flags.
-
- The only change is:
- IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
- more not changeable by user. They describe link media
- characteristics and set by device driver.
-
- Comments:
- - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
- - If neiher of these three flags are set;
- the interface is NBMA.
-
- - IFF_MULTICAST does not mean anything special:
- multicasts can be used on all not-NBMA links.
- IFF_MULTICAST means that this media uses special encapsulation
- for multicast frames. Apparently, all IFF_POINTOPOINT and
- IFF_BROADCAST devices are able to use multicasts too.
- */
-
-/* IFLA_LINK.
- For usual devices it is equal ifi_index.
- If it is a "virtual interface" (f.e. tunnel), ifi_link
- can point to real physical interface (f.e. for bandwidth calculations),
- or maybe 0, what means, that real media is unknown (usual
- for IPIP tunnels, when route to endpoint is allowed to change)
- */
-
-/*****************************************************************
- * Traffic control messages.
- ****/
-
-struct tcmsg
-{
- unsigned char tcm_family;
- unsigned char tcm__pad1;
- unsigned short tcm__pad2;
- int tcm_ifindex;
- uint32_t tcm_handle;
- uint32_t tcm_parent;
- uint32_t tcm_info;
-};
-
-enum
-{
- TCA_UNSPEC,
- TCA_KIND,
- TCA_OPTIONS,
- TCA_STATS,
- TCA_XSTATS,
- TCA_RATE,
-};
-
-#define TCA_MAX TCA_RATE
-
-#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
-#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
-
-
-/* SUMMARY: maximal rtattr understood by kernel */
-
-#define RTATTR_MAX RTA_MAX
-
-/* RTnetlink multicast groups */
-
-#define RTMGRP_LINK 1
-#define RTMGRP_NOTIFY 2
-#define RTMGRP_NEIGH 4
-#define RTMGRP_TC 8
-
-#define RTMGRP_IPV4_IFADDR 0x10
-#define RTMGRP_IPV4_MROUTE 0x20
-#define RTMGRP_IPV4_ROUTE 0x40
-
-#define RTMGRP_IPV6_IFADDR 0x100
-#define RTMGRP_IPV6_MROUTE 0x200
-#define RTMGRP_IPV6_ROUTE 0x400
-
-#define RTMGRP_DECnet_IFADDR 0x1000
-#define RTMGRP_DECnet_ROUTE 0x4000
-
-/* End of information exported to user level */
-
-#endif /* __LINUX_RTNETLINK_H */
diff --git a/programs/pluto/linux26/xfrm.h b/programs/pluto/linux26/xfrm.h
deleted file mode 100644
index 4269ae29b..000000000
--- a/programs/pluto/linux26/xfrm.h
+++ /dev/null
@@ -1,233 +0,0 @@
-#ifndef _LINUX_XFRM_H
-#define _LINUX_XFRM_H
-
-#include <stdint.h>
-
-/* All of the structures in this file may not change size as they are
- * passed into the kernel from userspace via netlink sockets.
- */
-
-/* Structure to encapsulate addresses. I do not want to use
- * "standard" structure. My apologies.
- */
-typedef union
-{
- uint32_t a4;
- uint32_t a6[4];
-} xfrm_address_t;
-
-/* Ident of a specific xfrm_state. It is used on input to lookup
- * the state by (spi,daddr,ah/esp) or to store information about
- * spi, protocol and tunnel address on output.
- */
-struct xfrm_id
-{
- xfrm_address_t daddr;
- uint32_t spi;
- uint8_t proto;
-};
-
-/* Selector, used as selector both on policy rules (SPD) and SAs. */
-
-struct xfrm_selector
-{
- xfrm_address_t daddr;
- xfrm_address_t saddr;
- uint16_t dport;
- uint16_t dport_mask;
- uint16_t sport;
- uint16_t sport_mask;
- uint16_t family;
- uint8_t prefixlen_d;
- uint8_t prefixlen_s;
- uint8_t proto;
- int ifindex;
- uid_t user;
-};
-
-#define XFRM_INF (~(uint64_t)0)
-
-struct xfrm_lifetime_cfg
-{
- uint64_t soft_byte_limit;
- uint64_t hard_byte_limit;
- uint64_t soft_packet_limit;
- uint64_t hard_packet_limit;
- uint64_t soft_add_expires_seconds;
- uint64_t hard_add_expires_seconds;
- uint64_t soft_use_expires_seconds;
- uint64_t hard_use_expires_seconds;
-};
-
-struct xfrm_lifetime_cur
-{
- uint64_t bytes;
- uint64_t packets;
- uint64_t add_time;
- uint64_t use_time;
-};
-
-struct xfrm_replay_state
-{
- uint32_t oseq;
- uint32_t seq;
- uint32_t bitmap;
-};
-
-struct xfrm_algo {
- char alg_name[64];
- int alg_key_len; /* in bits */
- char alg_key[0];
-};
-
-struct xfrm_stats {
- uint32_t replay_window;
- uint32_t replay;
- uint32_t integrity_failed;
-};
-
-enum
-{
- XFRM_POLICY_IN = 0,
- XFRM_POLICY_OUT = 1,
- XFRM_POLICY_FWD = 2,
- XFRM_POLICY_MAX = 3
-};
-
-enum
-{
- XFRM_SHARE_ANY, /* No limitations */
- XFRM_SHARE_SESSION, /* For this session only */
- XFRM_SHARE_USER, /* For this user only */
- XFRM_SHARE_UNIQUE /* Use once */
-};
-
-/* Netlink configuration messages. */
-#define XFRM_MSG_BASE 0x10
-
-#define XFRM_MSG_NEWSA (XFRM_MSG_BASE + 0)
-#define XFRM_MSG_DELSA (XFRM_MSG_BASE + 1)
-#define XFRM_MSG_GETSA (XFRM_MSG_BASE + 2)
-
-#define XFRM_MSG_NEWPOLICY (XFRM_MSG_BASE + 3)
-#define XFRM_MSG_DELPOLICY (XFRM_MSG_BASE + 4)
-#define XFRM_MSG_GETPOLICY (XFRM_MSG_BASE + 5)
-
-#define XFRM_MSG_ALLOCSPI (XFRM_MSG_BASE + 6)
-#define XFRM_MSG_ACQUIRE (XFRM_MSG_BASE + 7)
-#define XFRM_MSG_EXPIRE (XFRM_MSG_BASE + 8)
-
-#define XFRM_MSG_UPDPOLICY (XFRM_MSG_BASE + 9)
-#define XFRM_MSG_UPDSA (XFRM_MSG_BASE + 10)
-
-#define XFRM_MSG_POLEXPIRE (XFRM_MSG_BASE + 11)
-
-#define XFRM_MSG_MAX (XFRM_MSG_POLEXPIRE+1)
-
-struct xfrm_user_tmpl {
- struct xfrm_id id;
- uint16_t family;
- xfrm_address_t saddr;
- uint32_t reqid;
- uint8_t mode;
- uint8_t share;
- uint8_t optional;
- uint32_t aalgos;
- uint32_t ealgos;
- uint32_t calgos;
-};
-
-struct xfrm_encap_tmpl {
- uint16_t encap_type;
- uint16_t encap_sport;
- uint16_t encap_dport;
- xfrm_address_t encap_oa;
-};
-
-/* Netlink message attributes. */
-enum xfrm_attr_type_t {
- XFRMA_UNSPEC,
- XFRMA_ALG_AUTH, /* struct xfrm_algo */
- XFRMA_ALG_CRYPT, /* struct xfrm_algo */
- XFRMA_ALG_COMP, /* struct xfrm_algo */
- XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */
- XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */
-
-#define XFRMA_MAX XFRMA_TMPL
-};
-
-struct xfrm_usersa_info {
- struct xfrm_selector sel;
- struct xfrm_id id;
- xfrm_address_t saddr;
- struct xfrm_lifetime_cfg lft;
- struct xfrm_lifetime_cur curlft;
- struct xfrm_stats stats;
- uint32_t seq;
- uint32_t reqid;
- uint16_t family;
- uint8_t mode; /* 0=transport,1=tunnel */
- uint8_t replay_window;
- uint8_t flags;
-#define XFRM_STATE_NOECN 1
-};
-
-struct xfrm_usersa_id {
- xfrm_address_t daddr;
- uint32_t spi;
- uint16_t family;
- uint8_t proto;
-};
-
-struct xfrm_userspi_info {
- struct xfrm_usersa_info info;
- uint32_t min;
- uint32_t max;
-};
-
-struct xfrm_userpolicy_info {
- struct xfrm_selector sel;
- struct xfrm_lifetime_cfg lft;
- struct xfrm_lifetime_cur curlft;
- uint32_t priority;
- uint32_t index;
- uint8_t dir;
- uint8_t action;
-#define XFRM_POLICY_ALLOW 0
-#define XFRM_POLICY_BLOCK 1
- uint8_t flags;
-#define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */
- uint8_t share;
-};
-
-struct xfrm_userpolicy_id {
- struct xfrm_selector sel;
- uint32_t index;
- uint8_t dir;
-};
-
-struct xfrm_user_acquire {
- struct xfrm_id id;
- xfrm_address_t saddr;
- struct xfrm_selector sel;
- struct xfrm_userpolicy_info policy;
- uint32_t aalgos;
- uint32_t ealgos;
- uint32_t calgos;
- uint32_t seq;
-};
-
-struct xfrm_user_expire {
- struct xfrm_usersa_info state;
- uint8_t hard;
-};
-
-struct xfrm_user_polexpire {
- struct xfrm_userpolicy_info pol;
- uint8_t hard;
-};
-
-#define XFRMGRP_ACQUIRE 1
-#define XFRMGRP_EXPIRE 2
-
-#endif /* _LINUX_XFRM_H */
diff --git a/programs/pluto/log.c b/programs/pluto/log.c
deleted file mode 100644
index aef93ff3c..000000000
--- a/programs/pluto/log.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/* error logging functions
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: log.c,v 1.9 2006/10/17 10:30:54 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
-#include <sys/queue.h>
-#include <libgen.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "server.h"
-#include "state.h"
-#include "connections.h"
-#include "kernel.h"
-#include "whack.h" /* needs connections.h */
-#include "timer.h"
-
-/* close one per-peer log */
-static void perpeer_logclose(struct connection *c); /* forward */
-
-
-bool
- log_to_stderr = TRUE, /* should log go to stderr? */
- log_to_syslog = TRUE, /* should log go to syslog? */
- log_to_perpeer= FALSE; /* should log go to per-IP file? */
-
-bool
- logged_txt_warning = FALSE; /* should we complain about finding KEY? */
-
-/* should we complain when we find no local id */
-bool
- logged_myid_fqdn_txt_warning = FALSE,
- logged_myid_ip_txt_warning = FALSE,
- logged_myid_fqdn_key_warning = FALSE,
- logged_myid_ip_key_warning = FALSE;
-
-/* may include trailing / */
-const char *base_perpeer_logdir = PERPEERLOGDIR;
-static int perpeer_count = 0;
-
-/* from sys/queue.h */
-static CIRCLEQ_HEAD(,connection) perpeer_list;
-
-
-/* Context for logging.
- *
- * Global variables: must be carefully adjusted at transaction boundaries!
- * If the context provides a whack file descriptor, messages
- * should be copied to it -- see whack_log()
- */
-int whack_log_fd = NULL_FD; /* only set during whack_handle() */
-struct state *cur_state = NULL; /* current state, for diagnostics */
-struct connection *cur_connection = NULL; /* current connection, for diagnostics */
-const ip_address *cur_from = NULL; /* source of current current message */
-u_int16_t cur_from_port; /* host order */
-
-void
-init_log(const char *program)
-{
- if (log_to_stderr)
- setbuf(stderr, NULL);
- if (log_to_syslog)
- openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
-
- CIRCLEQ_INIT(&perpeer_list);
-}
-
-void
-close_peerlog(void)
-{
- /* end of circular queue is given by pointer to "HEAD"
- * BUT if the queue is not initialized, this won't be true
- * so we must guard by test perpeer_list.cqh_first != NULL
- */
- if (perpeer_list.cqh_first != NULL)
- while (perpeer_list.cqh_first != (void *)&perpeer_list)
- perpeer_logclose(perpeer_list.cqh_first);
-}
-
-void
-close_log(void)
-{
- if (log_to_syslog)
- closelog();
-
- close_peerlog();
-}
-
-/* Sanitize character string in situ: turns dangerous characters into \OOO.
- * With a bit of work, we could use simpler reps for \\, \r, etc.,
- * but this is only to protect against something that shouldn't be used.
- * Truncate resulting string to what fits in buffer.
- */
-static size_t
-sanitize(char *buf, size_t size)
-{
-# define UGLY_WIDTH 4 /* width for ugly character: \OOO */
- size_t len;
- size_t added = 0;
- char *p;
-
- passert(size >= UGLY_WIDTH); /* need room to swing cat */
-
- /* find right side of string to be sanitized and count
- * number of columns to be added. Stop on end of string
- * or lack of room for more result.
- */
- for (p = buf; *p != '\0' && &p[added] < &buf[size - UGLY_WIDTH]; )
- {
- unsigned char c = *p++;
-
- if (c == '\\' || !isprint(c))
- added += UGLY_WIDTH - 1;
- }
-
- /* at this point, p points after last original character to be
- * included. added is how many characters are added to sanitize.
- * so p[added] will point after last sanitized character.
- */
-
- p[added] = '\0';
- len = &p[added] - buf;
-
- /* scan backwards, copying characters to their new home
- * and inserting the expansions for ugly characters.
- * It is finished when no more shifting is required.
- * This is a predecrement loop.
- */
- while (added != 0)
- {
- char fmtd[UGLY_WIDTH + 1];
- unsigned char c;
-
- while ((c = *--p) != '\\' && isprint(c))
- p[added] = c;
- added -= UGLY_WIDTH - 1;
- snprintf(fmtd, sizeof(fmtd), "\\%03o", c);
- memcpy(p + added, fmtd, UGLY_WIDTH);
- }
- return len;
-# undef UGLY_WIDTH
-}
-
-/* format a string for the log, with suitable prefixes.
- * A format starting with ~ indicates that this is a reprocessing
- * of the message, so prefixing and quoting is suppressed.
- */
-static void
-fmt_log(char *buf, size_t buf_len, const char *fmt, va_list ap)
-{
- bool reproc = *fmt == '~';
- size_t ps;
- struct connection *c = cur_state != NULL ? cur_state->st_connection
- : cur_connection;
-
- buf[0] = '\0';
- if (reproc)
- fmt++; /* ~ at start of format suppresses this prefix */
- else if (c != NULL)
- {
- /* start with name of connection */
- char *const be = buf + buf_len;
- char *bp = buf;
-
- snprintf(bp, be - bp, "\"%s\"", c->name);
- bp += strlen(bp);
-
- /* if it fits, put in any connection instance information */
- if (be - bp > CONN_INST_BUF)
- {
- fmt_conn_instance(c, bp);
- bp += strlen(bp);
- }
-
- if (cur_state != NULL)
- {
- /* state number */
- snprintf(bp, be - bp, " #%lu", cur_state->st_serialno);
- bp += strlen(bp);
- }
- snprintf(bp, be - bp, ": ");
- }
- else if (cur_from != NULL)
- {
- /* peer's IP address */
- /* Note: must not use ip_str() because our caller might! */
- char ab[ADDRTOT_BUF];
-
- (void) addrtot(cur_from, 0, ab, sizeof(ab));
- snprintf(buf, buf_len, "packet from %s:%u: "
- , ab, (unsigned)cur_from_port);
- }
-
- ps = strlen(buf);
- vsnprintf(buf + ps, buf_len - ps, fmt, ap);
- if (!reproc)
- (void)sanitize(buf, buf_len);
-}
-
-static void
-perpeer_logclose(struct connection *c)
-{
- /* only free/close things if we had used them! */
- if (c->log_file != NULL)
- {
- passert(perpeer_count > 0);
-
- CIRCLEQ_REMOVE(&perpeer_list, c, log_link);
- perpeer_count--;
- fclose(c->log_file);
- c->log_file=NULL;
- }
-}
-
-void
-perpeer_logfree(struct connection *c)
-{
- perpeer_logclose(c);
- if (c->log_file_name != NULL)
- {
- pfree(c->log_file_name);
- c->log_file_name = NULL;
- c->log_file_err = FALSE;
- }
-}
-
-/* open the per-peer log */
-static void
-open_peerlog(struct connection *c)
-{
- syslog(LOG_INFO, "opening log file for conn %s", c->name);
-
- if (c->log_file_name == NULL)
- {
- char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];
- int peernamelen, lf_len;
-
- addrtot(&c->spd.that.host_addr, 'Q', peername, sizeof(peername));
- peernamelen = strlen(peername);
-
- /* copy IP address, turning : and . into / */
- {
- char c, *p, *q;
-
- p = peername;
- q = dname;
- do {
- c = *p++;
- if (c == '.' || c == ':')
- c = '/';
- *q++ = c;
- } while (c != '\0');
- }
-
- lf_len = peernamelen * 2
- + strlen(base_perpeer_logdir)
- + sizeof("//.log")
- + 1;
- c->log_file_name = alloc_bytes(lf_len, "per-peer log file name");
-
- fprintf(stderr, "base dir |%s| dname |%s| peername |%s|"
- , base_perpeer_logdir, dname, peername);
- snprintf(c->log_file_name, lf_len, "%s/%s/%s.log"
- , base_perpeer_logdir, dname, peername);
-
- syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name);
- }
-
- /* now open the file, creating directories if necessary */
-
- { /* create the directory */
- char *dname;
- int bpl_len = strlen(base_perpeer_logdir);
- char *slashloc;
-
- dname = clone_str(c->log_file_name, "temp copy of file name");
- dname = dirname(dname);
-
- if (access(dname, W_OK) != 0)
- {
- if (errno != ENOENT)
- {
- if (c->log_file_err)
- {
- syslog(LOG_CRIT, "can not write to %s: %s"
- , dname, strerror(errno));
- c->log_file_err = TRUE;
- pfree(dname);
- return;
- }
- }
-
- /* directory does not exist, walk path creating dirs */
- /* start at base_perpeer_logdir */
- slashloc = dname + bpl_len;
- slashloc++; /* since, by construction there is a slash
- right there */
-
- while (*slashloc != '\0')
- {
- char saveslash;
-
- /* look for next slash */
- while (*slashloc != '\0' && *slashloc != '/') slashloc++;
-
- saveslash = *slashloc;
-
- *slashloc = '\0';
-
- if (mkdir(dname, 0750) != 0 && errno != EEXIST)
- {
- syslog(LOG_CRIT, "can not create dir %s: %s"
- , dname, strerror(errno));
- c->log_file_err = TRUE;
- pfree(dname);
- return;
- }
- syslog(LOG_DEBUG, "created new directory %s", dname);
- *slashloc = saveslash;
- slashloc++;
- }
- }
-
- pfree(dname);
- }
-
- c->log_file = fopen(c->log_file_name, "a");
- if (c->log_file == NULL)
- {
- if (c->log_file_err)
- {
- syslog(LOG_CRIT, "logging system can not open %s: %s"
- , c->log_file_name, strerror(errno));
- c->log_file_err = TRUE;
- }
- return;
- }
-
- /* look for a connection to close! */
- while (perpeer_count >= MAX_PEERLOG_COUNT)
- {
- /* can not be NULL because perpeer_count > 0 */
- passert(perpeer_list.cqh_last != (void *)&perpeer_list);
-
- perpeer_logclose(perpeer_list.cqh_last);
- }
-
- /* insert this into the list */
- CIRCLEQ_INSERT_HEAD(&perpeer_list, c, log_link);
- passert(c->log_file != NULL);
- perpeer_count++;
-}
-
-/* log a line to cur_connection's log */
-static void
-peerlog(const char *prefix, const char *m)
-{
- if (cur_connection == NULL)
- {
- /* we can not log it in this case. Oh well. */
- return;
- }
-
- if (cur_connection->log_file == NULL)
- {
- open_peerlog(cur_connection);
- }
-
- /* despite our attempts above, we may not be able to open the file. */
- if (cur_connection->log_file != NULL)
- {
- char datebuf[32];
- time_t n;
- struct tm *t;
-
- time(&n);
- t = localtime(&n);
-
- strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);
- fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);
-
- /* now move it to the front of the list */
- CIRCLEQ_REMOVE(&perpeer_list, cur_connection, log_link);
- CIRCLEQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
- }
-}
-
-void
-plog(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
- if (log_to_perpeer)
- peerlog("", m);
-
- whack_log(RC_LOG, "~%s", m);
-}
-
-void
-loglog(int mess_no, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
- if (log_to_perpeer)
- peerlog("", m);
-
- whack_log(mess_no, "~%s", m);
-}
-
-void
-log_errno_routine(int e, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
- if (log_to_perpeer)
- {
- peerlog(strerror(e), m);
- }
-
- whack_log(RC_LOG_SERIOUS
- , "~ERROR: %s. Errno %d: %s", m, e, strerror(e));
-}
-
-void
-exit_log(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s\n", m);
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s", m);
- if (log_to_perpeer)
- peerlog("FATAL ERROR: ", m);
-
- whack_log(RC_LOG_SERIOUS, "~FATAL ERROR: %s", m);
-
- exit_pluto(1);
-}
-
-void
-exit_log_errno_routine(int e, const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- if (log_to_perpeer)
- peerlog(strerror(e), m);
-
- whack_log(RC_LOG_SERIOUS
- , "~FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
-
- exit_pluto(1);
-}
-
-/* emit message to whack.
- * form is "ddd statename text" where
- * - ddd is a decimal status code (RC_*) as described in whack.h
- * - text is a human-readable annotation
- */
-#ifdef DEBUG
-static volatile sig_atomic_t dying_breath = FALSE;
-#endif
-
-void
-whack_log(int mess_no, const char *message, ...)
-{
- int wfd = whack_log_fd != NULL_FD ? whack_log_fd
- : cur_state != NULL ? cur_state->st_whack_sock
- : NULL_FD;
-
- if (wfd != NULL_FD
-#ifdef DEBUG
- || dying_breath
-#endif
- )
- {
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
- int prelen = snprintf(m, sizeof(m), "%03d ", mess_no);
-
- passert(prelen >= 0);
-
- va_start(args, message);
- fmt_log(m+prelen, sizeof(m)-prelen, message, args);
- va_end(args);
-
-#if DEBUG
- if (dying_breath)
- {
- /* status output copied to log */
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m + prelen);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m + prelen);
- if (log_to_perpeer)
- peerlog("", m);
- }
-#endif
-
- if (wfd != NULL_FD)
- {
- /* write to whack socket, but suppress possible SIGPIPE */
- size_t len = strlen(m);
-#ifdef MSG_NOSIGNAL /* depends on version of glibc??? */
- m[len] = '\n'; /* don't need NUL, do need NL */
- (void) send(wfd, m, len + 1, MSG_NOSIGNAL);
-#else /* !MSG_NOSIGNAL */
- int r;
- struct sigaction act
- , oldact;
-
- m[len] = '\n'; /* don't need NUL, do need NL */
- act.sa_handler = SIG_IGN;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0; /* no nothing */
- r = sigaction(SIGPIPE, &act, &oldact);
- passert(r == 0);
-
- (void) write(wfd, m, len + 1);
-
- r = sigaction(SIGPIPE, &oldact, NULL);
- passert(r == 0);
-#endif /* !MSG_NOSIGNAL */
- }
- }
-}
-
-/* Build up a diagnostic in a static buffer.
- * Although this would be a generally useful function, it is very
- * hard to come up with a discipline that prevents different uses
- * from interfering. It is intended that by limiting it to building
- * diagnostics, we will avoid this problem.
- * Juggling is performed to allow an argument to be a previous
- * result: the new string may safely depend on the old one. This
- * restriction is not checked in any way: violators will produce
- * confusing results (without crashing!).
- */
-char diag_space[sizeof(diag_space)];
-
-err_t
-builddiag(const char *fmt, ...)
-{
- static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
- char t[sizeof(diag_space)]; /* build result here first */
- va_list args;
-
- va_start(args, fmt);
- t[0] = '\0'; /* in case nothing terminates string */
- vsnprintf(t, sizeof(t), fmt, args);
- va_end(args);
- strcpy(diag_space, t);
- return diag_space;
-}
-
-/* Debugging message support */
-
-#ifdef DEBUG
-
-void
-switch_fail(int n, const char *file_str, unsigned long line_no)
-{
- char buf[30];
-
- snprintf(buf, sizeof(buf), "case %d unexpected", n);
- passert_fail(buf, file_str, line_no);
-}
-
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
-{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- if (!dying_breath)
- {
- dying_breath = TRUE;
- show_status(TRUE, NULL);
- }
- abort(); /* exiting correctly doesn't always work */
-}
-
-void
-pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
-{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
-}
-
-lset_t
- base_debugging = DBG_NONE, /* default to reporting nothing */
- cur_debugging = DBG_NONE;
-
-void
-extra_debugging(const struct connection *c)
-{
- if(c == NULL)
- {
- reset_debugging();
- return;
- }
-
- if (c!= NULL && c->extra_debugging != 0)
- {
- plog("enabling for connection: %s"
- , bitnamesof(debug_bit_names, c->extra_debugging & ~cur_debugging));
- cur_debugging |= c->extra_debugging;
- }
-}
-
-/* log a debugging message (prefixed by "| ") */
-
-void
-DBG_log(const char *message, ...)
-{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- (void)sanitize(m, sizeof(m));
-
- if (log_to_stderr)
- fprintf(stderr, "| %s\n", m);
- if (log_to_syslog)
- syslog(LOG_DEBUG, "| %s", m);
- if (log_to_perpeer)
- peerlog("| ", m);
-}
-
-/* dump raw bytes in hex to stderr (for lack of any better destination) */
-
-void
-DBG_dump(const char *label, const void *p, size_t len)
-{
-# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
-# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
- char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
- char *bp;
- const unsigned char *cp = p;
-
- bp = buf;
-
- if (label != NULL && label[0] != '\0')
- {
- /* Handle the label. Care must be taken to avoid buffer overrun. */
- size_t llen = strlen(label);
-
- if (llen + 1 > sizeof(buf))
- {
- DBG_log("%s", label);
- }
- else
- {
- strcpy(buf, label);
- if (buf[llen-1] == '\n')
- {
- buf[llen-1] = '\0'; /* get rid of newline */
- DBG_log("%s", buf);
- }
- else if (llen < DUMP_LABEL_WIDTH)
- {
- bp = buf + llen;
- }
- else
- {
- DBG_log("%s", buf);
- }
- }
- }
-
- do {
- int i, j;
-
- for (i = 0; len!=0 && i!=4; i++)
- {
- *bp++ = ' ';
- for (j = 0; len!=0 && j!=4; len--, j++)
- {
- static const char hexdig[] = "0123456789abcdef";
-
- *bp++ = ' ';
- *bp++ = hexdig[(*cp >> 4) & 0xF];
- *bp++ = hexdig[*cp & 0xF];
- cp++;
- }
- }
- *bp = '\0';
- DBG_log("%s", buf);
- bp = buf;
- } while (len != 0);
-# undef DUMP_LABEL_WIDTH
-# undef DUMP_WIDTH
-}
-
-#endif /* DEBUG */
-
-void
-show_status(bool all, const char *name)
-{
- if (all)
- {
- show_ifaces_status();
- show_myid_status();
- show_debug_status();
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
- }
- show_connections_status(all, name);
- show_states_status(all, name);
-#ifdef KLIPS
- show_shunt_status();
-#endif
-}
-
-/* ip_str: a simple to use variant of addrtot.
- * It stores its result in a static buffer.
- * This means that newer calls overwrite the storage of older calls.
- * Note: this is not used in any of the logging functions, so their
- * callers may use it.
- */
-const char *
-ip_str(const ip_address *src)
-{
- static char buf[ADDRTOT_BUF];
-
- addrtot(src, 0, buf, sizeof(buf));
- return buf;
-}
-
-/*
- * a routine that attempts to schedule itself daily.
- *
- */
-
-void
-daily_log_reset(void)
-{
- /* now perform actions */
- logged_txt_warning = FALSE;
-
- logged_myid_fqdn_txt_warning = FALSE;
- logged_myid_ip_txt_warning = FALSE;
- logged_myid_fqdn_key_warning = FALSE;
- logged_myid_ip_key_warning = FALSE;
-}
-
-void
-daily_log_event(void)
-{
- struct tm *ltime;
- time_t n, interval;
-
- /* attempt to schedule oneself to midnight, local time
- * do this by getting seconds in the day, and delaying
- * by 86400 - hour*3600+minutes*60+seconds.
- */
- time(&n);
- ltime = localtime(&n);
- interval = (24 * 60 * 60)
- - (ltime->tm_sec
- + ltime->tm_min * 60
- + ltime->tm_hour * 3600);
-
- event_schedule(EVENT_LOG_DAILY, interval, NULL);
-
- daily_log_reset();
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/programs/pluto/log.h b/programs/pluto/log.h
deleted file mode 100644
index 0bf8219aa..000000000
--- a/programs/pluto/log.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/* logging definitions
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: log.h,v 1.4 2005/07/11 18:33:45 as Exp $
- */
-
-#include <freeswan.h>
-
-#define LOG_WIDTH 1024 /* roof of number of chars in log line */
-
-#ifndef PERPERRLOGDIR
-#define PERPERRLOGDIR "/var/log/pluto/peer"
-#endif
-
-/* our versions of assert: log result */
-
-#ifdef DEBUG
-
-extern void passert_fail(const char *pred_str
- , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-
-extern void pexpect_log(const char *pred_str
- , const char *file_str, unsigned long line_no);
-
-# define impossible() passert_fail("impossible", __FILE__, __LINE__)
-
-extern void switch_fail(int n
- , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-
-# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
-
-# define passert(pred) { \
- if (!(pred)) \
- passert_fail(#pred, __FILE__, __LINE__); \
- }
-
-# define pexpect(pred) { \
- if (!(pred)) \
- pexpect_log(#pred, __FILE__, __LINE__); \
- }
-
-/* assert that an err_t is NULL; evaluate exactly once */
-# define happy(x) { \
- err_t ugh = x; \
- if (ugh != NULL) \
- passert_fail(ugh, __FILE__, __LINE__); \
- }
-
-#else /*!DEBUG*/
-
-# define impossible() abort()
-# define bad_case(n) abort()
-# define passert(pred) { } /* do nothing */
-# define happy(x) { (void) x; } /* evaluate non-judgementally */
-
-#endif /*!DEBUG*/
-
-
-extern bool
- log_to_stderr, /* should log go to stderr? */
- log_to_syslog, /* should log go to syslog? */
- log_to_perpeer; /* should log go to per-IP file? */
-
-extern const char *base_perpeer_logdir;
-
-/* maximum number of files to keep open for per-peer log files */
-#define MAX_PEERLOG_COUNT 16
-
-/* Context for logging.
- *
- * Global variables: must be carefully adjusted at transaction boundaries!
- * All are to be left in RESET condition and will be checked.
- * There are several pairs of routines to set and reset them.
- * If the context provides a whack file descriptor, messages
- * should be copied to it -- see whack_log()
- */
-extern int whack_log_fd; /* only set during whack_handle() */
-extern struct state *cur_state; /* current state, for diagnostics */
-extern struct connection *cur_connection; /* current connection, for diagnostics */
-extern const ip_address *cur_from; /* source of current current message */
-extern u_int16_t cur_from_port; /* host order */
-
-#ifdef DEBUG
-
- extern lset_t cur_debugging; /* current debugging level */
-
- extern void extra_debugging(const struct connection *c);
-
-# define reset_debugging() { cur_debugging = base_debugging; }
-
-# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
- && cur_state == NULL \
- && cur_connection == NULL \
- && cur_from == NULL \
- && cur_debugging == base_debugging)
-
-#else /*!DEBUG*/
-
-# define extra_debugging(c) { }
-
-# define reset_debugging() { }
-
-# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
- && cur_state == NULL \
- && cur_connection == NULL \
- && cur_from == NULL)
-
-#endif /*!DEBUG*/
-
-#define reset_globals() { \
- whack_log_fd = NULL_FD; \
- cur_state = NULL; \
- cur_from = NULL; \
- reset_cur_connection(); \
- }
-
-
-#define set_cur_connection(c) { \
- cur_connection = (c); \
- extra_debugging(c); \
- }
-
-#define reset_cur_connection() { \
- cur_connection = NULL; \
- reset_debugging(); \
- }
-
-
-#define set_cur_state(s) { \
- cur_state = (s); \
- extra_debugging((s)->st_connection); \
- }
-
-#define reset_cur_state() { \
- cur_state = NULL; \
- reset_debugging(); \
- }
-
-extern void init_log(const char *program);
-extern void close_log(void);
-extern void plog(const char *message, ...) PRINTF_LIKE(1);
-extern void exit_log(const char *message, ...) PRINTF_LIKE(1) NEVER_RETURNS;
-
-/* close of all per-peer logging */
-extern void close_peerlog(void);
-
-/* free all per-peer log resources */
-extern void perpeer_logfree(struct connection *c);
-
-
-
-/* the following routines do a dance to capture errno before it is changed
- * A call must doubly parenthesize the argument list (no varargs macros).
- * The first argument must be "e", the local variable that captures errno.
- */
-#define log_errno(a) { int e = errno; log_errno_routine a; }
-extern void log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2);
-#define exit_log_errno(a) { int e = errno; exit_log_errno_routine a; }
-extern void exit_log_errno_routine(int e, const char *message, ...) PRINTF_LIKE(2) NEVER_RETURNS NEVER_RETURNS;
-
-extern void whack_log(int mess_no, const char *message, ...) PRINTF_LIKE(2);
-
-/* Log to both main log and whack log
- * Much like log, actually, except for specifying mess_no.
- */
-extern void loglog(int mess_no, const char *message, ...) PRINTF_LIKE(2);
-
-/* show status, usually on whack log */
-extern void show_status(bool all, const char *name);
-
-/* Build up a diagnostic in a static buffer.
- * Although this would be a generally useful function, it is very
- * hard to come up with a discipline that prevents different uses
- * from interfering. It is intended that by limiting it to building
- * diagnostics, we will avoid this problem.
- * Juggling is performed to allow an argument to be a previous
- * result: the new string may safely depend on the old one. This
- * restriction is not checked in any way: violators will produce
- * confusing results (without crashing!).
- */
-extern char diag_space[LOG_WIDTH]; /* output buffer, but can be occupied at call */
-extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1);
-
-#ifdef DEBUG
-
-extern lset_t base_debugging; /* bits selecting what to report */
-
-#define DBGP(cond) (cur_debugging & (cond))
-#define DBG(cond, action) { if (DBGP(cond)) { action ; } }
-
-extern void DBG_log(const char *message, ...) PRINTF_LIKE(1);
-extern void DBG_dump(const char *label, const void *p, size_t len);
-#define DBG_dump_chunk(label, ch) DBG_dump(label, (ch).ptr, (ch).len)
-
-#else /*!DEBUG*/
-
-#define DBG(cond, action) { } /* do nothing */
-
-#endif /*!DEBUG*/
-
-#define DBG_cond_dump(cond, label, p, len) DBG(cond, DBG_dump(label, p, len))
-#define DBG_cond_dump_chunk(cond, label, ch) DBG(cond, DBG_dump_chunk(label, ch))
-
-
-/* ip_str: a simple to use variant of addrtot.
- * It stores its result in a static buffer.
- * This means that newer calls overwrite the storage of older calls.
- * Note: this is not used in any of the logging functions, so their
- * callers may use it.
- */
-extern const char *ip_str(const ip_address *src);
-
-/*
- * call this routine to reset daily items.
- */
-extern void daily_log_reset(void);
-extern void daily_log_event(void);
-
-/*
- * some events are to be logged only occasionally.
- */
-extern bool logged_txt_warning;
-extern bool logged_myid_ip_txt_warning;
-extern bool logged_myid_ip_key_warning;
-extern bool logged_myid_fqdn_txt_warning;
-extern bool logged_myid_fqdn_key_warning;
diff --git a/programs/pluto/md2.c b/programs/pluto/md2.c
deleted file mode 100644
index d6465477d..000000000
--- a/programs/pluto/md2.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
- */
-
-/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
- rights reserved.
-
- License to copy and use this software is granted for
- non-commercial Internet Privacy-Enhanced Mail provided that it is
- identified as the "RSA Data Security, Inc. MD2 Message Digest
- Algorithm" in all material mentioning or referencing this software
- or this function.
-
- RSA Data Security, Inc. makes no representations concerning either
- the merchantability of this software or the suitability of this
- software for any particular purpose. It is provided "as is"
- without express or implied warranty of any kind.
-
- These notices must be retained in any copies of any part of this
- documentation and/or software.
- */
-
-#include "md2.h"
-
-#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
-
-static void MD2Transform PROTO_LIST
- ((unsigned char [16], unsigned char [16], const unsigned char [16]));
-
-#ifdef HAVEMEMCOPY
-#include <memory.h>
-#define MD2_memcpy memcpy
-#define MD2_memset memset
-#else
-#ifdef HAVEBCOPY
-#define MD2_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
-#define MD2_memset(_a,_b,_c) memset((_a), '\0',(_c))
-#else
-static void MD2_memcpy PROTO_LIST ((POINTER, CONST_POINTER, unsigned int));
-static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int));
-#endif
-#endif
-
-/* Permutation of 0..255 constructed from the digits of pi. It gives a
- "random" nonlinear byte substitution operation.
- */
-static unsigned char PI_SUBST[256] = {
- 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
- 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
- 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
- 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
- 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
- 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
- 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
- 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
- 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
- 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
- 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
- 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
- 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
- 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
- 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
- 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
- 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
- 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
-};
-
-static const unsigned char *PADDING[] = {
- (const unsigned char *)"",
- (const unsigned char *)"\001",
- (const unsigned char *)"\002\002",
- (const unsigned char *)"\003\003\003",
- (const unsigned char *)"\004\004\004\004",
- (const unsigned char *)"\005\005\005\005\005",
- (const unsigned char *)"\006\006\006\006\006\006",
- (const unsigned char *)"\007\007\007\007\007\007\007",
- (const unsigned char *)"\010\010\010\010\010\010\010\010",
- (const unsigned char *)"\011\011\011\011\011\011\011\011\011",
- (const unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
- (const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
- (const unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
- (const unsigned char *)
- "\015\015\015\015\015\015\015\015\015\015\015\015\015",
- (const unsigned char *)
- "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
- (const unsigned char *)
- "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
- (const unsigned char *)
- "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
-};
-
-/* MD2 initialization. Begins an MD2 operation, writing a new context.
- */
-void MD2Init (context)
-MD2_CTX *context; /* context */
-{
- context->count = 0;
- MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
- MD2_memset
- ((POINTER)context->checksum, 0, sizeof (context->checksum));
-}
-
-/* MD2 block update operation. Continues an MD2 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD2Update (context, input, inputLen)
-MD2_CTX *context; /* context */
-const unsigned char *input; /* input block */
-unsigned int inputLen; /* length of input block */
-{
- unsigned int i, index, partLen;
-
- /* Update number of bytes mod 16 */
- index = context->count;
- context->count = (index + inputLen) & 0xf;
-
- partLen = 16 - index;
-
- /* Transform as many times as possible.
- */
- if (inputLen >= partLen) {
- MD2_memcpy
- ((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen);
- MD2Transform (context->state, context->checksum, context->buffer);
-
- for (i = partLen; i + 15 < inputLen; i += 16)
- MD2Transform (context->state, context->checksum, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD2_memcpy
- ((POINTER)&context->buffer[index], (CONST_POINTER)&input[i],
- inputLen-i);
-}
-
-/* MD2 finalization. Ends an MD2 message-digest operation, writing the
- message digest and zeroizing the context.
- */
-void MD2Final (digest, context)
-
-unsigned char digest[16]; /* message digest */
-MD2_CTX *context; /* context */
-{
- unsigned int index, padLen;
-
- /* Pad out to multiple of 16.
- */
- index = context->count;
- padLen = 16 - index;
- MD2Update (context, PADDING[padLen], padLen);
-
- /* Extend with checksum */
- MD2Update (context, context->checksum, 16);
-
- /* Store state in digest */
- MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16);
-
- /* Zeroize sensitive information.
- */
- MD2_memset ((POINTER)context, 0, sizeof (*context));
-}
-
-/* MD2 basic transformation. Transforms state and updates checksum
- based on block.
- */
-static void MD2Transform (state, checksum, block)
-unsigned char state[16];
-unsigned char checksum[16];
-const unsigned char block[16];
-{
- unsigned int i, j, t;
- unsigned char x[48];
-
- /* Form encryption block from state, block, state ^ block.
- */
- MD2_memcpy ((POINTER)x, (CONST_POINTER)state, 16);
- MD2_memcpy ((POINTER)x+16, (CONST_POINTER)block, 16);
- for (i = 0; i < 16; i++)
- x[i+32] = state[i] ^ block[i];
-
- /* Encrypt block (18 rounds).
- */
- t = 0;
- for (i = 0; i < 18; i++) {
- for (j = 0; j < 48; j++)
- t = x[j] ^= PI_SUBST[t];
- t = (t + i) & 0xff;
- }
-
- /* Save new state */
- MD2_memcpy ((POINTER)state, (POINTER)x, 16);
-
- /* Update checksum.
- */
- t = checksum[15];
- for (i = 0; i < 16; i++)
- t = checksum[i] ^= PI_SUBST[block[i] ^ t];
-
- /* Zeroize sensitive information.
- */
- MD2_memset ((POINTER)x, 0, sizeof (x));
-}
-
-#ifndef HAVEMEMCOPY
-#ifndef HAVEBCOPY
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-static void MD2_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- output[i] = input[i];
-}
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-static void MD2_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
-#endif
-
diff --git a/programs/pluto/md2.h b/programs/pluto/md2.h
deleted file mode 100644
index b3b48dd92..000000000
--- a/programs/pluto/md2.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
- The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#define PROTOTYPES 1
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-typedef const unsigned char *CONST_POINTER;
-
-/* UINT2 defines a two byte word */
-typedef unsigned short int UINT2;
-
-/* UINT4 defines a four byte word */
-typedef unsigned long int UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-#endif
-
-/* MD2.H - header file for MD2C.C
- */
-
-/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
- rights reserved.
-
- License to copy and use this software is granted for
- non-commercial Internet Privacy-Enhanced Mail provided that it is
- identified as the "RSA Data Security, Inc. MD2 Message Digest
- Algorithm" in all material mentioning or referencing this software
- or this function.
-
- RSA Data Security, Inc. makes no representations concerning either
- the merchantability of this software or the suitability of this
- software for any particular purpose. It is provided "as is"
- without express or implied warranty of any kind.
-
- These notices must be retained in any copies of any part of this
- documentation and/or software.
- */
-
-/* MD2 context. */
-typedef struct {
- unsigned char state[16]; /* state */
- unsigned char checksum[16]; /* checksum */
- unsigned int count; /* number of bytes, modulo 16 */
- unsigned char buffer[16]; /* input buffer */
-} MD2_CTX;
-
-void MD2Init PROTO_LIST ((MD2_CTX *));
-void MD2Update PROTO_LIST
- ((MD2_CTX *, const unsigned char *, unsigned int));
-void MD2Final PROTO_LIST ((unsigned char [16], MD2_CTX *));
-
-#define _MD2_H_
diff --git a/programs/pluto/md5.c b/programs/pluto/md5.c
deleted file mode 100644
index 5d75e38a4..000000000
--- a/programs/pluto/md5.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
- * changes to accomodate it in the kernel by ji.
- * Minor changes to make 64 bit clean by Peter Onion (i.e. using u_int*_t).
- */
-
-/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/*
- * Additions by JI
- *
- * HAVEMEMCOPY is defined if mem* routines are available
- *
- * HAVEHTON is defined if htons() and htonl() can be used
- * for big/little endian conversions
- *
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
-#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
-
-#include "md5.h"
-
-#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
-
-/* Constants for MD5Transform routine.
- */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-#define MD5Transform _MD5Transform
-
-static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define Encode MD5_memcpy
-#define Decode MD5_memcpy
-#else
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, unsigned char *, unsigned int));
-#endif
-
-#ifdef HAVEMEMCOPY
-#include <memory.h>
-#define MD5_memcpy memcpy
-#define MD5_memset memset
-#else
-#ifdef HAVEBCOPY
-#define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
-#define MD5_memset(_a,_b,_c) memset((_a), '\0',(_c))
-#else
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-#endif
-#endif
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-void MD5Init (context)
-MD5_CTX *context; /* context */
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants.
-*/
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD5Update (context, input, inputLen)
-MD5_CTX *context; /* context */
-const unsigned char *input; /* input block */
-UINT4 inputLen; /* length of input block */
-{
- UINT4 i;
- unsigned int index, partLen;
-
- /* Compute number of bytes mod 64 */
- index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
- context->count[1]++;
- context->count[1] += (inputLen >> 29);
-
- partLen = 64 - index;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen) {
- MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
- MD5Transform (context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform (context->state, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i], inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void MD5Final (digest, context)
-unsigned char digest[16]; /* message digest */
-MD5_CTX *context; /* context */
-{
- unsigned char bits[8];
- unsigned int index, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64.
-*/
- index = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (context, bits, 8);
-
- if (digest != NULL) /* Bill Simpson's padding */
- {
- /* store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information.
- */
- MD5_memset ((POINTER)context, 0, sizeof (*context));
- }
-}
-
-/* MD5 basic transformation. Transforms state based on block.
- */
-static void MD5Transform (state, block)
-UINT4 state[4];
-const unsigned char block[64];
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void Encode (output, input, len)
-unsigned char *output;
-UINT4 *input;
-unsigned int len;
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void Decode (output, input, len)
-UINT4 *output;
-unsigned char *input;
-unsigned int len;
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-#endif
-
-#ifndef HAVEMEMCOPY
-#ifndef HAVEBCOPY
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-
-static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
-
- output[i] = input[i];
-}
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
-#endif
-
diff --git a/programs/pluto/md5.h b/programs/pluto/md5.h
deleted file mode 100644
index 9b29bc46e..000000000
--- a/programs/pluto/md5.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
- The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#define PROTOTYPES 1
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-typedef const unsigned char *CONSTPOINTER;
-
-/* UINT2 defines a two byte word */
-typedef u_int16_t UINT2;
-
-/* UINT4 defines a four byte word */
-typedef u_int32_t UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-#endif
-
-/* MD5.H - header file for MD5C.C
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-void MD5Init PROTO_LIST ((MD5_CTX *));
-void MD5Update PROTO_LIST
- ((MD5_CTX *, const unsigned char *, UINT4));
-void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
-
-#define _MD5_H_
diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c
deleted file mode 100644
index 620c595fb..000000000
--- a/programs/pluto/modecfg.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* Mode config related functions
- * Copyright (C) 2001-2002 Colubris Networks
- * Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
- * Copyright (C) 2003-2004 Xelerance Corporation
- * Copyright (C) 2006-2007 Andreas Steffen - Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: modecfg.c,v 1.16 2007/01/29 08:27:54 as Exp $
- *
- * This code originally written by Colubris Networks, Inc.
- * Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
- * Porting to 2.x by Sean Mathews
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "demux.h"
-#include "timer.h"
-#include "ipsec_doi.h"
-#include "log.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h"
-#include "modecfg.h"
-#include "whack.h"
-#include "xauth.h"
-
-#define MAX_XAUTH_TRIES 3
-
-#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
- | LELEM(INTERNAL_IP4_NETMASK) \
- | LELEM(INTERNAL_IP4_DNS) \
- | LELEM(INTERNAL_IP4_NBNS) \
- | LELEM(APPLICATION_VERSION) \
- )
-
-#define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) )
-
-#define UNITY_BANNER_STR "Welcome to strongSwan - the Linux VPN Solution!\n"
-
-/*
- * Addresses assigned (usually via ModeCfg) to the Initiator
- */
-typedef struct internal_addr internal_addr_t;
-
-struct internal_addr
-{
- lset_t attr_set;
- lset_t xauth_attr_set;
- lset_t unity_attr_set;
-
- /* ModeCfg variables */
- ip_address ipaddr;
- ip_address dns[2];
- ip_address wins[2];
-
- char *unity_banner;
-
- /* XAUTH variables */
- u_int16_t xauth_type;
- xauth_t xauth_secret;
- bool xauth_status;
-};
-
-/*
- * Initialize an internal_addr struct
- */
-static void
-init_internal_addr(internal_addr_t *ia)
-{
- ia->attr_set = LEMPTY;
- ia->xauth_attr_set = LEMPTY;
- ia->xauth_secret.user_name = empty_chunk;
- ia->xauth_secret.user_password = empty_chunk;
- ia->xauth_type = XAUTH_TYPE_GENERIC;
- ia->xauth_status = XAUTH_STATUS_FAIL;
- ia->unity_attr_set = LEMPTY;
- ia->unity_banner = NULL;
-
- anyaddr(AF_INET, &ia->ipaddr);
- anyaddr(AF_INET, &ia->dns[0]);
- anyaddr(AF_INET, &ia->dns[1]);
- anyaddr(AF_INET, &ia->wins[0]);
- anyaddr(AF_INET, &ia->wins[1]);
-}
-
-/*
- * get internal IP address for a connection
- */
-static void
-get_internal_addr(struct connection *c, internal_addr_t *ia)
-{
- if (isanyaddr(&c->spd.that.host_srcip))
- {
- /* not defined in connection - fetch it from LDAP */
- }
- else
- {
- char srcip[ADDRTOT_BUF];
-
- ia->ipaddr = c->spd.that.host_srcip;
-
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("assigning virtual IP source address %s", srcip);
- }
-
- if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
- {
- c->spd.that.client.addr = ia->ipaddr;
- c->spd.that.client.maskbits = 32;
- c->spd.that.has_client = TRUE;
-
- ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
- }
-
- if (!isanyaddr(&ia->dns[0])) /* We got DNS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
-
- if (!isanyaddr(&ia->wins[0])) /* We got WINS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
-}
-
-/*
- * Set srcip and client subnet to internal IP address
- */
-static bool
-set_internal_addr(struct connection *c, internal_addr_t *ia)
-{
- if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
- && !isanyaddr(&ia->ipaddr))
- {
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip)
- || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
- {
- char srcip[ADDRTOT_BUF];
-
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
- else
- {
- char old_srcip[ADDRTOT_BUF];
- char new_srcip[ADDRTOT_BUF];
-
- addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
- addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
- plog("replacing virtual IP source address %s by %s"
- , old_srcip, new_srcip);
- }
-
- /* setting srcip */
- c->spd.this.host_srcip = ia->ipaddr;
-
- /* setting client subnet to srcip/32 */
- addrtosubnet(&ia->ipaddr, &c->spd.this.client);
- setportof(0, &c->spd.this.client.addr);
- c->spd.this.has_client = TRUE;
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * Compute HASH of Mode Config.
- */
-static size_t
-modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
- , const struct state *st)
-{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("ModeCfg HASH computed:");
- DBG_dump("", dest, ctx.hmac_digest_size)
- )
- return ctx.hmac_digest_size;
-}
-
-
-/*
- * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
- */
-static stf_status
-modecfg_build_msg(struct state *st, pb_stream *rbody
- , u_int16_t msg_type
- , internal_addr_t *ia
- , u_int16_t ap_id)
-{
- u_char *r_hash_start, *r_hashval;
-
- START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
-
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr,attrval;
- int attr_type;
- int dns_idx, wins_idx;
- bool dont_advance;
- bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
- bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
- lset_t attr_set = ia->attr_set;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = msg_type;
- attrh.isama_identifier = ap_id;
-
- if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
- return STF_INTERNAL_ERROR;
-
- attr_type = 0;
- dns_idx = 0;
- wins_idx = 0;
-
- while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
- {
- if (attr_set == LEMPTY)
- {
- if (is_xauth_attr_set)
- {
- attr_set = ia->xauth_attr_set;
- attr_type = XAUTH_BASE;
- is_xauth_attr_set = FALSE;
- }
- else
- {
- attr_set = ia->unity_attr_set;
- attr_type = UNITY_BASE;
- is_unity_attr_set = FALSE;
- }
- }
-
- dont_advance = FALSE;
-
- if (attr_set & 1)
- {
- const u_char *byte_ptr;
- u_int len;
-
- /* ISAKMP attr out */
- if (attr_type == XAUTH_TYPE)
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_type;
- }
- else if (attr_type == XAUTH_STATUS)
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_status;
- }
- else
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
- }
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (!isanyaddr(&ia->ipaddr))
- {
- len = addrbytesptr(&ia->ipaddr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_addr");
- }
- break;
- case INTERNAL_IP4_NETMASK:
- {
- u_int mask;
-#if 0
- char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t,m=st->st_connection->that.host_addr.maskbit;
- for (t=0; t<4; t++)
- {
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- }
-#endif
- if (st->st_connection->spd.this.client.maskbits == 0)
- mask = 0;
- else
- mask = 0xffffffff * 1;
- out_raw(&mask, 4, &attrval, "IP4_mask");
- }
- break;
- case INTERNAL_IP4_SUBNET:
- {
- char mask[4];
- char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t;
- int m = st->st_connection->spd.this.client.maskbits;
-
- for (t = 0; t < 4; t++)
- {
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- if (m < 0)
- m = 0;
- }
- len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_subnet");
- out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
- }
- break;
- case INTERNAL_IP4_DNS:
- if (!isanyaddr(&ia->dns[dns_idx]))
- {
- len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_dns");
- }
- if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case INTERNAL_IP4_NBNS:
- if (!isanyaddr(&ia->wins[wins_idx]))
- {
- len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_wins");
- }
- if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case XAUTH_TYPE:
- break;
- case XAUTH_USER_NAME:
- if (ia->xauth_secret.user_name.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_name.ptr
- , ia->xauth_secret.user_name.len
- , &attrval, "xauth_user_name");
- }
- break;
- case XAUTH_USER_PASSWORD:
- if (ia->xauth_secret.user_password.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_password.ptr
- , ia->xauth_secret.user_password.len
- , &attrval, "xauth_user_password");
- }
- break;
- case XAUTH_STATUS:
- break;
- case UNITY_BANNER:
- if (ia->unity_banner != NULL)
- {
- out_raw(ia->unity_banner
- , strlen(ia->unity_banner)
- , &attrval, "UNITY_BANNER");
- }
- break;
- default:
- plog("attempt to send unsupported mode cfg attribute %s."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
- }
- close_output_pbs(&attrval);
- }
- if (!dont_advance)
- {
- attr_type++;
- attr_set >>= 1;
- }
- }
- close_message(&strattr);
- }
-
- modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
- close_message(rbody);
- encrypt_message(rbody, st);
- return STF_OK;
-}
-
-/*
- * Send ModeCfg message
- */
-static stf_status
-modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
-{
- pb_stream msg;
- pb_stream rbody;
- char buf[BUF_LEN];
-
- /* set up attr */
- init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
-
- /* this is the beginning of a new exchange */
- st->st_msgid = generate_msgid(st);
- init_phase2_iv(st, &st->st_msgid);
-
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* ATTR out */
- modecfg_build_msg(st, &rbody
- , isama_type
- , ia
- , 0 /* XXX isama_id */
- );
-
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
-
- /* Transmit */
- send_packet(st, "ModeCfg msg");
-
- if (st->st_event->ev_type != EVENT_RETRANSMIT)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
- }
- return STF_OK;
-}
-
-/*
- * Parse a ModeCfg attribute payload
- */
-static stf_status
-modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
-{
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
- {
- u_int16_t attr_type;
- u_int16_t attr_len;
-
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
- {
- return STF_FAIL;
- }
- attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
- attr_len = attr.isaat_lv;
-
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (attr_len == 4)
- {
- initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
- }
- /* fall through to set attribute flag */
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- case INTERNAL_ADDRESS_EXPIRY:
- case INTERNAL_IP4_DHCP:
- case INTERNAL_IP6_ADDRESS:
- case INTERNAL_IP6_NETMASK:
- case INTERNAL_IP6_DNS:
- case INTERNAL_IP6_NBNS:
- case INTERNAL_IP6_DHCP:
- case SUPPORTED_ATTRIBUTES:
- case INTERNAL_IP6_SUBNET:
- ia->attr_set |= LELEM(attr_type);
- break;
- case APPLICATION_VERSION:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- ia->attr_set |= LELEM(attr_type);
- break;
- case XAUTH_TYPE:
- ia->xauth_type = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_NAME:
- setchunk(ia->xauth_secret.user_name, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_PASSWORD:
- setchunk(ia->xauth_secret.user_password, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_STATUS:
- ia->xauth_status = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_MESSAGE:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case XAUTH_PASSCODE:
- case XAUTH_CHALLENGE:
- case XAUTH_DOMAIN:
- case XAUTH_NEXT_PIN:
- case XAUTH_ANSWER:
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case UNITY_DDNS_HOSTNAME:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case UNITY_BANNER:
- case UNITY_SAVE_PASSWD:
- case UNITY_DEF_DOMAIN:
- case UNITY_SPLITDNS_NAME:
- case UNITY_SPLIT_INCLUDE:
- case UNITY_NATT_PORT:
- case UNITY_LOCAL_LAN:
- case UNITY_PFS:
- case UNITY_FW_TYPE:
- case UNITY_BACKUP_SERVERS:
- ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
- break;
- default:
- plog("unsupported ModeCfg attribute %s received."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
- }
- }
- return STF_OK;
-}
-
-/*
- * Parse a ModeCfg message
- */
-static stf_status
-modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
- , internal_addr_t *ia)
-{
- struct state *const st = md->st;
- struct payload_digest *p;
- stf_status stat;
-
- st->st_msgid = md->hdr.isa_msgid;
-
- CHECK_QUICK_HASH(md, modecfg_hash(hash_val
- , hash_pbs->roof
- , md->message_pbs.roof, st)
- , "MODECFG-HASH", "ISAKMP_CFG_MSG");
-
- /* process the ModeCfg payloads received */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- internal_addr_t ia_candidate;
-
- init_internal_addr(&ia_candidate);
-
- if (p->payload.attribute.isama_type == isama_type)
- {
- *isama_id = p->payload.attribute.isama_identifier;
-
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
- if (stat == STF_OK)
- {
- /* return with a valid set of attributes */
- *ia = ia_candidate;
- return STF_OK;
- }
- }
- else
- {
- plog("expected %s, got %s instead (ignored)"
- , enum_name(&attr_msg_type_names, isama_type)
- , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
-
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
- }
- if (stat != STF_OK)
- return stat;
- }
- return STF_IGNORE;
-}
-
-/*
- * Send ModeCfg request message from client to server in pull mode
- */
-stf_status
-modecfg_send_request(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
-
- ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
-
- plog("sending ModeCfg request");
- st->st_state = STATE_MODE_CFG_I1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
-}
-
-/* STATE_MODE_CFG_R0:
- * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
- *
- * used in ModeCfg pull mode, on the server (responder)
- */
-stf_status
-modecfg_inR0(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- bool want_unity_banner;
- stf_status stat, stat_build;
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
-
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
-
- if (want_unity_banner)
- {
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
- }
-
- plog("sending ModeCfg reply");
-
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- st->st_msgid = 0;
- return STF_OK;
-}
-
-/* STATE_MODE_CFG_I1:
- * HDR*, HASH, ATTR(REPLY=IP)
- *
- * used in ModeCfg pull mode, on the client (initiator)
- */
-stf_status
-modecfg_inI1(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
-
- plog("parsing ModeCfg reply");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- st->st_msgid = 0;
- return STF_OK;
-}
-
-
-/*
- * Send ModeCfg set message from server to client in push mode
- */
-stf_status
-modecfg_send_set(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
-
-#ifdef CISCO_QUIRKS
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
-#endif
-
- plog("sending ModeCfg set");
- st->st_state = STATE_MODE_CFG_R3;
- stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
-}
-
-/* STATE_MODE_CFG_I0:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
- *
- * used in ModeCfg push mode, on the client (initiator).
- */
-stf_status
-modecfg_inI0(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- lset_t attr_set, unity_attr_set;
- stf_status stat, stat_build;
-
- plog("parsing ModeCfg set");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
-
- /* prepare ModeCfg ack which sends zero length attributes */
- attr_set = ia.attr_set;
- unity_attr_set = ia.unity_attr_set;
- init_internal_addr(&ia);
- ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
- ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
-
- plog("sending ModeCfg ack");
-
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- st->st_msgid = 0;
- return STF_OK;
-}
-
-/* STATE_MODE_CFG_R3:
- * HDR*, HASH, ATTR(ACK,OK)
- *
- * used in ModeCfg push mode, on the server (responder)
- */
-stf_status
-modecfg_inR3(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
-
- plog("parsing ModeCfg ack");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_msgid = 0;
- return STF_OK;
-}
-
-/*
- * Send XAUTH credentials request (username + password)
- */
-stf_status
-xauth_send_request(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
-
- plog("sending XAUTH request");
- st->st_state = STATE_XAUTH_R1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_xauth.started = TRUE;
- return stat;
-}
-
-/* STATE_XAUTH_I0:
- * HDR*, HASH, ATTR(REQ) --> HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD)
- *
- * used on the XAUTH client (initiator)
- */
-stf_status
-xauth_inI0(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
- bool xauth_type_present;
-
- plog("parsing XAUTH request");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* check XAUTH attributes */
- xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
-
- if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
- {
- plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
-
- /* prepare XAUTH reply */
- init_internal_addr(&ia);
-
- if (stat == STF_OK)
- {
- /* get user credentials using a plugin function */
- if (!xauth_module.get_secret(&ia.xauth_secret))
- {
- plog("xauth user credentials not found");
- stat = STF_FAIL;
- }
- }
- if (stat == STF_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("my xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("my xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
- if (xauth_type_present)
- ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
- }
- else
- {
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = XAUTH_STATUS_FAIL;
- }
-
- plog("sending XAUTH reply");
-
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- if (stat == STF_OK)
- {
- st->st_xauth.started = TRUE;
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH reply msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH reply msg");
- send_packet(st, "XAUTH reply msg");
- delete_state(st);
- return STF_IGNORE;
- }
-}
-
-/* STATE_XAUTH_R1:
- * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
- *
- * used on the XAUTH server (responder)
- */
-stf_status
-xauth_inR1(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
-
- plog("parsing XAUTH reply");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* did the client return an XAUTH FAIL status? */
- if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
- {
- plog("received FAIL status in XAUTH reply");
-
- /* client is not able to do XAUTH, delete ISAKMP SA */
- delete_state(st);
- return STF_IGNORE;
- }
-
- /* check XAUTH reply */
- if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("peer xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("peer xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- /* verify the user credentials using a plugn function */
- st->st_xauth.status = xauth_module.verify_secret(&ia.xauth_secret);
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
- }
-
- /* prepare XAUTH set which sends the authentication status */
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
-
- plog("sending XAUTH status:");
-
- stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat_build != STF_OK)
- return stat_build;
- return STF_OK;
-}
-
-/* STATE_XAUTH_I1:
- * HDR*, HASH, ATTR(STATUS) --> HDR*, HASH, ATTR(ACK)
- *
- * used on the XAUTH client (initiator)
- */
-stf_status
-xauth_inI1(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
-
- plog("parsing XAUTH status");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
- return stat;
- }
-
- st->st_xauth.status = ia.xauth_status;
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
-
- plog("sending XAUTH ack");
- init_internal_addr(&ia);
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- if (st->st_xauth.status)
- {
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH ack msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH ack msg");
- send_packet(st, "XAUTH ack msg");
- delete_state(st);
- return STF_IGNORE;
- }
-}
-
-/* STATE_XAUTH_R2:
- * HDR*, ATTR(STATUS), HASH --> Done
- *
- * used on the XAUTH server (responder)
- */
-stf_status
-xauth_inR2(struct msg_digest *md)
-{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
-
- plog("parsing XAUTH ack");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_msgid = 0;
- if (st->st_xauth.status)
- {
- return STF_OK;
- }
- else
- {
- delete_state(st);
- return STF_IGNORE;
- }
-}
diff --git a/programs/pluto/modecfg.h b/programs/pluto/modecfg.h
deleted file mode 100644
index 4fce75aef..000000000
--- a/programs/pluto/modecfg.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Mode Config related functions
- * Copyright (C) 2001-2002 Colubris Networks
- * Copyright (C) 2003-2004 Xelerance Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: modecfg.h,v 1.4 2007/01/10 00:36:19 as Exp $
- */
-
-#ifndef _MODECFG_H
-#define _MODECFG_H
-
-struct state;
-struct msg_digest;
-
-/* ModeConfig pull mode start function */
-extern stf_status modecfg_send_request(struct state *st);
-
-/* ModeConfig pull mode state transition functions */
-extern stf_status modecfg_inR0(struct msg_digest *md);
-extern stf_status modecfg_inI1(struct msg_digest *md);
-
-/* ModeConfig push mode start function */
-extern stf_status modecfg_send_set(struct state *st);
-
-/* ModeConfig push mode state transition functions */
-extern stf_status modecfg_inI0(struct msg_digest *md);
-extern stf_status modecfg_inR3(struct msg_digest *md);
-
-/* XAUTH start function */
-extern stf_status xauth_send_request(struct state *st);
-
-/* XAUTH state transition funcgtions */
-extern stf_status xauth_inI0(struct msg_digest *md);
-extern stf_status xauth_inR1(struct msg_digest *md);
-extern stf_status xauth_inI1(struct msg_digest *md);
-extern stf_status xauth_inR2(struct msg_digest *md);
-
-#endif /* _MODECFG_H */
diff --git a/programs/pluto/mp_defs.c b/programs/pluto/mp_defs.c
deleted file mode 100644
index 7ad896751..000000000
--- a/programs/pluto/mp_defs.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* some multiprecision utilities
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: mp_defs.c,v 1.1 2006/01/05 12:37:11 as Exp $
- */
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-
-/* Convert MP_INT to network form (binary octets, big-endian).
- * We do the malloc; caller must eventually do free.
- */
-chunk_t
-mpz_to_n(const MP_INT *mp, size_t bytes)
-{
- chunk_t r;
- MP_INT temp1, temp2;
- int i;
-
- r.len = bytes;
- r.ptr = alloc_bytes(r.len, "host representation of large integer");
-
- mpz_init(&temp1);
- mpz_init(&temp2);
-
- mpz_set(&temp1, mp);
-
- for (i = r.len-1; i >= 0; i--)
- {
- r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
- mpz_set(&temp1, &temp2);
- }
-
- passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
- mpz_clear(&temp1);
- mpz_clear(&temp2);
-
- return r;
-}
-
-/* Convert network form (binary bytes, big-endian) to MP_INT.
- * The *mp must not be previously mpz_inited.
- */
-void
-n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen)
-{
- size_t i;
-
- mpz_init_set_ui(mp, 0);
-
- for (i = 0; i != nlen; i++)
- {
- mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
- mpz_add_ui(mp, mp, nbytes[i]);
- }
-}
diff --git a/programs/pluto/mp_defs.h b/programs/pluto/mp_defs.h
deleted file mode 100644
index 744a028d1..000000000
--- a/programs/pluto/mp_defs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* some multiprecision utilities
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: mp_defs.h,v 1.2 2006/01/06 11:40:45 as Exp $
- */
-
-#ifndef _MP_DEFS_H
-#define _MP_DEFS_H
-
-#include <gmp.h>
-
-#include "defs.h"
-
-extern void n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen);
-extern chunk_t mpz_to_n(const MP_INT *mp, size_t bytes);
-
-/* var := mod(base ** exp, mod), ensuring var is mpz_inited */
-#define mpz_init_powm(flag, var, base, exp, mod) { \
- if (!(flag)) \
- mpz_init(&(var)); \
- (flag) = TRUE; \
- mpz_powm(&(var), &(base), &(exp), (mod)); \
- }
-
-#endif /* _MP_DEFS_H */
diff --git a/programs/pluto/nat_traversal.c b/programs/pluto/nat_traversal.c
deleted file mode 100644
index 2f5ba3cb4..000000000
--- a/programs/pluto/nat_traversal.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/* FreeS/WAN NAT-Traversal
- * Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: nat_traversal.c,v 1.8 2005/01/06 22:36:58 as Exp $
- */
-
-#ifdef NAT_TRAVERSAL
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "server.h"
-#include "state.h"
-#include "connections.h"
-#include "packet.h"
-#include "demux.h"
-#include "kernel.h"
-#include "whack.h"
-#include "timer.h"
-
-
-#include "cookie.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h"
-#include "vendor.h"
-#include "ike_alg.h"
-#include "nat_traversal.h"
-
-/* #define FORCE_NAT_TRAVERSAL */
-#define NAT_D_DEBUG
-#define NAT_T_SUPPORT_LAST_DRAFTS
-
-#ifndef SOL_UDP
-#define SOL_UDP 17
-#endif
-
-#ifndef UDP_ESPINUDP
-#define UDP_ESPINUDP 100
-#endif
-
-#define DEFAULT_KEEP_ALIVE_PERIOD 20
-
-#ifdef _IKE_ALG_H
-/* Alg patch: hash_digest_len -> hash_digest_size */
-#define hash_digest_len hash_digest_size
-#endif
-
-bool nat_traversal_enabled = FALSE;
-bool nat_traversal_support_non_ike = FALSE;
-bool nat_traversal_support_port_floating = FALSE;
-
-static unsigned int _kap = 0;
-static unsigned int _ka_evt = 0;
-static bool _force_ka = 0;
-
-static const char *natt_version = "0.6c";
-
-void init_nat_traversal (bool activate, unsigned int keep_alive_period,
- bool fka, bool spf)
-{
- nat_traversal_enabled = activate;
- nat_traversal_support_non_ike = activate;
-#ifdef NAT_T_SUPPORT_LAST_DRAFTS
- nat_traversal_support_port_floating = activate ? spf : FALSE;
-#endif
- _force_ka = fka;
- _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD;
- plog(" including NAT-Traversal patch (Version %s)%s%s%s"
- , natt_version, activate ? "" : " [disabled]"
- , activate & fka ? " [Force KeepAlive]" : ""
- , activate & !spf ? " [Port Floating disabled]" : "");
-}
-
-static void disable_nat_traversal (int type)
-{
- if (type == ESPINUDP_WITH_NON_IKE)
- nat_traversal_support_non_ike = FALSE;
- else
- nat_traversal_support_port_floating = FALSE;
-
- if (!nat_traversal_support_non_ike &&
- !nat_traversal_support_port_floating)
- nat_traversal_enabled = FALSE;
-}
-
-static void _natd_hash(const struct hash_desc *hasher, char *hash,
- u_int8_t *icookie, u_int8_t *rcookie,
- const ip_address *ip, u_int16_t port)
-{
- union hash_ctx ctx;
-
- if (is_zero_cookie(icookie))
- DBG_log("_natd_hash: Warning, icookie is zero !!");
- if (is_zero_cookie(rcookie))
- DBG_log("_natd_hash: Warning, rcookie is zero !!");
-
- /**
- * draft-ietf-ipsec-nat-t-ike-01.txt
- *
- * HASH = HASH(CKY-I | CKY-R | IP | Port)
- *
- * All values in network order
- */
- hasher->hash_init(&ctx);
- hasher->hash_update(&ctx, icookie, COOKIE_SIZE);
- hasher->hash_update(&ctx, rcookie, COOKIE_SIZE);
- switch (addrtypeof(ip)) {
- case AF_INET:
- hasher->hash_update(&ctx, (const u_char *)&ip->u.v4.sin_addr.s_addr
- , sizeof(ip->u.v4.sin_addr.s_addr));
- break;
- case AF_INET6:
- hasher->hash_update(&ctx, (const u_char *)&ip->u.v6.sin6_addr.s6_addr
- , sizeof(ip->u.v6.sin6_addr.s6_addr));
- break;
- }
- hasher->hash_update(&ctx, (const u_char *)&port, sizeof(u_int16_t));
- hasher->hash_final(hash, &ctx);
-#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("_natd_hash: hasher=%p(%d)", hasher, (int)hasher->hash_digest_len);
- DBG_dump("_natd_hash: icookie=", icookie, COOKIE_SIZE);
- DBG_dump("_natd_hash: rcookie=", rcookie, COOKIE_SIZE);
- switch (addrtypeof(ip)) {
- case AF_INET:
- DBG_dump("_natd_hash: ip=", &ip->u.v4.sin_addr.s_addr
- , sizeof(ip->u.v4.sin_addr.s_addr));
- break;
- }
- DBG_log("_natd_hash: port=%d", port);
- DBG_dump("_natd_hash: hash=", hash, hasher->hash_digest_len);
- );
-#endif
-}
-
-/* Add NAT-Traversal VIDs (supported ones)
- * used when we are Initiator
- */
-bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs)
-{
- bool r = TRUE;
-
- if (nat_traversal_support_port_floating)
- {
- u_int8_t last_np = nat_traversal_support_non_ike ?
- ISAKMP_NEXT_VID : np;
-
- if (r)
- r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC);
- if (r)
- r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03);
- if (r)
- r = out_vendorid(last_np, outs, VID_NATT_IETF_02);
- }
- if (nat_traversal_support_non_ike)
- {
- if (r)
- r = out_vendorid(np, outs, VID_NATT_IETF_00);
- }
- return r;
-}
-
-u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid)
-{
- switch (nat_t_vid)
- {
- case VID_NATT_IETF_00:
- return LELEM(NAT_TRAVERSAL_IETF_00_01);
- case VID_NATT_IETF_02:
- case VID_NATT_IETF_02_N:
- case VID_NATT_IETF_03:
- return LELEM(NAT_TRAVERSAL_IETF_02_03);
- case VID_NATT_RFC:
- return LELEM(NAT_TRAVERSAL_RFC);
- }
- return 0;
-}
-
-void nat_traversal_natd_lookup(struct msg_digest *md)
-{
- char hash[MAX_DIGEST_LEN];
- struct payload_digest *p;
- struct state *st = md->st;
- int i;
-
- if (!st || !md->iface || !st->st_oakley.hasher)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return;
- }
-
- /** Count NAT-D **/
- for (p = md->chain[ISAKMP_NEXT_NATD_RFC], i=0; p != NULL; p = p->next, i++);
-
- /*
- * We need at least 2 NAT-D (1 for us, many for peer)
- */
- if (i < 2)
- {
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negociation", i);
- st->nat_traversal = 0;
- return;
- }
-
- /*
- * First one with my IP & port
- */
- p = md->chain[ISAKMP_NEXT_NATD_RFC];
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
- &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
-
- if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
- memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0))
- {
-#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
- DBG_dump("expected NAT-D:", hash
- , st->st_oakley.hasher->hash_digest_len);
- DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
- )
-#endif
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
- }
-
- /*
- * The others with sender IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
- &(md->sender), ntohs(md->sender_port));
- for (p = p->next, i=0 ; p != NULL; p = p->next)
- {
- if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
- memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0)
- {
- i++;
- }
- }
- if (!i)
- {
-#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
- DBG_dump("expected NAT-D:", hash
- , st->st_oakley.hasher->hash_digest_len);
- p = md->chain[ISAKMP_NEXT_NATD_RFC];
- for (p = p->next, i=0 ; p != NULL; p = p->next)
- {
- DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
- }
- )
-#endif
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
- }
-#ifdef FORCE_NAT_TRAVERSAL
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
-#endif
-}
-
-bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
- struct msg_digest *md)
-{
- char hash[MAX_DIGEST_LEN];
- struct state *st = md->st;
-
- if (!st || !st->st_oakley.hasher)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return FALSE;
- }
-
- DBG(DBG_EMITTING,
- DBG_log("sending NATD payloads")
- )
-
- /*
- * First one with sender IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
- is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
- &(md->sender),
-#ifdef FORCE_NAT_TRAVERSAL
- 0
-#else
- ntohs(md->sender_port)
-#endif
- );
- if (!out_generic_raw((st->nat_traversal & NAT_T_WITH_RFC_VALUES
- ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS), &isakmp_nat_d, outs,
- hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"))
- {
- return FALSE;
- }
-
- /*
- * Second one with my IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
- is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
- &(md->iface->addr),
-#ifdef FORCE_NAT_TRAVERSAL
- 0
-#else
- ntohs(st->st_connection->spd.this.host_port)
-#endif
- );
- return (out_generic_raw(np, &isakmp_nat_d, outs,
- hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"));
-}
-
-/*
- * nat_traversal_natoa_lookup()
- *
- * Look for NAT-OA in message
- */
-void nat_traversal_natoa_lookup(struct msg_digest *md)
-{
- struct payload_digest *p;
- struct state *st = md->st;
- int i;
- ip_address ip;
-
- if (!st || !md->iface)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return;
- }
-
- /* Initialize NAT-OA */
- anyaddr(AF_INET, &st->nat_oa);
-
- /* Count NAT-OA **/
- for (p = md->chain[ISAKMP_NEXT_NATOA_RFC], i=0; p != NULL; p = p->next, i++);
-
- DBG(DBG_NATT,
- DBG_log("NAT-Traversal: received %d NAT-OA.", i)
- )
-
- if (i == 0)
- return;
-
- if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER)))
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
- "ignored because peer is not NATed", i);
- return;
- }
-
- if (i > 1)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
- "using first, ignoring others", i);
- }
-
- /* Take first */
- p = md->chain[ISAKMP_NEXT_NATOA_RFC];
-
- DBG(DBG_PARSING,
- DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
- );
-
- switch (p->payload.nat_oa.isanoa_idtype)
- {
- case ID_IPV4_ADDR:
- if (pbs_left(&p->pbs) == sizeof(struct in_addr))
- {
- initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET, &ip);
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv4 NAT-OA "
- "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
- return;
- }
- break;
- case ID_IPV6_ADDR:
- if (pbs_left(&p->pbs) == sizeof(struct in6_addr))
- {
- initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET6, &ip);
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv6 NAT-OA "
- "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
- return;
- }
- break;
- default:
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "invalid ID Type (%d) in NAT-OA - ignored",
- p->payload.nat_oa.isanoa_idtype);
- return;
- }
-
- DBG(DBG_NATT,
- {
- char ip_t[ADDRTOT_BUF];
- addrtot(&ip, 0, ip_t, sizeof(ip_t));
-
- DBG_log("received NAT-OA: %s", ip_t);
- }
- )
-
- if (isanyaddr(&ip))
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %%any NAT-OA...");
- else
- st->nat_oa = ip;
-}
-
-bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
- struct state *st)
-{
- struct isakmp_nat_oa natoa;
- pb_stream pbs;
- unsigned char ip_val[sizeof(struct in6_addr)];
- size_t ip_len = 0;
- ip_address *ip;
-
- if ((!st) || (!st->st_connection))
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return FALSE;
- }
- ip = &(st->st_connection->spd.this.host_addr);
-
- memset(&natoa, 0, sizeof(natoa));
- natoa.isanoa_np = np;
-
- switch (addrtypeof(ip))
- {
- case AF_INET:
- ip_len = sizeof(ip->u.v4.sin_addr.s_addr);
- memcpy(ip_val, &ip->u.v4.sin_addr.s_addr, ip_len);
- natoa.isanoa_idtype = ID_IPV4_ADDR;
- break;
- case AF_INET6:
- ip_len = sizeof(ip->u.v6.sin6_addr.s6_addr);
- memcpy(ip_val, &ip->u.v6.sin6_addr.s6_addr, ip_len);
- natoa.isanoa_idtype = ID_IPV6_ADDR;
- break;
- default:
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "invalid addrtypeof()=%d", addrtypeof(ip));
- return FALSE;
- }
-
- if (!out_struct(&natoa, &isakmp_nat_oa, outs, &pbs))
- return FALSE;
-
- if (!out_raw(ip_val, ip_len, &pbs, "NAT-OA"))
- return FALSE;
-
- DBG(DBG_NATT,
- DBG_dump("NAT-OA (S):", ip_val, ip_len)
- )
-
- close_output_pbs(&pbs);
- return TRUE;
-}
-
-void nat_traversal_show_result (u_int32_t nt, u_int16_t sport)
-{
- const char *mth = NULL, *rslt = NULL;
-
- switch (nt & NAT_TRAVERSAL_METHOD)
- {
- case LELEM(NAT_TRAVERSAL_IETF_00_01):
- mth = natt_type_bitnames[0];
- break;
- case LELEM(NAT_TRAVERSAL_IETF_02_03):
- mth = natt_type_bitnames[1];
- break;
- case LELEM(NAT_TRAVERSAL_RFC):
- mth = natt_type_bitnames[2];
- break;
- }
-
- switch (nt & NAT_T_DETECTED)
- {
- case 0:
- rslt = "no NAT detected";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_ME):
- rslt = "i am NATed";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
- rslt = "peer is NATed";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
- rslt = "both are NATed";
- break;
- }
-
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: Result using %s: %s",
- mth ? mth : "unknown method",
- rslt ? rslt : "unknown result"
- );
-
- if ((nt & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))
- && (sport == IKE_UDP_PORT)
- && ((nt & NAT_T_WITH_PORT_FLOATING)==0))
- {
- loglog(RC_LOG_SERIOUS,
- "Warning: peer is NATed but source port is still udp/%d. "
- "Ipsec-passthrough NAT device suspected -- NAT-T may not work.",
- IKE_UDP_PORT
- );
- }
-}
-
-int nat_traversal_espinudp_socket (int sk, u_int32_t type)
-{
- int r = setsockopt(sk, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
-
- if (r < 0 && errno == ENOPROTOOPT)
- {
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: ESPINUDP(%d) not supported by kernel -- "
- "NAT-T disabled", type);
- disable_nat_traversal(type);
- }
- return r;
-}
-
-void nat_traversal_new_ka_event (void)
-{
- if (_ka_evt)
- return; /* event already scheduled */
-
- event_schedule(EVENT_NAT_T_KEEPALIVE, _kap, NULL);
- _ka_evt = 1;
-}
-
-static void nat_traversal_send_ka (struct state *st)
-{
- static unsigned char ka_payload = 0xff;
- chunk_t sav;
-
- DBG(DBG_NATT,
- DBG_log("ka_event: send NAT-KA to %s:%d",
- ip_str(&st->st_connection->spd.that.host_addr),
- st->st_connection->spd.that.host_port);
- )
-
- /* save state chunk */
- setchunk(sav, st->st_tpacket.ptr, st->st_tpacket.len);
-
- /* send keep alive */
- setchunk(st->st_tpacket, &ka_payload, 1);
- _send_packet(st, "NAT-T Keep Alive", FALSE);
-
- /* restore state chunk */
- setchunk(st->st_tpacket, sav.ptr, sav.len);
-}
-
-/**
- * Find ISAKMP States with NAT-T and send keep-alive
- */
-static void nat_traversal_ka_event_state (struct state *st, void *data)
-{
- unsigned int *_kap_st = (unsigned int *)data;
- const struct connection *c = st->st_connection;
-
- if (!c)
- return;
-
- if ((st->st_state == STATE_MAIN_R3 || st->st_state == STATE_MAIN_I4)
- && (st->nat_traversal & NAT_T_DETECTED)
- && ((st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
- {
- /*
- * - ISAKMP established
- * - NAT-Traversal detected
- * - NAT-KeepAlive needed (we are NATed)
- */
- if (c->newest_isakmp_sa != st->st_serialno)
- {
- /*
- * if newest is also valid, ignore this one, we will only use
- * newest.
- */
- struct state *st_newest;
-
- st_newest = state_with_serialno(c->newest_isakmp_sa);
- if (st_newest
- && (st_newest->st_state == STATE_MAIN_R3 || st_newest->st_state == STATE_MAIN_I4)
- && (st_newest->nat_traversal & NAT_T_DETECTED)
- && ((st_newest->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
- {
- return;
- }
- }
- set_cur_state(st);
- nat_traversal_send_ka(st);
- reset_cur_state();
- (*_kap_st)++;
- }
-}
-
-void nat_traversal_ka_event (void)
-{
- unsigned int _kap_st = 0;
-
- _ka_evt = 0; /* ready to be reschedule */
-
- for_each_state((void *)nat_traversal_ka_event_state, &_kap_st);
-
- /* if there are still states who needs Keep-Alive, schedule new event */
- if (_kap_st)
- nat_traversal_new_ka_event();
-}
-
-struct _new_mapp_nfo {
- ip_address addr;
- u_int16_t sport, dport;
-};
-
-static void nat_traversal_find_new_mapp_state (struct state *st, void *data)
-{
- struct connection *c = st->st_connection;
- struct _new_mapp_nfo *nfo = (struct _new_mapp_nfo *)data;
-
- if (c != NULL
- && sameaddr(&c->spd.that.host_addr, &(nfo->addr))
- && c->spd.that.host_port == nfo->sport)
- {
-
- /* change host port */
- c->spd.that.host_port = nfo->dport;
-
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- || IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- if (!update_ipsec_sa(st))
- {
- /*
- * If ipsec update failed, restore old port or we'll
- * not be able to update anymore.
- */
- c->spd.that.host_port = nfo->sport;
- }
- }
- }
-}
-
-static int nat_traversal_new_mapping(const ip_address *src, u_int16_t sport,
- const ip_address *dst, u_int16_t dport)
-{
- char srca[ADDRTOT_BUF], dsta[ADDRTOT_BUF];
- struct _new_mapp_nfo nfo;
-
- addrtot(src, 0, srca, ADDRTOT_BUF);
- addrtot(dst, 0, dsta, ADDRTOT_BUF);
-
- if (!sameaddr(src, dst))
- {
- loglog(RC_LOG_SERIOUS, "nat_traversal_new_mapping: "
- "address change currently not supported [%s:%d,%s:%d]",
- srca, sport, dsta, dport);
- return -1;
- }
-
- if (sport == dport)
- {
- /* no change */
- return 0;
- }
-
- DBG_log("NAT-T: new mapping %s:%d/%d)", srca, sport, dport);
-
- nfo.addr = *src;
- nfo.sport = sport;
- nfo.dport = dport;
-
- for_each_state((void *)nat_traversal_find_new_mapp_state, &nfo);
-
- return 0;
-}
-
-void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st)
-{
- struct connection *c = st ? st->st_connection : NULL;
- struct iface *i = NULL;
-
- if ((st == NULL) || (c == NULL))
- return;
-
- if (md)
- {
- /*
- * If source port has changed, update (including other states and
- * established kernel SA)
- */
- if (c->spd.that.host_port != md->sender_port)
- {
- nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
- &c->spd.that.host_addr, md->sender_port);
- }
-
- /*
- * If interface type has changed, update local port (500/4500)
- */
- if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !md->iface->ike_float)
- || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && md->iface->ike_float))
- {
- c->spd.this.host_port = (md->iface->ike_float)
- ? NAT_T_IKE_FLOAT_PORT : pluto_port;
-
- DBG(DBG_NATT,
- DBG_log("NAT-T: updating local port to %d", c->spd.this.host_port);
- );
- }
- }
-
- /*
- * If we're initiator and NAT-T (with port floating) is detected, we
- * need to change port (MAIN_I3 or QUICK_I1)
- */
- if ((st->st_state == STATE_MAIN_I3 || st->st_state == STATE_QUICK_I1)
- && (st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
- && (st->nat_traversal & NAT_T_DETECTED)
- && (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT))
- {
- DBG(DBG_NATT,
- DBG_log("NAT-T: floating to port %d", NAT_T_IKE_FLOAT_PORT);
- )
- c->spd.this.host_port = NAT_T_IKE_FLOAT_PORT;
- c->spd.that.host_port = NAT_T_IKE_FLOAT_PORT;
- /*
- * Also update pending connections or they will be deleted if uniqueids
- * option is set.
- */
- update_pending(st, st);
- }
-
- /*
- * Find valid interface according to local port (500/4500)
- */
- if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !c->interface->ike_float)
- || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && c->interface->ike_float))
- {
- for (i = interfaces; i != NULL; i = i->next)
- {
- if (sameaddr(&c->interface->addr, &i->addr)
- && i->ike_float != c->interface->ike_float)
- {
- DBG(DBG_NATT,
- DBG_log("NAT-T: using interface %s:%d", i->rname,
- i->ike_float ? NAT_T_IKE_FLOAT_PORT : pluto_port);
- )
- c->interface = i;
- break;
- }
- }
- }
-}
-
-struct _new_klips_mapp_nfo {
- struct sadb_sa *sa;
- ip_address src, dst;
- u_int16_t sport, dport;
-};
-
-static void nat_t_new_klips_mapp (struct state *st, void *data)
-{
- struct connection *c = st->st_connection;
- struct _new_klips_mapp_nfo *nfo = (struct _new_klips_mapp_nfo *)data;
-
- if (c != NULL && st->st_esp.present
- && sameaddr(&c->spd.that.host_addr, &(nfo->src))
- && st->st_esp.our_spi == nfo->sa->sadb_sa_spi)
- {
- nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
- &(nfo->dst), nfo->dport);
- }
-}
-
-void process_pfkey_nat_t_new_mapping(
- struct sadb_msg *msg __attribute__ ((unused)),
- struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-{
- struct _new_klips_mapp_nfo nfo;
- struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
- struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
- struct sockaddr *srca, *dsta;
- err_t ugh = NULL;
-
- nfo.sa = (void *) extensions[SADB_EXT_SA];
-
- if (!nfo.sa || !srcx || !dstx)
- {
- plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: "
- "got NULL params");
- return;
- }
-
- srca = ((struct sockaddr *)(void *)&srcx[1]);
- dsta = ((struct sockaddr *)(void *)&dstx[1]);
-
- if (srca->sa_family != AF_INET || dsta->sa_family != AF_INET)
- {
- ugh = "only AF_INET supported";
- }
- else
- {
- char text_said[SATOT_BUF];
- char _srca[ADDRTOT_BUF], _dsta[ADDRTOT_BUF];
- ip_said said;
-
- initaddr((const void *) &((const struct sockaddr_in *)srca)->sin_addr,
- sizeof(((const struct sockaddr_in *)srca)->sin_addr),
- srca->sa_family, &(nfo.src));
- nfo.sport = ntohs(((const struct sockaddr_in *)srca)->sin_port);
- initaddr((const void *) &((const struct sockaddr_in *)dsta)->sin_addr,
- sizeof(((const struct sockaddr_in *)dsta)->sin_addr),
- dsta->sa_family, &(nfo.dst));
- nfo.dport = ntohs(((const struct sockaddr_in *)dsta)->sin_port);
-
- DBG(DBG_NATT,
- initsaid(&nfo.src, nfo.sa->sadb_sa_spi, SA_ESP, &said);
- satot(&said, 0, text_said, SATOT_BUF);
- addrtot(&nfo.src, 0, _srca, ADDRTOT_BUF);
- addrtot(&nfo.dst, 0, _dsta, ADDRTOT_BUF);
- DBG_log("new klips mapping %s %s:%d %s:%d",
- text_said, _srca, nfo.sport, _dsta, nfo.dport);
- )
-
- for_each_state((void *)nat_t_new_klips_mapp, &nfo);
- }
-
- if (ugh != NULL)
- plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: %s", ugh);
-}
-
-#endif
-
diff --git a/programs/pluto/nat_traversal.h b/programs/pluto/nat_traversal.h
deleted file mode 100644
index 71222c54c..000000000
--- a/programs/pluto/nat_traversal.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* FreeS/WAN NAT-Traversal
- * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: nat_traversal.h,v 1.4 2004/07/27 21:11:30 as Exp $
- */
-
-#ifndef _NAT_TRAVERSAL_H
-#define _NAT_TRAVERSAL_H
-
-#include "packet.h"
-
-#define NAT_TRAVERSAL_IETF_00_01 1
-#define NAT_TRAVERSAL_IETF_02_03 2
-#define NAT_TRAVERSAL_RFC 3
-
-#define NAT_TRAVERSAL_NAT_BHND_ME 30
-#define NAT_TRAVERSAL_NAT_BHND_PEER 31
-
-#define NAT_TRAVERSAL_METHOD (0xffffffff - LELEM(30) - LELEM(31))
-
-/**
- * NAT-Traversal methods which need NAT-D
- */
-#define NAT_T_WITH_NATD \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which need NAT-OA
- */
-#define NAT_T_WITH_NATOA \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which use NAT-KeepAlive
- */
-#define NAT_T_WITH_KA \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
-/**
- * NAT-Traversal methods which use floating port
- */
-#define NAT_T_WITH_PORT_FLOATING \
- ( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
-
-/**
- * NAT-Traversal methods which use officials values (RFC)
- */
-#define NAT_T_WITH_RFC_VALUES \
- ( LELEM(NAT_TRAVERSAL_RFC) )
-
-/**
- * NAT-Traversal detected
- */
-#define NAT_T_DETECTED \
- ( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) )
-
-/**
- * NAT-T Port Floating
- */
-#define NAT_T_IKE_FLOAT_PORT 4500
-
-void init_nat_traversal (bool activate, unsigned int keep_alive_period,
- bool fka, bool spf);
-
-extern bool nat_traversal_enabled;
-extern bool nat_traversal_support_non_ike;
-extern bool nat_traversal_support_port_floating;
-
-/**
- * NAT-D
- */
-void nat_traversal_natd_lookup(struct msg_digest *md);
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
- struct msg_digest *md);
-#endif
-
-/**
- * NAT-OA
- */
-void nat_traversal_natoa_lookup(struct msg_digest *md);
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
- struct state *st);
-#endif
-
-/**
- * NAT-keep_alive
- */
-void nat_traversal_new_ka_event (void);
-void nat_traversal_ka_event (void);
-
-void nat_traversal_show_result (u_int32_t nt, u_int16_t sport);
-
-int nat_traversal_espinudp_socket (int sk, u_int32_t type);
-
-/**
- * Vendor ID
- */
-#ifndef PB_STREAM_UNDEFINED
-bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs);
-#endif
-u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid);
-
-void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st);
-
-/**
- * New NAT mapping
- */
-#ifdef __PFKEY_V2_H
-void process_pfkey_nat_t_new_mapping(
- struct sadb_msg *,
- struct sadb_ext *[SADB_EXT_MAX + 1]);
-#endif
-
-/**
- * IKE port floating
- */
-bool
-nat_traversal_port_float(struct state *st, struct msg_digest *md, bool in);
-
-/**
- * Encapsulation mode macro (see demux.c)
- */
-#define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
- ((st)->nat_traversal & NAT_T_DETECTED) \
- ? ( ((nat_t_policy) & POLICY_TUNNEL) \
- ? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
- ? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
- : (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
- ) \
- : ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
- ? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
- : (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
- ) \
- ) \
- : ( ((st)->st_policy & POLICY_TUNNEL) \
- ? (ENCAPSULATION_MODE_TUNNEL) \
- : (ENCAPSULATION_MODE_TRANSPORT) \
- ) \
- )
-
-#endif /* _NAT_TRAVERSAL_H */
-
diff --git a/programs/pluto/ocsp.c b/programs/pluto/ocsp.c
deleted file mode 100644
index f31b96c7f..000000000
--- a/programs/pluto/ocsp.c
+++ /dev/null
@@ -1,1568 +0,0 @@
-/* Support of the Online Certificate Status Protocol (OCSP)
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "rnd.h"
-#include "asn1.h"
-#include "certs.h"
-#include "smartcard.h"
-#include "oid.h"
-#include "whack.h"
-#include "pkcs1.h"
-#include "keys.h"
-#include "fetch.h"
-#include "ocsp.h"
-
-#define NONCE_LENGTH 16
-
-static const char *const cert_status_names[] = {
- "good",
- "revoked",
- "unknown",
- "undefined"
-};
-
-
-static const char *const response_status_names[] = {
- "successful",
- "malformed request",
- "internal error",
- "try later",
- "signature required",
- "unauthorized"
-};
-
-/* response container */
-typedef struct response response_t;
-
-struct response {
- chunk_t tbs;
- chunk_t responder_id_name;
- chunk_t responder_id_key;
- time_t produced_at;
- chunk_t responses;
- chunk_t nonce;
- int algorithm;
- chunk_t signature;
-};
-
-const response_t empty_response = {
- { NULL, 0 } , /* tbs */
- { NULL, 0 } , /* responder_id_name */
- { NULL, 0 } , /* responder_id_key */
- UNDEFINED_TIME, /* produced_at */
- { NULL, 0 } , /* single_response */
- { NULL, 0 } , /* nonce */
- OID_UNKNOWN , /* signature_algorithm */
- { NULL, 0 } /* signature */
-};
-
-/* single response container */
-typedef struct single_response single_response_t;
-
-struct single_response {
- single_response_t *next;
- int hash_algorithm;
- chunk_t issuer_name_hash;
- chunk_t issuer_key_hash;
- chunk_t serialNumber;
- cert_status_t status;
- time_t revocationTime;
- crl_reason_t revocationReason;
- time_t thisUpdate;
- time_t nextUpdate;
-};
-
-const single_response_t empty_single_response = {
- NULL , /* *next */
- OID_UNKNOWN , /* hash_algorithm */
- { NULL, 0 } , /* issuer_name_hash */
- { NULL, 0 } , /* issuer_key_hash */
- { NULL, 0 } , /* serial_number */
- CERT_UNDEFINED , /* status */
- UNDEFINED_TIME , /* revocationTime */
- REASON_UNSPECIFIED, /* revocationReason */
- UNDEFINED_TIME , /* this_update */
- UNDEFINED_TIME /* next_update */
-};
-
-
-/* list of single requests */
-typedef struct request_list request_list_t;
-struct request_list {
- chunk_t request;
- request_list_t *next;
-};
-
-/* some OCSP specific prefabricated ASN.1 constants */
-
-static u_char ASN1_nonce_oid_str[] = {
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
-};
-
-static const chunk_t ASN1_nonce_oid = strchunk(ASN1_nonce_oid_str);
-
-static u_char ASN1_response_oid_str[] = {
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
-};
-
-static const chunk_t ASN1_response_oid = strchunk(ASN1_response_oid_str);
-
-static u_char ASN1_response_content_str[] = {
- 0x04, 0x0D,
- 0x30, 0x0B,
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
-};
-
-static const chunk_t ASN1_response_content = strchunk(ASN1_response_content_str);
-
-/* default OCSP uri */
-static chunk_t ocsp_default_uri;
-
-/* ocsp cache: pointer to first element */
-static ocsp_location_t *ocsp_cache = NULL;
-
-/* static temporary storage for ocsp requestor information */
-static x509cert_t *ocsp_requestor_cert = NULL;
-
-static smartcard_t *ocsp_requestor_sc = NULL;
-
-static const struct RSA_private_key *ocsp_requestor_pri = NULL;
-
-/* asn.1 definitions for parsing */
-
-static const asn1Object_t ocspResponseObjects[] = {
- { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
- { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
- { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
- { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-
-#define OCSP_RESPONSE_STATUS 1
-#define OCSP_RESPONSE_TYPE 4
-#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_ROOF 7
-
-static const asn1Object_t basicResponseObjects[] = {
- { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
- ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
- { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
- { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
- { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
- { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 16 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
- { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
- { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
- { 3, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 24 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
-};
-
-#define BASIC_RESPONSE_TBS_DATA 1
-#define BASIC_RESPONSE_VERSION 3
-#define BASIC_RESPONSE_ID_BY_NAME 5
-#define BASIC_RESPONSE_ID_BY_KEY 8
-#define BASIC_RESPONSE_PRODUCED_AT 10
-#define BASIC_RESPONSE_RESPONSES 11
-#define BASIC_RESPONSE_EXT_ID 15
-#define BASIC_RESPONSE_CRITICAL 16
-#define BASIC_RESPONSE_EXT_VALUE 17
-#define BASIC_RESPONSE_ALGORITHM 20
-#define BASIC_RESPONSE_SIGNATURE 21
-#define BASIC_RESPONSE_CERTIFICATE 24
-#define BASIC_RESPONSE_ROOF 27
-
-static const asn1Object_t responsesObjects[] = {
- { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-
-#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_ROOF 3
-
-static const asn1Object_t singleResponseObjects[] = {
- { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
- { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
- { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
- { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
- { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
- { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
- { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
- { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
- { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
- { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
- { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
- { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 24 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
-};
-
-#define SINGLE_RESPONSE_ALGORITHM 2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER 5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
-#define SINGLE_RESPONSE_THIS_UPDATE 16
-#define SINGLE_RESPONSE_NEXT_UPDATE 18
-#define SINGLE_RESPONSE_EXT_ID 23
-#define SINGLE_RESPONSE_CRITICAL 24
-#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ROOF 28
-
-/* build an ocsp location from certificate information
- * without unsharing its contents
- */
-static bool
-build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
-{
- static u_char digest[SHA1_DIGEST_SIZE]; /* temporary storage */
-
- location->uri = cert->accessLocation;
-
- if (location->uri.ptr == NULL)
- {
- ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID);
- if (ca != NULL && ca->ocspuri != NULL)
- setchunk(location->uri, ca->ocspuri, strlen(ca->ocspuri))
- else
- /* abort if no ocsp location uri is defined */
- return FALSE;
- }
-
- setchunk(location->authNameID, digest, SHA1_DIGEST_SIZE);
- compute_digest(cert->issuer, OID_SHA1, &location->authNameID);
-
- location->next = NULL;
- location->issuer = cert->issuer;
- location->authKeyID = cert->authKeyID;
- location->authKeySerialNumber = cert->authKeySerialNumber;
-
- if (cert->authKeyID.ptr == NULL)
- {
- x509cert_t *authcert = get_authcert(cert->issuer
- , cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);
-
- if (authcert != NULL)
- {
- location->authKeyID = authcert->subjectKeyID;
- location->authKeySerialNumber = authcert->serialNumber;
- }
- }
-
- location->nonce = empty_chunk;
- location->certinfo = NULL;
-
- return TRUE;
-}
-
-/*
- * compare two ocsp locations for equality
- */
-static bool
-same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
-{
- return ((a->authKeyID.ptr != NULL)
- ? same_keyid(a->authKeyID, b->authKeyID)
- : (same_dn(a->issuer, b->issuer)
- && same_serial(a->authKeySerialNumber, b->authKeySerialNumber)))
- && same_chunk(a->uri, b->uri);
-}
-
-/*
- * find an existing ocsp location in a chained list
- */
-ocsp_location_t*
-get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
-{
-
- while (chain != NULL)
- {
- if (same_ocsp_location(loc, chain))
- return chain;
- chain = chain->next;
- }
- return NULL;
-}
-
-/* retrieves the status of a cert from the ocsp cache
- * returns CERT_UNDEFINED if no status is found
- */
-static cert_status_t
-get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
- ,time_t *nextUpdate, time_t *revocationTime, crl_reason_t *revocationReason)
-{
- ocsp_certinfo_t *certinfo, **certinfop;
- int cmp = -1;
-
- /* find location */
- ocsp_location_t *location = get_ocsp_location(loc, ocsp_cache);
-
- if (location == NULL)
- return CERT_UNDEFINED;
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
-
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
- certinfo = *certinfop;
- }
-
- if (cmp == 0)
- {
- *nextUpdate = certinfo->nextUpdate;
- *revocationTime = certinfo->revocationTime;
- *revocationReason = certinfo->revocationReason;
- return certinfo->status;
- }
-
- return CERT_UNDEFINED;
-}
-
-/*
- * verify the ocsp status of a certificate
- */
-cert_status_t
-verify_by_ocsp(const x509cert_t *cert, time_t *until
-, time_t *revocationDate, crl_reason_t *revocationReason)
-{
- cert_status_t status;
- ocsp_location_t location;
- time_t nextUpdate = 0;
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
-
- /* is an ocsp location defined? */
- if (!build_ocsp_location(cert, &location))
- return CERT_UNDEFINED;
-
- lock_ocsp_cache("verify_by_ocsp");
- status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate
- , revocationDate, revocationReason);
- unlock_ocsp_cache("verify_by_ocsp");
-
- if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
- {
- plog("ocsp status is stale or not in cache");
- add_ocsp_fetch_request(&location, cert->serialNumber);
-
- /* inititate fetching of ocsp status */
- wake_fetch_thread("verify_by_ocsp");
- }
- *until = nextUpdate;
- return status;
-}
-
-/*
- * check if an ocsp status is about to expire
- */
-void
-check_ocsp(void)
-{
- ocsp_location_t *location;
-
- lock_ocsp_cache("check_ocsp");
- location = ocsp_cache;
-
- while (location != NULL)
- {
- char buf[BUF_LEN];
- bool first = TRUE;
- ocsp_certinfo_t *certinfo = location->certinfo;
-
- while (certinfo != NULL)
- {
- if (!certinfo->once)
- {
- time_t time_left = certinfo->nextUpdate - time(NULL);
-
- DBG(DBG_CONTROL,
- if (first)
- {
- dntoa(buf, BUF_LEN, location->issuer);
- DBG_log("issuer: '%s'", buf);
- if (location->authKeyID.ptr != NULL)
- {
- datatot(location->authKeyID.ptr, location->authKeyID.len
- , ':', buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- first = FALSE;
- }
- datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
- , ':', buf, BUF_LEN);
- DBG_log("serial: %s, %ld seconds left", buf, time_left)
- )
-
- if (time_left < 2*crl_check_interval)
- add_ocsp_fetch_request(location, certinfo->serialNumber);
- }
- certinfo = certinfo->next;
- }
- location = location->next;
- }
- unlock_ocsp_cache("check_ocsp");
-}
-
-/*
- * frees the allocated memory of a certinfo struct
- */
-static void
-free_certinfo(ocsp_certinfo_t *certinfo)
-{
- freeanychunk(certinfo->serialNumber);
- pfree(certinfo);
-}
-
-/*
- * frees all certinfos in a chained list
- */
-static void
-free_certinfos(ocsp_certinfo_t *chain)
-{
- ocsp_certinfo_t *certinfo;
-
- while (chain != NULL)
- {
- certinfo = chain;
- chain = chain->next;
- free_certinfo(certinfo);
- }
-}
-
-/*
- * frees the memory allocated to an ocsp location including all certinfos
- */
-static void
-free_ocsp_location(ocsp_location_t* location)
-{
- freeanychunk(location->issuer);
- freeanychunk(location->authNameID);
- freeanychunk(location->authKeyID);
- freeanychunk(location->authKeySerialNumber);
- freeanychunk(location->uri);
- free_certinfos(location->certinfo);
- pfree(location);
-}
-
-/*
- * free a chained list of ocsp locations
- */
-void
-free_ocsp_locations(ocsp_location_t **chain)
-{
- while (*chain != NULL)
- {
- ocsp_location_t *location = *chain;
- *chain = location->next;
- free_ocsp_location(location);
- }
-}
-
-/*
- * free the ocsp cache
- */
-void
-free_ocsp_cache(void)
-{
- lock_ocsp_cache("free_ocsp_cache");
- free_ocsp_locations(&ocsp_cache);
- unlock_ocsp_cache("free_ocsp_cache");
-}
-
-/*
- * frees the ocsp cache and global variables
- */
-void
-free_ocsp(void)
-{
- pfreeany(ocsp_default_uri.ptr);
- free_ocsp_cache();
-}
-
-/*
- * list a chained list of ocsp_locations
- */
-void
-list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
-, bool strict)
-{
- bool first = TRUE;
-
- while (location != NULL)
- {
- ocsp_certinfo_t *certinfo = location->certinfo;
-
- if (certinfo != NULL)
- {
- u_char buf[BUF_LEN];
-
- if (first)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of OCSP %s:", requests?
- "fetch requests":"responses");
- first = FALSE;
- }
- whack_log(RC_COMMENT, " ");
- if (location->issuer.ptr != NULL)
- {
- dntoa(buf, BUF_LEN, location->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- }
- whack_log(RC_COMMENT, " uri: '%.*s'", (int)location->uri.len
- , location->uri.ptr);
- if (location->authNameID.ptr != NULL)
- {
- datatot(location->authNameID.ptr, location->authNameID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authname: %s", buf);
- }
- if (location->authKeyID.ptr != NULL)
- {
- datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (location->authKeySerialNumber.ptr != NULL)
- {
- datatot(location->authKeySerialNumber.ptr
- , location->authKeySerialNumber.len, ':', buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
- while (certinfo != NULL)
- {
- char thisUpdate[TIMETOA_BUF];
-
- strcpy(thisUpdate, timetoa(&certinfo->thisUpdate, utc));
-
- if (requests)
- {
- whack_log(RC_COMMENT, "%s, trials: %d", thisUpdate
- , certinfo->trials);
- }
- else if (certinfo->once)
- {
- whack_log(RC_COMMENT, "%s, onetime use%s", thisUpdate
- , (certinfo->nextUpdate < time(NULL))? " (expired)": "");
- }
- else
- {
- whack_log(RC_COMMENT, "%s, until %s %s", thisUpdate
- , timetoa(&certinfo->nextUpdate, utc)
- , check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
- }
- datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s, %s", buf
- , cert_status_names[certinfo->status]);
- certinfo = certinfo->next;
- }
- }
- location = location->next;
- }
-}
-
-/*
- * list the ocsp cache
- */
-void
-list_ocsp_cache(bool utc, bool strict)
-{
- lock_ocsp_cache("list_ocsp_cache");
- list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
- unlock_ocsp_cache("list_ocsp_cache");
-}
-
-static bool
-get_ocsp_requestor_cert(ocsp_location_t *location)
-{
- x509cert_t *cert = NULL;
-
- /* initialize temporary static storage */
- ocsp_requestor_cert = NULL;
- ocsp_requestor_sc = NULL;
- ocsp_requestor_pri = NULL;
-
- for (;;)
- {
- char buf[BUF_LEN];
-
- /* looking for a certificate from the same issuer */
- cert = get_x509cert(location->issuer, location->authKeySerialNumber
- ,location->authKeyID, cert);
- if (cert == NULL)
- break;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("candidate: '%s'", buf);
- )
-
- if (cert->smartcard)
- {
- /* look for a matching private key on a smartcard */
- smartcard_t *sc = scx_get(cert);
-
- if (sc != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("matching smartcard found")
- )
- if (sc->valid)
- {
- ocsp_requestor_cert = cert;
- ocsp_requestor_sc = sc;
- return TRUE;
- }
- plog("unable to sign ocsp request without PIN");
- }
- }
- else
- {
- /* look for a matching private key in the chained list */
- const struct RSA_private_key *pri = get_x509_private_key(cert);
-
- if (pri != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("matching private key found")
- )
- ocsp_requestor_cert = cert;
- ocsp_requestor_pri = pri;
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-static chunk_t
-generate_signature(chunk_t digest, smartcard_t *sc
- , const RSA_private_key_t *pri)
-{
- chunk_t sigdata;
- u_char *pos;
- size_t siglen = 0;
-
- if (sc != NULL)
- {
- /* RSA signature is done on smartcard */
-
- if (!scx_establish_context(sc) || !scx_login(sc))
- {
- scx_release_context(sc);
- return empty_chunk;
- }
-
- siglen = scx_get_keylength(sc);
-
- if (siglen == 0)
- {
- plog("failed to get keylength from smartcard");
- scx_release_context(sc);
- return empty_chunk;
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
- )
-
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
- *pos++ = 0x00;
- scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- }
- else
- {
- /* RSA signature is done in software */
- siglen = pri->pub.k;
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
- *pos++ = 0x00;
- sign_hash(pri, digest.ptr, digest.len, pos, siglen);
- }
- return sigdata;
-}
-
-/*
- * build signature into ocsp request
- * gets built only if a request cert with
- * a corresponding private key is found
- */
-static chunk_t
-build_signature(chunk_t tbsRequest)
-{
- chunk_t sigdata, certs;
- chunk_t digest_info;
-
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest_raw = { digest_buf, MAX_DIGEST_LEN };
-
- if (!compute_digest(tbsRequest, OID_SHA1, &digest_raw))
- return empty_chunk;
-
- /* according to PKCS#1 v2.1 digest must be packaged into
- * an ASN.1 structure for encryption
- */
- digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_sha1_id
- , asn1_simple_object(ASN1_OCTET_STRING, digest_raw));
-
- /* generate the RSA signature */
- sigdata = generate_signature(digest_info
- , ocsp_requestor_sc
- , ocsp_requestor_pri);
- freeanychunk(digest_info);
-
- /* has the RSA signature generation been successful? */
- if (sigdata.ptr == NULL)
- return empty_chunk;
-
- /* include our certificate */
- certs = asn1_wrap(ASN1_CONTEXT_C_0, "m"
- , asn1_simple_object(ASN1_SEQUENCE
- , ocsp_requestor_cert->certificate
- )
- );
-
- /* build signature comprising algorithm, signature and cert */
- return asn1_wrap(ASN1_CONTEXT_C_0, "m"
- , asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_sha1WithRSA_id
- , sigdata
- , certs
- )
- );
-}
-
-/* build request (into requestList)
- * no singleRequestExtensions used
- */
-static chunk_t
-build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
-{
- chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
- , ASN1_sha1_id
- , asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
- , asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
- , asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
-
- return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
-}
-
-/*
- * build requestList (into TBSRequest)
- */
-static chunk_t
-build_request_list(ocsp_location_t *location)
-{
- chunk_t requestList;
- request_list_t *reqs = NULL;
- ocsp_certinfo_t *certinfo = location->certinfo;
- u_char *pos;
-
- size_t datalen = 0;
-
- /* build content */
- while (certinfo != NULL)
- {
- /* build request for every certificate in list
- * and store them in a chained list
- */
- request_list_t *req = alloc_thing(request_list_t, "ocsp request");
-
- req->request = build_request(location, certinfo);
- req->next = reqs;
- reqs = req;
-
- datalen += req->request.len;
- certinfo = certinfo->next;
- }
-
- pos = build_asn1_object(&requestList, ASN1_SEQUENCE
- , datalen);
-
- /* copy all in chained list, free list afterwards */
- while (reqs != NULL)
- {
- request_list_t *req = reqs;
-
- mv_chunk(&pos, req->request);
- reqs = reqs->next;
- pfree(req);
- }
-
- return requestList;
-}
-
-/*
- * build requestorName (into TBSRequest)
- */
-static chunk_t
-build_requestor_name(void)
-{
- return asn1_wrap(ASN1_CONTEXT_C_1, "m"
- , asn1_simple_object(ASN1_CONTEXT_C_4
- , ocsp_requestor_cert->subject));
-}
-
-/*
- * build nonce extension (into requestExtensions)
- */
-static chunk_t
-build_nonce_extension(ocsp_location_t *location)
-{
- /* generate a random nonce */
- location->nonce.ptr = alloc_bytes(NONCE_LENGTH, "ocsp nonce"),
- location->nonce.len = NONCE_LENGTH;
- get_rnd_bytes(location->nonce.ptr, NONCE_LENGTH);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_nonce_oid
- , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
-}
-
-/*
- * build requestExtensions (into TBSRequest)
- */
-static chunk_t
-build_request_ext(ocsp_location_t *location)
-{
- return asn1_wrap(ASN1_CONTEXT_C_2, "m"
- , asn1_wrap(ASN1_SEQUENCE, "mm"
- , build_nonce_extension(location)
- , asn1_wrap(ASN1_SEQUENCE, "cc"
- , ASN1_response_oid
- , ASN1_response_content
- )
- )
- );
-}
-
-/*
- * build TBSRequest (into OCSPRequest)
- */
-static chunk_t
-build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
-{
- /* version is skipped since the default is ok */
- return asn1_wrap(ASN1_SEQUENCE, "mmm"
- , (has_requestor_cert)
- ? build_requestor_name()
- : empty_chunk
- , build_request_list(location)
- , build_request_ext(location));
-}
-
-/* assembles an ocsp request to given location
- * and sets nonce field in location to the sent nonce
- */
-chunk_t
-build_ocsp_request(ocsp_location_t *location)
-{
- bool has_requestor_cert;
- chunk_t tbsRequest, signature;
- char buf[BUF_LEN];
-
- DBG(DBG_CONTROL,
- DBG_log("assembling ocsp request");
- dntoa(buf, BUF_LEN, location->issuer);
- DBG_log("issuer: '%s'", buf);
- if (location->authKeyID.ptr != NULL)
- {
- datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
- lock_certs_and_keys("build_ocsp_request");
-
- /* looks for requestor cert and matching private key */
- has_requestor_cert = get_ocsp_requestor_cert(location);
-
- /* build content */
- tbsRequest = build_tbs_request(location, has_requestor_cert);
-
- /* sign tbsReuqest */
- signature = (has_requestor_cert)? build_signature(tbsRequest)
- : empty_chunk;
-
- unlock_certs_and_keys("build_ocsp_request");
-
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , tbsRequest
- , signature);
-}
-
-/*
- * check if the OCSP response has a valid signature
- */
-static bool
-valid_ocsp_response(response_t *res)
-{
- int pathlen;
- x509cert_t *authcert;
-
- lock_authcert_list("valid_ocsp_response");
-
- authcert = get_authcert(res->responder_id_name, empty_chunk
- , res->responder_id_key, AUTH_OCSP | AUTH_CA);
-
- if (authcert == NULL)
- {
- plog("no matching ocsp signer cert found");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("ocsp signer cert found")
- )
-
- if (!check_signature(res->tbs, res->signature, res->algorithm
- , res->algorithm, authcert))
- {
- plog("signature of ocsp response is invalid");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("signature of ocsp response is valid")
- )
-
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- u_char buf[BUF_LEN];
- err_t ugh = NULL;
- time_t until;
-
- x509cert_t *cert = authcert;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
-
- ugh = check_validity(authcert, &until);
-
- if (ugh != NULL)
- {
- plog("%s", ugh);
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
-
- authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
-
- if (authcert == NULL)
- {
- plog("issuer cacert not found");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
- )
-
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, authcert))
- {
- plog("certificate signature is invalid");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
- )
-
- /* check if cert is self-signed */
- if (same_dn(cert->issuer, cert->subject))
- {
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- unlock_authcert_list("valid_ocsp_response");
- return TRUE;
- }
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
-}
-
-/*
- * parse a basic OCSP response
- */
-static bool
-parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
-{
- u_int level, version;
- u_int extn_oid = OID_UNKNOWN;
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < BASIC_RESPONSE_ROOF)
- {
- if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case BASIC_RESPONSE_TBS_DATA:
- res->tbs = object;
- break;
- case BASIC_RESPONSE_VERSION:
- version = (object.len)? (1 + (u_int)*object.ptr) : 1;
- if (version != OCSP_BASIC_RESPONSE_VERSION)
- {
- plog("wrong ocsp basic response version (version= %i)", version);
- return FALSE;
- }
- break;
- case BASIC_RESPONSE_ID_BY_NAME:
- res->responder_id_name = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case BASIC_RESPONSE_ID_BY_KEY:
- res->responder_id_key = object;
- break;
- case BASIC_RESPONSE_PRODUCED_AT:
- res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case BASIC_RESPONSE_RESPONSES:
- res->responses = object;
- break;
- case BASIC_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case BASIC_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case BASIC_RESPONSE_EXT_VALUE:
- if (extn_oid == OID_NONCE)
- res->nonce = object;
- break;
- case BASIC_RESPONSE_ALGORITHM:
- res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case BASIC_RESPONSE_SIGNATURE:
- res->signature = object;
- break;
- case BASIC_RESPONSE_CERTIFICATE:
- {
- chunk_t blob;
- x509cert_t *cert = alloc_thing(x509cert_t, "ocspcert");
-
- clonetochunk(blob, object.ptr, object.len, "ocspcert blob");
- *cert = empty_x509cert;
-
- if (parse_x509cert(blob, level+1, cert)
- && cert->isOcspSigner
- && trust_authcert_candidate(cert, NULL))
- {
- add_authcert(cert, AUTH_OCSP);
- }
- else
- {
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("embedded ocsp certificate rejected")
- )
- free_x509cert(cert);
- }
- }
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-
-/*
- * parse an ocsp response and return the result as a response_t struct
- */
-static response_status
-parse_ocsp_response(chunk_t blob, response_t * res)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- response_status rStatus = STATUS_INTERNALERROR;
- u_int ocspResponseType = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
- while (objectID < OCSP_RESPONSE_ROOF)
- {
- if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
- return STATUS_INTERNALERROR;
-
- switch (objectID) {
- case OCSP_RESPONSE_STATUS:
- rStatus = (response_status) *object.ptr;
-
- switch (rStatus)
- {
- case STATUS_SUCCESSFUL:
- break;
- case STATUS_MALFORMEDREQUEST:
- case STATUS_INTERNALERROR:
- case STATUS_TRYLATER:
- case STATUS_SIGREQUIRED:
- case STATUS_UNAUTHORIZED:
- plog("ocsp response: server said '%s'"
- , response_status_names[rStatus]);
- return rStatus;
- default:
- return STATUS_INTERNALERROR;
- }
- break;
- case OCSP_RESPONSE_TYPE:
- ocspResponseType = known_oid(object);
- break;
- case OCSP_RESPONSE:
- {
- switch (ocspResponseType) {
- case OID_BASIC:
- if (!parse_basic_ocsp_response(object, level+1, res))
- return STATUS_INTERNALERROR;
- break;
- default:
- DBG(DBG_CONTROL,
- DBG_log("ocsp response is not of type BASIC");
- DBG_dump_chunk("ocsp response OID: ", object);
- )
- return STATUS_INTERNALERROR;
- }
- }
- break;
- }
- objectID++;
- }
- return rStatus;
-}
-
-/*
- * parse a basic OCSP response
- */
-static bool
-parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
-{
- u_int level, extn_oid;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < SINGLE_RESPONSE_ROOF)
- {
- if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case SINGLE_RESPONSE_ALGORITHM:
- sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case SINGLE_RESPONSE_ISSUER_NAME_HASH:
- sres->issuer_name_hash = object;
- break;
- case SINGLE_RESPONSE_ISSUER_KEY_HASH:
- sres->issuer_key_hash = object;
- break;
- case SINGLE_RESPONSE_SERIAL_NUMBER:
- sres->serialNumber = object;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_GOOD:
- sres->status = CERT_GOOD;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
- sres->status = CERT_REVOKED;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
- sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
- sres->revocationReason = (object.len == 1)
- ? *object.ptr : REASON_UNSPECIFIED;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
- sres->status = CERT_UNKNOWN;
- break;
- case SINGLE_RESPONSE_THIS_UPDATE:
- sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_NEXT_UPDATE:
- sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case SINGLE_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- case SINGLE_RESPONSE_EXT_VALUE:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/*
- * add an ocsp location to a chained list
- */
-ocsp_location_t*
-add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
-{
- ocsp_location_t *location = alloc_thing(ocsp_location_t, "ocsp location");
-
- /* unshare location fields */
- clonetochunk(location->issuer
- , loc->issuer.ptr, loc->issuer.len
- , "ocsp issuer");
-
- clonetochunk(location->authNameID
- , loc->authNameID.ptr, loc->authNameID.len
- , "ocsp authNameID");
-
- if (loc->authKeyID.ptr == NULL)
- location->authKeyID = empty_chunk;
- else
- clonetochunk(location->authKeyID
- , loc->authKeyID.ptr, loc->authKeyID.len
- , "ocsp authKeyID");
-
- if (loc->authKeySerialNumber.ptr == NULL)
- location->authKeySerialNumber = empty_chunk;
- else
- clonetochunk(location->authKeySerialNumber
- , loc->authKeySerialNumber.ptr, loc->authKeySerialNumber.len
- , "ocsp authKeySerialNumber");
-
- clonetochunk(location->uri
- , loc->uri.ptr, loc->uri.len
- , "ocsp uri");
-
- location->certinfo = NULL;
-
- /* insert new ocsp location in front of chain */
- location->next = *chain;
- *chain = location;
-
- DBG(DBG_CONTROL,
- DBG_log("new ocsp location added")
- )
-
- return location;
-}
-
-/*
- * add a certinfo struct to a chained list
- */
-void
-add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chain
- , bool request)
-{
- ocsp_location_t *location;
- ocsp_certinfo_t *certinfo, **certinfop;
- char buf[BUF_LEN];
- time_t now;
- int cmp = -1;
-
- location = get_ocsp_location(loc, *chain);
- if (location == NULL)
- location = add_ocsp_location(loc, chain);
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
-
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(info->serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
- certinfo = *certinfop;
- }
-
- if (cmp != 0)
- {
- /* add a new certinfo entry */
- ocsp_certinfo_t *cnew = alloc_thing(ocsp_certinfo_t, "ocsp certinfo");
- clonetochunk(cnew->serialNumber, info->serialNumber.ptr
- , info->serialNumber.len, "serialNumber");
- cnew->next = certinfo;
- *certinfop = cnew;
- certinfo = cnew;
- }
-
- DBG(DBG_CONTROL,
- datatot(info->serialNumber.ptr, info->serialNumber.len, ':'
- , buf, BUF_LEN);
- DBG_log("ocsp %s for serial %s %s"
- , request?"fetch request":"certinfo"
- , buf
- , (cmp == 0)? (request?"already exists":"updated"):"added")
- )
-
- time(&now);
-
- if (request)
- {
- certinfo->status = CERT_UNDEFINED;
-
- if (cmp != 0)
- certinfo->thisUpdate = now;
-
- certinfo->nextUpdate = UNDEFINED_TIME;
- }
- else
- {
- certinfo->status = info->status;
- certinfo->revocationTime = info->revocationTime;
- certinfo->revocationReason = info->revocationReason;
-
- certinfo->thisUpdate = (info->thisUpdate != UNDEFINED_TIME)?
- info->thisUpdate : now;
-
- certinfo->once = (info->nextUpdate == UNDEFINED_TIME);
-
- certinfo->nextUpdate = (certinfo->once)?
- (now + OCSP_DEFAULT_VALID_TIME) : info->nextUpdate;
- }
-}
-
-/*
- * process received ocsp single response and add it to ocsp cache
- */
-static void
-process_single_response(ocsp_location_t *location, single_response_t *sres)
-{
- ocsp_certinfo_t *certinfo, **certinfop;
- int cmp = -1;
-
- if (sres->hash_algorithm != OID_SHA1)
- {
- plog("only SHA-1 hash supported in OCSP single response");
- return;
- }
- if (!(same_chunk(sres->issuer_name_hash, location->authNameID)
- && same_chunk(sres->issuer_key_hash, location->authKeyID)))
- {
- plog("ocsp single response has wrong issuer");
- return;
- }
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
-
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(sres->serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
- certinfo = *certinfop;
- }
-
- if (cmp != 0)
- {
- plog("received unrequested cert status from ocsp server");
- return;
- }
-
- /* unlink cert from ocsp fetch request list */
- *certinfop = certinfo->next;
-
- /* update certinfo using the single response information */
- certinfo->thisUpdate = sres->thisUpdate;
- certinfo->nextUpdate = sres->nextUpdate;
- certinfo->status = sres->status;
- certinfo->revocationTime = sres->revocationTime;
- certinfo->revocationReason = sres->revocationReason;
-
- /* add or update certinfo in ocsp cache */
- lock_ocsp_cache("process_single_response");
- add_certinfo(location, certinfo, &ocsp_cache, FALSE);
- unlock_ocsp_cache("process_single_response");
-
- /* free certinfo unlinked from ocsp fetch request list */
- free_certinfo(certinfo);
-
-}
-
-/*
- * parse and verify ocsp response and update the ocsp cache
- */
-void
-parse_ocsp(ocsp_location_t *location, chunk_t blob)
-{
- response_t res = empty_response;
-
- /* parse the ocsp response without looking at the single responses yet */
- response_status status = parse_ocsp_response(blob, &res);
-
- if (status != STATUS_SUCCESSFUL)
- {
- plog("error in ocsp response");
- return;
- }
- /* check if there was a nonce in the request */
- if (location->nonce.ptr != NULL && res.nonce.ptr == NULL)
- {
- plog("ocsp response contains no nonce, replay attack possible");
- }
- /* check if the nonce is identical */
- if (res.nonce.ptr != NULL && !same_chunk(res.nonce, location->nonce))
- {
- plog("invalid nonce in ocsp response");
- return;
- }
- /* check if the response is signed by a trusted key */
- if (!valid_ocsp_response(&res))
- {
- plog("invalid ocsp response");
- return;
- }
- DBG(DBG_CONTROL,
- DBG_log("valid ocsp response")
- )
-
- /* now parse the single responses one at a time */
- {
- u_int level;
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, res.responses, 0, FALSE, DBG_RAW);
-
- while (objectID < RESPONSES_ROOF)
- {
- if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
- return;
-
- if (objectID == RESPONSES_SINGLE_RESPONSE)
- {
- single_response_t sres = empty_single_response;
-
- if (parse_ocsp_single_response(object, level+1, &sres))
- {
- process_single_response(location, &sres);
- }
- }
- objectID++;
- }
- }
-}
diff --git a/programs/pluto/ocsp.h b/programs/pluto/ocsp.h
deleted file mode 100644
index 49e1026ec..000000000
--- a/programs/pluto/ocsp.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Support of the Online Certificate Status Protocol (OCSP) Support
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- */
-
-#include "constants.h"
-
-/* constants */
-
-#define OCSP_BASIC_RESPONSE_VERSION 1
-#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
-#define OCSP_WARNING_INTERVAL 2 /* days */
-
-/* OCSP response status */
-
-typedef enum {
- STATUS_SUCCESSFUL = 0,
- STATUS_MALFORMEDREQUEST = 1,
- STATUS_INTERNALERROR = 2,
- STATUS_TRYLATER = 3,
- STATUS_SIGREQUIRED = 5,
- STATUS_UNAUTHORIZED= 6
-} response_status;
-
-/* OCSP access structures */
-
-typedef struct ocsp_certinfo ocsp_certinfo_t;
-
-struct ocsp_certinfo {
- ocsp_certinfo_t *next;
- int trials;
- chunk_t serialNumber;
- cert_status_t status;
- bool once;
- crl_reason_t revocationReason;
- time_t revocationTime;
- time_t thisUpdate;
- time_t nextUpdate;
-};
-
-typedef struct ocsp_location ocsp_location_t;
-
-struct ocsp_location {
- ocsp_location_t *next;
- chunk_t issuer;
- chunk_t authNameID;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- chunk_t uri;
- chunk_t nonce;
- ocsp_certinfo_t *certinfo;
-};
-
-extern ocsp_location_t* get_ocsp_location(const ocsp_location_t *loc
- , ocsp_location_t *chain);
-extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
- , ocsp_location_t **chain);
-extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
- , ocsp_location_t **chain, bool request);
-extern void check_ocsp(void);
-extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until
- , time_t *revocationTime, crl_reason_t *revocationReason);
-extern bool ocsp_set_request_cert(char* path);
-extern void ocsp_set_default_uri(char* uri);
-extern void ocsp_cache_add_cert(const x509cert_t* cert);
-extern chunk_t build_ocsp_request(ocsp_location_t* location);
-extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
-extern void list_ocsp_locations(ocsp_location_t *location, bool requests
- , bool utc, bool strict);
-extern void list_ocsp_cache(bool utc, bool strict);
-extern void free_ocsp_locations(ocsp_location_t **chain);
-extern void free_ocsp_cache(void);
-extern void free_ocsp(void);
-extern void ocsp_purge_cache(void);
diff --git a/programs/pluto/oid.c b/programs/pluto/oid.c
deleted file mode 100644
index 4b0632de2..000000000
--- a/programs/pluto/oid.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* List of some useful object identifiers (OIDs)
- * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This file has been automatically generated by the script oid.pl
- * Do not edit manually!
- */
-
-#include <stdlib.h>
-
-#include "oid.h"
-
-const oid_t oid_names[] = {
- {0x02, 7, 1, "ITU-T Administration" }, /* 0 */
- { 0x82, 0, 1, "" }, /* 1 */
- { 0x06, 0, 1, "Germany ITU-T member" }, /* 2 */
- { 0x01, 0, 1, "Deutsche Telekom AG" }, /* 3 */
- { 0x0A, 0, 1, "" }, /* 4 */
- { 0x07, 0, 1, "" }, /* 5 */
- { 0x14, 0, 0, "ND" }, /* 6 */
- {0x09, 18, 1, "data" }, /* 7 */
- { 0x92, 0, 1, "" }, /* 8 */
- { 0x26, 0, 1, "" }, /* 9 */
- { 0x89, 0, 1, "" }, /* 10 */
- { 0x93, 0, 1, "" }, /* 11 */
- { 0xF2, 0, 1, "" }, /* 12 */
- { 0x2C, 0, 1, "" }, /* 13 */
- { 0x64, 0, 1, "pilot" }, /* 14 */
- { 0x01, 0, 1, "pilotAttributeType" }, /* 15 */
- { 0x01, 17, 0, "UID" }, /* 16 */
- { 0x19, 0, 0, "DC" }, /* 17 */
- {0x55, 51, 1, "X.500" }, /* 18 */
- { 0x04, 36, 1, "X.509" }, /* 19 */
- { 0x03, 21, 0, "CN" }, /* 20 */
- { 0x04, 22, 0, "S" }, /* 21 */
- { 0x05, 23, 0, "SN" }, /* 22 */
- { 0x06, 24, 0, "C" }, /* 23 */
- { 0x07, 25, 0, "L" }, /* 24 */
- { 0x08, 26, 0, "ST" }, /* 25 */
- { 0x0A, 27, 0, "O" }, /* 26 */
- { 0x0B, 28, 0, "OU" }, /* 27 */
- { 0x0C, 29, 0, "T" }, /* 28 */
- { 0x0D, 30, 0, "D" }, /* 29 */
- { 0x24, 31, 0, "userCertificate" }, /* 30 */
- { 0x29, 32, 0, "N" }, /* 31 */
- { 0x2A, 33, 0, "G" }, /* 32 */
- { 0x2B, 34, 0, "I" }, /* 33 */
- { 0x2D, 35, 0, "ID" }, /* 34 */
- { 0x48, 0, 0, "role" }, /* 35 */
- { 0x1D, 0, 1, "id-ce" }, /* 36 */
- { 0x09, 38, 0, "subjectDirectoryAttrs" }, /* 37 */
- { 0x0E, 39, 0, "subjectKeyIdentifier" }, /* 38 */
- { 0x0F, 40, 0, "keyUsage" }, /* 39 */
- { 0x10, 41, 0, "privateKeyUsagePeriod" }, /* 40 */
- { 0x11, 42, 0, "subjectAltName" }, /* 41 */
- { 0x12, 43, 0, "issuerAltName" }, /* 42 */
- { 0x13, 44, 0, "basicConstraints" }, /* 43 */
- { 0x15, 45, 0, "reasonCode" }, /* 44 */
- { 0x1F, 46, 0, "crlDistributionPoints" }, /* 45 */
- { 0x20, 47, 0, "certificatePolicies" }, /* 46 */
- { 0x23, 48, 0, "authorityKeyIdentifier" }, /* 47 */
- { 0x25, 49, 0, "extendedKeyUsage" }, /* 48 */
- { 0x37, 50, 0, "targetInformation" }, /* 49 */
- { 0x38, 0, 0, "noRevAvail" }, /* 50 */
- {0x2A, 88, 1, "" }, /* 51 */
- { 0x86, 0, 1, "" }, /* 52 */
- { 0x48, 0, 1, "" }, /* 53 */
- { 0x86, 0, 1, "" }, /* 54 */
- { 0xF7, 0, 1, "" }, /* 55 */
- { 0x0D, 0, 1, "RSADSI" }, /* 56 */
- { 0x01, 83, 1, "PKCS" }, /* 57 */
- { 0x01, 66, 1, "PKCS-1" }, /* 58 */
- { 0x01, 60, 0, "rsaEncryption" }, /* 59 */
- { 0x02, 61, 0, "md2WithRSAEncryption" }, /* 60 */
- { 0x04, 62, 0, "md5WithRSAEncryption" }, /* 61 */
- { 0x05, 63, 0, "sha-1WithRSAEncryption" }, /* 62 */
- { 0x0B, 64, 0, "sha256WithRSAEncryption"}, /* 63 */
- { 0x0C, 65, 0, "sha384WithRSAEncryption"}, /* 64 */
- { 0x0D, 0, 0, "sha512WithRSAEncryption"}, /* 65 */
- { 0x07, 73, 1, "PKCS-7" }, /* 66 */
- { 0x01, 68, 0, "data" }, /* 67 */
- { 0x02, 69, 0, "signedData" }, /* 68 */
- { 0x03, 70, 0, "envelopedData" }, /* 69 */
- { 0x04, 71, 0, "signedAndEnvelopedData" }, /* 70 */
- { 0x05, 72, 0, "digestedData" }, /* 71 */
- { 0x06, 0, 0, "encryptedData" }, /* 72 */
- { 0x09, 0, 1, "PKCS-9" }, /* 73 */
- { 0x01, 75, 0, "E" }, /* 74 */
- { 0x02, 76, 0, "unstructuredName" }, /* 75 */
- { 0x03, 77, 0, "contentType" }, /* 76 */
- { 0x04, 78, 0, "messageDigest" }, /* 77 */
- { 0x05, 79, 0, "signingTime" }, /* 78 */
- { 0x06, 80, 0, "counterSignature" }, /* 79 */
- { 0x07, 81, 0, "challengePassword" }, /* 80 */
- { 0x08, 82, 0, "unstructuredAddress" }, /* 81 */
- { 0x0E, 0, 0, "extensionRequest" }, /* 82 */
- { 0x02, 86, 1, "digestAlgorithm" }, /* 83 */
- { 0x02, 85, 0, "md2" }, /* 84 */
- { 0x05, 0, 0, "md5" }, /* 85 */
- { 0x03, 0, 1, "encryptionAlgorithm" }, /* 86 */
- { 0x07, 0, 0, "3des-ede-cbc" }, /* 87 */
- {0x2B, 149, 1, "" }, /* 88 */
- { 0x06, 136, 1, "dod" }, /* 89 */
- { 0x01, 0, 1, "internet" }, /* 90 */
- { 0x04, 105, 1, "private" }, /* 91 */
- { 0x01, 0, 1, "enterprise" }, /* 92 */
- { 0x82, 98, 1, "" }, /* 93 */
- { 0x37, 0, 1, "Microsoft" }, /* 94 */
- { 0x0A, 0, 1, "" }, /* 95 */
- { 0x03, 0, 1, "" }, /* 96 */
- { 0x03, 0, 0, "msSGC" }, /* 97 */
- { 0x89, 0, 1, "" }, /* 98 */
- { 0x31, 0, 1, "" }, /* 99 */
- { 0x01, 0, 1, "" }, /* 100 */
- { 0x01, 0, 1, "" }, /* 101 */
- { 0x02, 0, 1, "" }, /* 102 */
- { 0x02, 104, 0, "" }, /* 103 */
- { 0x4B, 0, 0, "TCGID" }, /* 104 */
- { 0x05, 0, 1, "security" }, /* 105 */
- { 0x05, 0, 1, "mechanisms" }, /* 106 */
- { 0x07, 0, 1, "id-pkix" }, /* 107 */
- { 0x01, 110, 1, "id-pe" }, /* 108 */
- { 0x01, 0, 0, "authorityInfoAccess" }, /* 109 */
- { 0x03, 120, 1, "id-kp" }, /* 110 */
- { 0x01, 112, 0, "serverAuth" }, /* 111 */
- { 0x02, 113, 0, "clientAuth" }, /* 112 */
- { 0x03, 114, 0, "codeSigning" }, /* 113 */
- { 0x04, 115, 0, "emailProtection" }, /* 114 */
- { 0x05, 116, 0, "ipsecEndSystem" }, /* 115 */
- { 0x06, 117, 0, "ipsecTunnel" }, /* 116 */
- { 0x07, 118, 0, "ipsecUser" }, /* 117 */
- { 0x08, 119, 0, "timeStamping" }, /* 118 */
- { 0x09, 0, 0, "ocspSigning" }, /* 119 */
- { 0x08, 122, 1, "id-otherNames" }, /* 120 */
- { 0x05, 0, 0, "xmppAddr" }, /* 121 */
- { 0x0A, 127, 1, "id-aca" }, /* 122 */
- { 0x01, 124, 0, "authenticationInfo" }, /* 123 */
- { 0x02, 125, 0, "accessIdentity" }, /* 124 */
- { 0x03, 126, 0, "chargingIdentity" }, /* 125 */
- { 0x04, 0, 0, "group" }, /* 126 */
- { 0x30, 0, 1, "id-ad" }, /* 127 */
- { 0x01, 0, 1, "ocsp" }, /* 128 */
- { 0x01, 130, 0, "basic" }, /* 129 */
- { 0x02, 131, 0, "nonce" }, /* 130 */
- { 0x03, 132, 0, "crl" }, /* 131 */
- { 0x04, 133, 0, "response" }, /* 132 */
- { 0x05, 134, 0, "noCheck" }, /* 133 */
- { 0x06, 135, 0, "archiveCutoff" }, /* 134 */
- { 0x07, 0, 0, "serviceLocator" }, /* 135 */
- { 0x0E, 142, 1, "oiw" }, /* 136 */
- { 0x03, 0, 1, "secsig" }, /* 137 */
- { 0x02, 0, 1, "algorithms" }, /* 138 */
- { 0x07, 140, 0, "des-cbc" }, /* 139 */
- { 0x1A, 141, 0, "sha-1" }, /* 140 */
- { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 141 */
- { 0x24, 0, 1, "TeleTrusT" }, /* 142 */
- { 0x03, 0, 1, "algorithm" }, /* 143 */
- { 0x03, 0, 1, "signatureAlgorithm" }, /* 144 */
- { 0x01, 0, 1, "rsaSignature" }, /* 145 */
- { 0x02, 147, 0, "rsaSigWithripemd160" }, /* 146 */
- { 0x03, 148, 0, "rsaSigWithripemd128" }, /* 147 */
- { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 148 */
- {0x60, 0, 1, "" }, /* 149 */
- { 0x86, 0, 1, "" }, /* 150 */
- { 0x48, 0, 1, "" }, /* 151 */
- { 0x01, 0, 1, "organization" }, /* 152 */
- { 0x65, 160, 1, "gov" }, /* 153 */
- { 0x03, 0, 1, "csor" }, /* 154 */
- { 0x04, 0, 1, "nistalgorithm" }, /* 155 */
- { 0x02, 0, 1, "hashalgs" }, /* 156 */
- { 0x01, 158, 0, "id-SHA-256" }, /* 157 */
- { 0x02, 159, 0, "id-SHA-384" }, /* 158 */
- { 0x03, 0, 0, "id-SHA-512" }, /* 159 */
- { 0x86, 0, 1, "" }, /* 160 */
- { 0xf8, 0, 1, "" }, /* 161 */
- { 0x42, 174, 1, "netscape" }, /* 162 */
- { 0x01, 169, 1, "" }, /* 163 */
- { 0x01, 165, 0, "nsCertType" }, /* 164 */
- { 0x03, 166, 0, "nsRevocationUrl" }, /* 165 */
- { 0x04, 167, 0, "nsCaRevocationUrl" }, /* 166 */
- { 0x08, 168, 0, "nsCaPolicyUrl" }, /* 167 */
- { 0x0d, 0, 0, "nsComment" }, /* 168 */
- { 0x03, 172, 1, "directory" }, /* 169 */
- { 0x01, 0, 1, "" }, /* 170 */
- { 0x03, 0, 0, "employeeNumber" }, /* 171 */
- { 0x04, 0, 1, "policy" }, /* 172 */
- { 0x01, 0, 0, "nsSGC" }, /* 173 */
- { 0x45, 0, 1, "verisign" }, /* 174 */
- { 0x01, 0, 1, "pki" }, /* 175 */
- { 0x09, 0, 1, "attributes" }, /* 176 */
- { 0x02, 178, 0, "messageType" }, /* 177 */
- { 0x03, 179, 0, "pkiStatus" }, /* 178 */
- { 0x04, 180, 0, "failInfo" }, /* 179 */
- { 0x05, 181, 0, "senderNonce" }, /* 180 */
- { 0x06, 182, 0, "recipientNonce" }, /* 181 */
- { 0x07, 183, 0, "transID" }, /* 182 */
- { 0x08, 0, 0, "extensionReq" } /* 183 */
-};
diff --git a/programs/pluto/oid.h b/programs/pluto/oid.h
deleted file mode 100644
index ccdfb2954..000000000
--- a/programs/pluto/oid.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Object identifiers (OIDs) used by FreeS/WAN
- * Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This file has been automatically generated by the script oid.pl
- * Do not edit manually!
- */
-
-typedef struct {
- u_char octet;
- u_int next;
- u_int down;
- const u_char *name;
-} oid_t;
-
-extern const oid_t oid_names[];
-
-#define OID_UNKNOWN -1
-#define OID_ROLE 35
-#define OID_SUBJECT_KEY_ID 38
-#define OID_SUBJECT_ALT_NAME 41
-#define OID_BASIC_CONSTRAINTS 43
-#define OID_CRL_REASON_CODE 44
-#define OID_CRL_DISTRIBUTION_POINTS 45
-#define OID_AUTHORITY_KEY_ID 47
-#define OID_EXTENDED_KEY_USAGE 48
-#define OID_TARGET_INFORMATION 49
-#define OID_NO_REV_AVAIL 50
-#define OID_RSA_ENCRYPTION 59
-#define OID_MD2_WITH_RSA 60
-#define OID_MD5_WITH_RSA 61
-#define OID_SHA1_WITH_RSA 62
-#define OID_SHA256_WITH_RSA 63
-#define OID_SHA384_WITH_RSA 64
-#define OID_SHA512_WITH_RSA 65
-#define OID_PKCS7_DATA 67
-#define OID_PKCS7_SIGNED_DATA 68
-#define OID_PKCS7_ENVELOPED_DATA 69
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA 70
-#define OID_PKCS7_DIGESTED_DATA 71
-#define OID_PKCS7_ENCRYPTED_DATA 72
-#define OID_PKCS9_EMAIL 74
-#define OID_PKCS9_CONTENT_TYPE 76
-#define OID_PKCS9_MESSAGE_DIGEST 77
-#define OID_PKCS9_SIGNING_TIME 78
-#define OID_MD2 84
-#define OID_MD5 85
-#define OID_3DES_EDE_CBC 87
-#define OID_AUTHORITY_INFO_ACCESS 109
-#define OID_OCSP_SIGNING 119
-#define OID_XMPP_ADDR 121
-#define OID_AUTHENTICATION_INFO 123
-#define OID_ACCESS_IDENTITY 124
-#define OID_CHARGING_IDENTITY 125
-#define OID_GROUP 126
-#define OID_OCSP 128
-#define OID_BASIC 129
-#define OID_NONCE 130
-#define OID_CRL 131
-#define OID_RESPONSE 132
-#define OID_NO_CHECK 133
-#define OID_ARCHIVE_CUTOFF 134
-#define OID_SERVICE_LOCATOR 135
-#define OID_DES_CBC 139
-#define OID_SHA1 140
-#define OID_SHA1_WITH_RSA_OIW 141
-#define OID_SHA256 157
-#define OID_SHA384 158
-#define OID_SHA512 159
-#define OID_NS_REVOCATION_URL 165
-#define OID_NS_CA_REVOCATION_URL 166
-#define OID_NS_CA_POLICY_URL 167
-#define OID_NS_COMMENT 168
-#define OID_PKI_MESSAGE_TYPE 177
-#define OID_PKI_STATUS 178
-#define OID_PKI_FAIL_INFO 179
-#define OID_PKI_SENDER_NONCE 180
-#define OID_PKI_RECIPIENT_NONCE 181
-#define OID_PKI_TRANS_ID 182
diff --git a/programs/pluto/oid.pl b/programs/pluto/oid.pl
deleted file mode 100644
index 52ac8eae0..000000000
--- a/programs/pluto/oid.pl
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/perl
-# Generates oid.h and oid.c out of oid.txt
-# Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-
-$copyright="Copyright (C) 2003-2004 Andreas Steffen, Zuercher Hochschule Winterthur";
-$automatic="This file has been automatically generated by the script oid.pl";
-$warning="Do not edit manually!";
-
-print "oid.pl generating oid.h and oid.c\n";
-
-# Generate oid.h
-
-open(OID_H, ">oid.h")
- or die "could not open 'oid.h': $!";
-
-print OID_H "/* Object identifiers (OIDs) used by FreeS/WAN\n",
- " * ", $copyright, "\n",
- " * \n",
- " * ", $automatic, "\n",
- " * ", $warning, "\n",
- " */\n\n",
- "typedef struct {\n",
- " u_char octet;\n",
- " u_int next;\n",
- " u_int down;\n",
- " const u_char *name;\n",
- "} oid_t;\n",
- "\n",
- "extern const oid_t oid_names[];\n",
- "\n",
- "#define OID_UNKNOWN -1\n";
-
-# parse oid.txt
-
-open(SRC, "<oid.txt")
- or die "could not open 'oid.txt': $!";
-
-$counter = 0;
-$max_name = 0;
-$max_order = 0;
-
-while ($line = <SRC>)
-{
- $line =~ m/( *?)(0x\w{2})\s+(".*?")[ \t]*?([\w_]*?)\Z/;
-
- @order[$counter] = length($1);
- @octet[$counter] = $2;
- @name[$counter] = $3;
-
- if (length($1) > $max_order)
- {
- $max_order = length($1);
- }
- if (length($3) > $max_name)
- {
- $max_name = length($3);
- }
- if (length($4) > 0)
- {
- printf OID_H "#define %s%s%d\n", $4, "\t" x ((39-length($4))/8), $counter;
- }
- $counter++;
-}
-
-close SRC;
-close OID_H;
-
-# Generate oid.c
-
-open(OID_C, ">oid.c")
- or die "could not open 'oid.c': $!";
-
-print OID_C "/* List of some useful object identifiers (OIDs)\n",
- " * ", $copyright, "\n",
- " * \n",
- " * ", $automatic, "\n",
- " * ", $warning, "\n",
- " */\n",
- "\n",
- "#include <stdlib.h>\n",
- "\n",
- "#include \"oid.h\"\n",
- "\n",
- "const oid_t oid_names[] = {\n";
-
-for ($c = 0; $c < $counter; $c++)
-{
- $next = 0;
-
- for ($d = $c+1; $d < $counter && @order[$d] >= @order[$c]; $d++)
- {
- if (@order[$d] == @order[$c])
- {
- @next[$c] = $d;
- last;
- }
- }
-
- printf OID_C " {%s%s,%s%3d, %d, %s%s}%s /* %3d */\n"
- ,' ' x @order[$c]
- , @octet[$c]
- , ' ' x (1 + $max_order - @order[$c])
- , @next[$c]
- , @order[$c+1] > @order[$c]
- , @name[$c]
- , ' ' x ($max_name - length(@name[$c]))
- , $c != $counter-1 ? "," : " "
- , $c;
-}
-
-print OID_C "};\n" ;
-close OID_C;
diff --git a/programs/pluto/oid.txt b/programs/pluto/oid.txt
deleted file mode 100644
index e8750024e..000000000
--- a/programs/pluto/oid.txt
+++ /dev/null
@@ -1,184 +0,0 @@
-0x02 "ITU-T Administration"
- 0x82 ""
- 0x06 "Germany ITU-T member"
- 0x01 "Deutsche Telekom AG"
- 0x0A ""
- 0x07 ""
- 0x14 "ND"
-0x09 "data"
- 0x92 ""
- 0x26 ""
- 0x89 ""
- 0x93 ""
- 0xF2 ""
- 0x2C ""
- 0x64 "pilot"
- 0x01 "pilotAttributeType"
- 0x01 "UID"
- 0x19 "DC"
-0x55 "X.500"
- 0x04 "X.509"
- 0x03 "CN"
- 0x04 "S"
- 0x05 "SN"
- 0x06 "C"
- 0x07 "L"
- 0x08 "ST"
- 0x0A "O"
- 0x0B "OU"
- 0x0C "T"
- 0x0D "D"
- 0x24 "userCertificate"
- 0x29 "N"
- 0x2A "G"
- 0x2B "I"
- 0x2D "ID"
- 0x48 "role" OID_ROLE
- 0x1D "id-ce"
- 0x09 "subjectDirectoryAttrs"
- 0x0E "subjectKeyIdentifier" OID_SUBJECT_KEY_ID
- 0x0F "keyUsage"
- 0x10 "privateKeyUsagePeriod"
- 0x11 "subjectAltName" OID_SUBJECT_ALT_NAME
- 0x12 "issuerAltName"
- 0x13 "basicConstraints" OID_BASIC_CONSTRAINTS
- 0x15 "reasonCode" OID_CRL_REASON_CODE
- 0x1F "crlDistributionPoints" OID_CRL_DISTRIBUTION_POINTS
- 0x20 "certificatePolicies"
- 0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID
- 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE
- 0x37 "targetInformation" OID_TARGET_INFORMATION
- 0x38 "noRevAvail" OID_NO_REV_AVAIL
-0x2A ""
- 0x86 ""
- 0x48 ""
- 0x86 ""
- 0xF7 ""
- 0x0D "RSADSI"
- 0x01 "PKCS"
- 0x01 "PKCS-1"
- 0x01 "rsaEncryption" OID_RSA_ENCRYPTION
- 0x02 "md2WithRSAEncryption" OID_MD2_WITH_RSA
- 0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA
- 0x05 "sha-1WithRSAEncryption" OID_SHA1_WITH_RSA
- 0x0B "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
- 0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
- 0x0D "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
- 0x07 "PKCS-7"
- 0x01 "data" OID_PKCS7_DATA
- 0x02 "signedData" OID_PKCS7_SIGNED_DATA
- 0x03 "envelopedData" OID_PKCS7_ENVELOPED_DATA
- 0x04 "signedAndEnvelopedData" OID_PKCS7_SIGNED_ENVELOPED_DATA
- 0x05 "digestedData" OID_PKCS7_DIGESTED_DATA
- 0x06 "encryptedData" OID_PKCS7_ENCRYPTED_DATA
- 0x09 "PKCS-9"
- 0x01 "E" OID_PKCS9_EMAIL
- 0x02 "unstructuredName"
- 0x03 "contentType" OID_PKCS9_CONTENT_TYPE
- 0x04 "messageDigest" OID_PKCS9_MESSAGE_DIGEST
- 0x05 "signingTime" OID_PKCS9_SIGNING_TIME
- 0x06 "counterSignature"
- 0x07 "challengePassword"
- 0x08 "unstructuredAddress"
- 0x0E "extensionRequest"
- 0x02 "digestAlgorithm"
- 0x02 "md2" OID_MD2
- 0x05 "md5" OID_MD5
- 0x03 "encryptionAlgorithm"
- 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC
-0x2B ""
- 0x06 "dod"
- 0x01 "internet"
- 0x04 "private"
- 0x01 "enterprise"
- 0x82 ""
- 0x37 "Microsoft"
- 0x0A ""
- 0x03 ""
- 0x03 "msSGC"
- 0x89 ""
- 0x31 ""
- 0x01 ""
- 0x01 ""
- 0x02 ""
- 0x02 ""
- 0x4B "TCGID"
- 0x05 "security"
- 0x05 "mechanisms"
- 0x07 "id-pkix"
- 0x01 "id-pe"
- 0x01 "authorityInfoAccess" OID_AUTHORITY_INFO_ACCESS
- 0x03 "id-kp"
- 0x01 "serverAuth"
- 0x02 "clientAuth"
- 0x03 "codeSigning"
- 0x04 "emailProtection"
- 0x05 "ipsecEndSystem"
- 0x06 "ipsecTunnel"
- 0x07 "ipsecUser"
- 0x08 "timeStamping"
- 0x09 "ocspSigning" OID_OCSP_SIGNING
- 0x08 "id-otherNames"
- 0x05 "xmppAddr" OID_XMPP_ADDR
- 0x0A "id-aca"
- 0x01 "authenticationInfo" OID_AUTHENTICATION_INFO
- 0x02 "accessIdentity" OID_ACCESS_IDENTITY
- 0x03 "chargingIdentity" OID_CHARGING_IDENTITY
- 0x04 "group" OID_GROUP
- 0x30 "id-ad"
- 0x01 "ocsp" OID_OCSP
- 0x01 "basic" OID_BASIC
- 0x02 "nonce" OID_NONCE
- 0x03 "crl" OID_CRL
- 0x04 "response" OID_RESPONSE
- 0x05 "noCheck" OID_NO_CHECK
- 0x06 "archiveCutoff" OID_ARCHIVE_CUTOFF
- 0x07 "serviceLocator" OID_SERVICE_LOCATOR
- 0x0E "oiw"
- 0x03 "secsig"
- 0x02 "algorithms"
- 0x07 "des-cbc" OID_DES_CBC
- 0x1A "sha-1" OID_SHA1
- 0x1D "sha-1WithRSASignature" OID_SHA1_WITH_RSA_OIW
- 0x24 "TeleTrusT"
- 0x03 "algorithm"
- 0x03 "signatureAlgorithm"
- 0x01 "rsaSignature"
- 0x02 "rsaSigWithripemd160"
- 0x03 "rsaSigWithripemd128"
- 0x04 "rsaSigWithripemd256"
-0x60 ""
- 0x86 ""
- 0x48 ""
- 0x01 "organization"
- 0x65 "gov"
- 0x03 "csor"
- 0x04 "nistalgorithm"
- 0x02 "hashalgs"
- 0x01 "id-SHA-256" OID_SHA256
- 0x02 "id-SHA-384" OID_SHA384
- 0x03 "id-SHA-512" OID_SHA512
- 0x86 ""
- 0xf8 ""
- 0x42 "netscape"
- 0x01 ""
- 0x01 "nsCertType"
- 0x03 "nsRevocationUrl" OID_NS_REVOCATION_URL
- 0x04 "nsCaRevocationUrl" OID_NS_CA_REVOCATION_URL
- 0x08 "nsCaPolicyUrl" OID_NS_CA_POLICY_URL
- 0x0d "nsComment" OID_NS_COMMENT
- 0x03 "directory"
- 0x01 ""
- 0x03 "employeeNumber"
- 0x04 "policy"
- 0x01 "nsSGC"
- 0x45 "verisign"
- 0x01 "pki"
- 0x09 "attributes"
- 0x02 "messageType" OID_PKI_MESSAGE_TYPE
- 0x03 "pkiStatus" OID_PKI_STATUS
- 0x04 "failInfo" OID_PKI_FAIL_INFO
- 0x05 "senderNonce" OID_PKI_SENDER_NONCE
- 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE
- 0x07 "transID" OID_PKI_TRANS_ID
- 0x08 "extensionReq"
diff --git a/programs/pluto/packet.c b/programs/pluto/packet.c
deleted file mode 100644
index 9f04c8bb2..000000000
--- a/programs/pluto/packet.c
+++ /dev/null
@@ -1,1244 +0,0 @@
-/* parsing packets: formats and tools
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: packet.c,v 1.7 2005/01/06 22:39:04 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <netinet/in.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "packet.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-/* ISAKMP Header: for all messages
- * layout from RFC 2408 "ISAKMP" section 3.1
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Initiator !
- * ! Cookie !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Responder !
- * ! Cookie !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Message ID !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-static field_desc isa_fields[] = {
- { ft_raw, COOKIE_SIZE, "initiator cookie", NULL },
- { ft_raw, COOKIE_SIZE, "responder cookie", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names },
- { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names },
- { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names },
- { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL },
- { ft_len, 32/BITS_PER_BYTE, "length", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isakmp_hdr) };
-
-/* Generic portion of all ISAKMP payloads.
- * layout from RFC 2408 "ISAKMP" section 3.2
- * This describes the first 32-bit chunk of all payloads.
- * The previous next payload depends on the actual payload type.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-static field_desc isag_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-
-/* ISAKMP Data Attribute (generic representation within payloads)
- * layout from RFC 2408 "ISAKMP" section 3.3
- * This is not a payload type.
- * In TLV format, this is followed by a value field.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !A! Attribute Type ! AF=0 Attribute Length !
- * !F! ! AF=1 Attribute Value !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . AF=0 Attribute Value .
- * . AF=1 Not Transmitted .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/* Oakley Attributes */
-static field_desc isaat_fields_oakley[] = {
- { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_oakley_attribute_desc = {
- "ISAKMP Oakley attribute",
- isaat_fields_oakley, sizeof(struct isakmp_attribute) };
-
-/* IPsec DOI Attributes */
-static field_desc isaat_fields_ipsec[] = {
- { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipsec_attribute_desc = {
- "ISAKMP IPsec DOI attribute",
- isaat_fields_ipsec, sizeof(struct isakmp_attribute) };
-
-/* Mode Config Attributes */
-static field_desc isaat_fields_modecfg[] = {
- { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_modecfg_attribute_desc = {
- "ISAKMP ModeCfg attribute",
- isaat_fields_modecfg, sizeof(struct isakmp_attribute) };
-
-/* ISAKMP Security Association Payload
- * layout from RFC 2408 "ISAKMP" section 3.4
- * A variable length Situation follows.
- * Previous next payload: ISAKMP_NEXT_SA
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Situation ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isasa_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_sa_desc = { "ISAKMP Security Association Payload", isasa_fields, sizeof(struct isakmp_sa) };
-
-static field_desc ipsec_sit_field[] = {
- { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_t) };
-
-/* ISAKMP Proposal Payload
- * layout from RFC 2408 "ISAKMP" section 3.5
- * A variable length SPI follows.
- * Previous next payload: ISAKMP_NEXT_P
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Proposal # ! Protocol-Id ! SPI Size !# of Transforms!
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! SPI (variable) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isap_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names },
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, sizeof(struct isakmp_proposal) };
-
-/* ISAKMP Transform Payload
- * layout from RFC 2408 "ISAKMP" section 3.6
- * Variable length SA Attributes follow.
- * Previous next payload: ISAKMP_NEXT_T
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Transform # ! Transform-Id ! RESERVED2 !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ SA Attributes ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-/* PROTO_ISAKMP */
-static field_desc isat_fields_isakmp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_isakmp_transform_desc = {
- "ISAKMP Transform Payload (ISAKMP)",
- isat_fields_isakmp, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPSEC_AH */
-static field_desc isat_fields_ah[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ah_transform_desc = {
- "ISAKMP Transform Payload (AH)",
- isat_fields_ah, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPSEC_ESP */
-static field_desc isat_fields_esp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_esp_transform_desc = {
- "ISAKMP Transform Payload (ESP)",
- isat_fields_esp, sizeof(struct isakmp_transform) };
-
-/* PROTO_IPCOMP */
-static field_desc isat_fields_ipcomp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipcomp_transform_desc = {
- "ISAKMP Transform Payload (COMP)",
- isat_fields_ipcomp, sizeof(struct isakmp_transform) };
-
-
-/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.7
- * Variable Key Exchange Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_KE
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Key Exchange Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_keyex_desc = { "ISAKMP Key Exchange Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Identification Payload
- * layout from RFC 2408 "ISAKMP" section 3.8
- * See "struct identity" declared later.
- * Variable length Identification Data follow.
- * Previous next payload: ISAKMP_NEXT_ID
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! ID Type ! DOI Specific ID Data !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Identification Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isaid_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, /* ??? depends on DOI? */
- { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL }, /* ??? depends on DOI? */
- { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL }, /* ??? depends on DOI? */
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isaid_fields, sizeof(struct isakmp_id) };
-
-/* IPSEC Identification Payload Content
- * layout from RFC 2407 "IPsec DOI" section 4.6.2
- * See struct isakmp_id declared earlier.
- * Note: Hashing skips the ISAKMP generic payload header
- * Variable length Identification Data follow.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! ID Type ! Protocol ID ! Port !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ~ Identification Data ~
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isaiid_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
- { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL }, /* ??? UDP/TCP or 0? */
- { ft_nat, 16/BITS_PER_BYTE, "port", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload (IPsec DOI)", isaiid_fields, sizeof(struct isakmp_ipsec_id) };
-
-/* ISAKMP Certificate Payload: oddball fixed field beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.9
- * Variable length Certificate Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_CERT.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert Encoding ! !
- * +-+-+-+-+-+-+-+-+ !
- * ~ Certificate Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isacert_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names },
- { ft_end, 0, NULL, NULL }
-};
-
-/* Note: the size field of isakmp_ipsec_certificate_desc cannot be
- * sizeof(struct isakmp_cert) because that will rounded up for padding.
- */
- struct_desc isakmp_ipsec_certificate_desc = { "ISAKMP Certificate Payload", isacert_fields, ISAKMP_CERT_SIZE };
-
-/* ISAKMP Certificate Request Payload: oddball field beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.10
- * Variable length Certificate Types and Certificate Authorities follow.
- * Previous next payload: ISAKMP_NEXT_CR.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert. Type ! !
- * +-+-+-+-+-+-+-+-+ !
- * ~ Certificate Authority ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isacr_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names },
- { ft_end, 0, NULL, NULL }
-};
-
-/* Note: the size field of isakmp_ipsec_cert_req_desc cannot be
- * sizeof(struct isakmp_cr) because that will rounded up for padding.
- */
-struct_desc isakmp_ipsec_cert_req_desc = { "ISAKMP Certificate RequestPayload", isacr_fields, ISAKMP_CR_SIZE };
-
-/* ISAKMP Hash Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.11
- * Variable length Hash Data follow.
- * Previous next payload: ISAKMP_NEXT_HASH.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Hash Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_hash_desc = { "ISAKMP Hash Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Signature Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.12
- * Variable length Signature Data follow.
- * Previous next payload: ISAKMP_NEXT_SIG.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Signature Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_signature_desc = { "ISAKMP Signature Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Nonce Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.13
- * Variable length Nonce Data follow.
- * Previous next payload: ISAKMP_NEXT_NONCE.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Nonce Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_nonce_desc = { "ISAKMP Nonce Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP Notification Payload
- * layout from RFC 2408 "ISAKMP" section 3.14
- * This is followed by a variable length SPI
- * and then possibly by variable length Notification Data.
- * Previous next payload: ISAKMP_NEXT_N
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Protocol-ID ! SPI Size ! Notify Message Type !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Security Parameter Index (SPI) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Notification Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isan_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC, ESP, ... */
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", &notification_names },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fields, sizeof(struct isakmp_notification) };
-
-/* ISAKMP Delete Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length SPI.
- * Previous next payload: ISAKMP_NEXT_D
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Protocol-Id ! SPI Size ! # of SPIs !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Security Parameter Index(es) (SPI) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isad_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC */
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_delete_desc = { "ISAKMP Delete Payload", isad_fields, sizeof(struct isakmp_delete) };
-
-/* ISAKMP Vendor ID Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length VID.
- * Previous next payload: ISAKMP_NEXT_VID
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Vendor ID (VID) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_vendor_id_desc = { "ISAKMP Vendor ID Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* MODECFG */
-/*
- * From draft-dukes-ike-mode-cfg
-3.2. Attribute Payload
- 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Next Payload ! RESERVED ! Payload Length !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Type ! RESERVED ! Identifier !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! !
- ~ Attributes ~
- ! !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-static field_desc isaattr_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_attr_desc = { "ISAKMP Mode Attribute", isaattr_fields, sizeof(struct isakmp_mode_attr) };
-
-/* ISAKMP NAT-Traversal NAT-D
- * layout from draft-ietf-ipsec-nat-t-ike-01.txt section 3.2
- *
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! HASH of the address and port !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct_desc isakmp_nat_d = { "ISAKMP NAT-D Payload", isag_fields, sizeof(struct isakmp_generic) };
-
-/* ISAKMP NAT-Traversal NAT-OA
- * layout from draft-ietf-ipsec-nat-t-ike-01.txt section 4.2
- *
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! ID Type ! RESERVED ! RESERVED !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! IPv4 (4 octets) or IPv6 address (16 octets) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-static field_desc isanat_oa_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
- { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
-};
-
-struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof(struct isakmp_nat_oa) };
-
-/* descriptor for each payload type
- *
- * There is a slight problem in that some payloads differ, depending
- * on the mode. Since this is table only used for top-level payloads,
- * Proposal and Transform payloads need not be handled.
- * That leaves only Identification payloads as a problem.
- * We make all these entries NULL
- */
-struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = {
- NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */
- &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */
- NULL, /* 2 ISAKMP_NEXT_P (Proposal) */
- NULL, /* 3 ISAKMP_NEXT_T (Transform) */
- &isakmp_keyex_desc, /* 4 ISAKMP_NEXT_KE (Key Exchange) */
- NULL, /* 5 ISAKMP_NEXT_ID (Identification) */
- &isakmp_ipsec_certificate_desc, /* 6 ISAKMP_NEXT_CERT (Certificate) */
- &isakmp_ipsec_cert_req_desc, /* 7 ISAKMP_NEXT_CR (Certificate Request) */
- &isakmp_hash_desc, /* 8 ISAKMP_NEXT_HASH (Hash) */
- &isakmp_signature_desc, /* 9 ISAKMP_NEXT_SIG (Signature) */
- &isakmp_nonce_desc, /* 10 ISAKMP_NEXT_NONCE (Nonce) */
- &isakmp_notification_desc, /* 11 ISAKMP_NEXT_N (Notification) */
- &isakmp_delete_desc, /* 12 ISAKMP_NEXT_D (Delete) */
- &isakmp_vendor_id_desc, /* 13 ISAKMP_NEXT_VID (Vendor ID) */
- &isakmp_attr_desc, /* 14 ISAKMP_NEXT_ATTR (Mode Config) */
- NULL, /* 15 */
- NULL, /* 16 */
- NULL, /* 17 */
- NULL, /* 18 */
- NULL, /* 19 */
- &isakmp_nat_d, /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */
- &isakmp_nat_oa, /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */
-};
-
-void
-init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name)
-{
- pbs->container = NULL;
- pbs->desc = NULL;
- pbs->name = name;
- pbs->start = pbs->cur = start;
- pbs->roof = start + len;
- pbs->lenfld = NULL;
- pbs->lenfld_desc = NULL;
-}
-
-#ifdef DEBUG
-
-/* print a host struct
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size! This requires
- * that all padding be explicit.
- */
-void
-DBG_print_struct(const char *label, const void *struct_ptr
-, struct_desc *sd, bool len_meaningful)
-{
- bool immediate = FALSE;
- const u_int8_t *inp = struct_ptr;
- field_desc *fp;
-
- DBG_log("%s%s:", label, sd->name);
-
- for (fp = sd->fields; fp->field_type != ft_end; fp++)
- {
- int i = fp->size;
- u_int32_t n = 0;
-
- switch (fp->field_type)
- {
- case ft_mbz: /* must be zero */
- inp += i;
- break;
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- switch (i)
- {
- case 8/BITS_PER_BYTE:
- n = *(const u_int8_t *)inp;
- break;
- case 16/BITS_PER_BYTE:
- n = *(const u_int16_t *)inp;
- break;
- case 32/BITS_PER_BYTE:
- n = *(const u_int32_t *)inp;
- break;
- default:
- bad_case(i);
- }
- switch (fp->field_type)
- {
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- if (!immediate && !len_meaningful)
- break;
- /* FALL THROUGH */
- case ft_nat: /* natural number (may be 0) */
- DBG_log(" %s: %lu", fp->name, (unsigned long)n);
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n));
- break;
- case ft_set: /* bits representing set */
- DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n));
- break;
- default:
- bad_case(fp->field_type);
- }
- inp += i;
- break;
-
- case ft_raw: /* bytes to be left in network-order */
- {
- char m[50]; /* arbitrary limit on name width in log */
-
- snprintf(m, sizeof(m), " %s:", fp->name);
- DBG_dump(m, inp, i);
- inp += i;
- }
- break;
- default:
- bad_case(fp->field_type);
- }
- }
-}
-
-static void
-DBG_prefix_print_struct(const pb_stream *pbs
-, const char *label, const void *struct_ptr
-, struct_desc *sd, bool len_meaningful)
-{
- /* print out a title, with a prefix of asterisks to show
- * the nesting level.
- */
- char space[40]; /* arbitrary limit on label+flock-of-* */
- size_t len = strlen(label);
-
- if (sizeof(space) <= len)
- {
- DBG_print_struct(label, struct_ptr, sd, len_meaningful);
- }
- else
- {
- const pb_stream *p = pbs;
- char *pre = &space[sizeof(space) - (len + 1)];
-
- strcpy(pre, label);
-
- /* put at least one * out */
- for (;;)
- {
- if (pre <= space)
- break;
- *--pre = '*';
- if (p == NULL)
- break;
- p = p->container;
- }
- DBG_print_struct(pre, struct_ptr, sd, len_meaningful);
- }
-}
-
-#endif
-
-/* "parse" a network struct into a host struct.
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size! This requires
- * that all padding be explicit.
- *
- * If obj_pbs is supplied, a new pb_stream is created for the
- * variable part of the structure (this depends on their
- * being one length field in the structure). The cursor of this
- * new PBS is set to after the parsed part of the struct.
- *
- * This routine returns TRUE iff it succeeds.
- */
-
-bool
-in_struct(void *struct_ptr, struct_desc *sd
-, pb_stream *ins, pb_stream *obj_pbs)
-{
- err_t ugh = NULL;
- u_int8_t *cur = ins->cur;
-
- if (ins->roof - cur < (ptrdiff_t)sd->size)
- {
- ugh = builddiag("not enough room in input packet for %s", sd->name);
- }
- else
- {
- u_int8_t *roof = cur + sd->size; /* may be changed by a length field */
- u_int8_t *outp = struct_ptr;
- bool immediate = FALSE;
- field_desc *fp;
-
- for (fp = sd->fields; ugh == NULL; fp++)
- {
- size_t i = fp->size;
-
- passert(ins->roof - cur >= (ptrdiff_t)i);
- passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
- passert(outp - (cur - ins->cur) == struct_ptr);
-
-#if 0
- DBG(DBG_PARSING, DBG_log("%d %s"
- , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));
-#endif
- switch (fp->field_type)
- {
- case ft_mbz: /* must be zero */
- for (; i != 0; i--)
- {
- if (*cur++ != 0)
- {
- ugh = builddiag("byte %d of %s must be zero, but is not"
- , (int) (cur - ins->cur), sd->name);
- break;
- }
- *outp++ = '\0'; /* probably redundant */
- }
- break;
-
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- {
- u_int32_t n = 0;
-
- for (; i != 0; i--)
- n = (n << BITS_PER_BYTE) | *cur++;
-
- switch (fp->field_type)
- {
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- {
- u_int32_t len = fp->field_type == ft_len? n
- : immediate? sd->size : n + sd->size;
-
- if (len < sd->size)
- {
- ugh = builddiag("%s of %s is smaller than minimum"
- , fp->name, sd->name);
- }
- else if (pbs_left(ins) < len)
- {
- ugh = builddiag("%s of %s is larger than can fit"
- , fp->name, sd->name);
- }
- else
- {
- roof = ins->cur + len;
- }
- break;
- }
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- if (enum_name(fp->desc, n) == NULL)
- {
- ugh = builddiag("%s of %s has an unknown value: %lu"
- , fp->name, sd->name, (unsigned long)n);
- }
- /* FALL THROUGH */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- break;
- case ft_set: /* bits representing set */
- if (!testset(fp->desc, n))
- {
- ugh = builddiag("bitset %s of %s has unknown member(s): %s"
- , fp->name, sd->name, bitnamesof(fp->desc, n));
- }
- break;
- default:
- break;
- }
- i = fp->size;
- switch (i)
- {
- case 8/BITS_PER_BYTE:
- *(u_int8_t *)outp = n;
- break;
- case 16/BITS_PER_BYTE:
- *(u_int16_t *)outp = n;
- break;
- case 32/BITS_PER_BYTE:
- *(u_int32_t *)outp = n;
- break;
- default:
- bad_case(i);
- }
- outp += i;
- break;
- }
-
- case ft_raw: /* bytes to be left in network-order */
- for (; i != 0; i--)
- {
- *outp++ = *cur++;
- }
- break;
-
- case ft_end: /* end of field list */
- passert(cur == ins->cur + sd->size);
- if (obj_pbs != NULL)
- {
- init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name);
- obj_pbs->container = ins;
- obj_pbs->desc = sd;
- obj_pbs->cur = cur;
- }
- ins->cur = roof;
- DBG(DBG_PARSING
- , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE));
- return TRUE;
-
- default:
- bad_case(fp->field_type);
- }
- }
- }
-
- /* some failure got us here: report it */
- loglog(RC_LOG_SERIOUS, ugh);
- return FALSE;
-}
-
-bool
-in_raw(void *bytes, size_t len, pb_stream *ins, const char *name)
-{
- if (pbs_left(ins) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name);
- return FALSE;
- }
- else
- {
- if (bytes == NULL)
- {
- DBG(DBG_PARSING
- , DBG_log("skipping %u raw bytes of %s (%s)"
- , (unsigned) len, ins->name, name);
- DBG_dump(name, ins->cur, len));
- }
- else
- {
- memcpy(bytes, ins->cur, len);
- DBG(DBG_PARSING
- , DBG_log("parsing %u raw bytes of %s into %s"
- , (unsigned) len, ins->name, name);
- DBG_dump(name, bytes, len));
- }
- ins->cur += len;
- return TRUE;
- }
-}
-
-/* "emit" a host struct into a network packet.
- *
- * This code assumes that the network and host structure
- * members have the same alignment and size! This requires
- * that all padding be explicit.
- *
- * If obj_pbs is non-NULL, its pbs describes a new output stream set up
- * to contain the object. The cursor will be left at the variable part.
- * This new stream must subsequently be finalized by close_output_pbs().
- *
- * The value of any field of type ft_len is computed, not taken
- * from the input struct. The length is actually filled in when
- * the object's output stream is finalized. If obj_pbs is NULL,
- * finalization is done by out_struct before it returns.
- *
- * This routine returns TRUE iff it succeeds.
- */
-
-bool
-out_struct(const void *struct_ptr, struct_desc *sd
-, pb_stream *outs, pb_stream *obj_pbs)
-{
- err_t ugh = NULL;
- const u_int8_t *inp = struct_ptr;
- u_int8_t *cur = outs->cur;
-
- DBG(DBG_EMITTING
- , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL));
-
- if (outs->roof - cur < (ptrdiff_t)sd->size)
- {
- ugh = builddiag("not enough room left in output packet to place %s"
- , sd->name);
- }
- else
- {
- bool immediate = FALSE;
- pb_stream obj;
- field_desc *fp;
-
- obj.lenfld = NULL; /* until a length field is discovered */
- obj.lenfld_desc = NULL;
-
- for (fp = sd->fields; ugh == NULL; fp++)
- {
- size_t i = fp->size;
-
- passert(outs->roof - cur >= (ptrdiff_t)i);
- passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i));
- passert(inp - (cur - outs->cur) == struct_ptr);
-
-#if 0
- DBG(DBG_EMITTING, DBG_log("%d %s"
- , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name);
-#endif
- switch (fp->field_type)
- {
- case ft_mbz: /* must be zero */
- inp += i;
- for (; i != 0; i--)
- *cur++ = '\0';
- break;
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- {
- u_int32_t n = 0;
-
- switch (i)
- {
- case 8/BITS_PER_BYTE:
- n = *(const u_int8_t *)inp;
- break;
- case 16/BITS_PER_BYTE:
- n = *(const u_int16_t *)inp;
- break;
- case 32/BITS_PER_BYTE:
- n = *(const u_int32_t *)inp;
- break;
- default:
- bad_case(i);
- }
-
- switch (fp->field_type)
- {
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- if (immediate)
- break; /* not a length */
- /* We can't check the length because it will likely
- * be filled in after variable part is supplied.
- * We do record where this is so that it can be
- * filled in by a subsequent close_output_pbs().
- */
- passert(obj.lenfld == NULL); /* only one ft_len allowed */
- obj.lenfld = cur;
- obj.lenfld_desc = fp;
- break;
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- if (enum_name(fp->desc, n) == NULL)
- {
- ugh = builddiag("%s of %s has an unknown value: %lu"
- , fp->name, sd->name, (unsigned long)n);
- }
- /* FALL THROUGH */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- break;
- case ft_set: /* bits representing set */
- if (!testset(fp->desc, n))
- {
- ugh = builddiag("bitset %s of %s has unknown member(s): %s"
- , fp->name, sd->name, bitnamesof(fp->desc, n));
- }
- break;
- default:
- break;
- }
-
- while (i-- != 0)
- {
- cur[i] = (u_int8_t)n;
- n >>= BITS_PER_BYTE;
- }
- inp += fp->size;
- cur += fp->size;
- break;
- }
- case ft_raw: /* bytes to be left in network-order */
- for (; i != 0; i--)
- *cur++ = *inp++;
- break;
- case ft_end: /* end of field list */
- passert(cur == outs->cur + sd->size);
-
- obj.container = outs;
- obj.desc = sd;
- obj.name = sd->name;
- obj.start = outs->cur;
- obj.cur = cur;
- obj.roof = outs->roof; /* limit of possible */
- /* obj.lenfld and obj.lenfld_desc already set */
-
- if (obj_pbs == NULL)
- {
- close_output_pbs(&obj); /* fill in length field, if any */
- }
- else
- {
- /* We set outs->cur to outs->roof so that
- * any attempt to output something into outs
- * before obj is closed will trigger an error.
- */
- outs->cur = outs->roof;
-
- *obj_pbs = obj;
- }
- return TRUE;
-
- default:
- bad_case(fp->field_type);
- }
- }
- }
-
- /* some failure got us here: report it */
- loglog(RC_LOG_SERIOUS, ugh); /* ??? serious, but errno not relevant */
- return FALSE;
-}
-
-bool
-out_generic(u_int8_t np, struct_desc *sd
-, pb_stream *outs, pb_stream *obj_pbs)
-{
- struct isakmp_generic gen;
-
- passert(sd->fields == isakmp_generic_desc.fields);
- gen.isag_np = np;
- return out_struct(&gen, sd, outs, obj_pbs);
-}
-
-bool
-out_generic_raw(u_int8_t np, struct_desc *sd
-, pb_stream *outs, const void *bytes, size_t len, const char *name)
-{
- pb_stream pbs;
-
- if (!out_generic(np, sd, outs, &pbs)
- || !out_raw(bytes, len, &pbs, name))
- return FALSE;
- close_output_pbs(&pbs);
- return TRUE;
-}
-
-bool
-out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name)
-{
- if (pbs_left(outs) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s"
- , (unsigned long) len, name, outs->name);
- return FALSE;
- }
- else
- {
- DBG(DBG_EMITTING
- , DBG_log("emitting %u raw bytes of %s into %s"
- , (unsigned) len, name, outs->name);
- DBG_dump(name, bytes, len));
- memcpy(outs->cur, bytes, len);
- outs->cur += len;
- return TRUE;
- }
-}
-
-bool
-out_zero(size_t len, pb_stream *outs, const char *name)
-{
- if (pbs_left(outs) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name);
- return FALSE;
- }
- else
- {
- DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s"
- , (unsigned) len, name, outs->name));
- memset(outs->cur, 0x00, len);
- outs->cur += len;
- return TRUE;
- }
-}
-
-/* Record current length.
- * Note: currently, this may be repeated any number of times;
- * the last one wins.
- */
-void
-close_output_pbs(pb_stream *pbs)
-{
- if (pbs->lenfld != NULL)
- {
- u_int32_t len = pbs_offset(pbs);
- int i = pbs->lenfld_desc->size;
-
- if (pbs->lenfld_desc->field_type == ft_lv)
- len -= sizeof(struct isakmp_attribute);
- DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu"
- , pbs->name, (unsigned long) len));
- while (i-- != 0)
- {
- pbs->lenfld[i] = (u_int8_t)len;
- len >>= BITS_PER_BYTE;
- }
- }
- if (pbs->container != NULL)
- pbs->container->cur = pbs->cur; /* pass space utilization up */
-}
diff --git a/programs/pluto/packet.h b/programs/pluto/packet.h
deleted file mode 100644
index 676a5e6cd..000000000
--- a/programs/pluto/packet.h
+++ /dev/null
@@ -1,655 +0,0 @@
-/* parsing packets: formats and tools
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: packet.h,v 1.5 2005/01/06 22:10:15 as Exp $
- */
-
-#ifndef _PACKET_H
-#define _PACKET_H
-
-/* a struct_desc describes a structure for the struct I/O routines.
- * This requires arrays of field_desc values to describe struct fields.
- */
-
-typedef const struct struct_desc {
- const char *name;
- const struct field_desc *fields;
- size_t size;
-} struct_desc;
-
-/* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set,
- * the subsequent ft_lv field will be interpreted as an immediate value.
- * This matches how attributes are encoded.
- * See RFC 2408 "ISAKMP" 3.3
- */
-
-enum field_type {
- ft_mbz, /* must be zero */
- ft_nat, /* natural number (may be 0) */
- ft_len, /* length of this struct and any following crud */
- ft_lv, /* length/value field of attribute */
- ft_enum, /* value from an enumeration */
- ft_loose_enum, /* value from an enumeration with only some names known */
- ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
- ft_af_enum, /* Attribute Format + value from an enumeration */
- ft_set, /* bits representing set */
- ft_raw, /* bytes to be left in network-order */
- ft_end, /* end of field list */
-};
-
-typedef const struct field_desc {
- enum field_type field_type;
- int size; /* size, in bytes, of field */
- const char *name;
- const void *desc; /* enum_names for enum or char *[] for bits */
-} field_desc;
-
-/* The formatting of input and output of packets is done
- * through packet_byte_stream objects.
- * These describe a stream of bytes in memory.
- * Several routines are provided to manipulate these objects
- * Actual packet transfer is done elsewhere.
- */
-typedef struct packet_byte_stream {
- struct packet_byte_stream *container; /* PBS of which we are part */
- struct_desc *desc;
- const char *name; /* what does this PBS represent? */
- u_int8_t
- *start,
- *cur, /* current position in stream */
- *roof; /* byte after last in PBS (actually just a limit on output) */
- /* For an output PBS, the length field will be filled in later so
- * we need to record its particulars. Note: it may not be aligned.
- */
- u_int8_t *lenfld;
- field_desc *lenfld_desc;
-} pb_stream;
-
-/* For an input PBS, pbs_offset is amount of stream processed.
- * For an output PBS, pbs_offset is current size of stream.
- * For an input PBS, pbs_room is size of stream.
- * For an output PBS, pbs_room is maximum size allowed.
- */
-#define pbs_offset(pbs) ((size_t)((pbs)->cur - (pbs)->start))
-#define pbs_room(pbs) ((size_t)((pbs)->roof - (pbs)->start))
-#define pbs_left(pbs) ((size_t)((pbs)->roof - (pbs)->cur))
-
-extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name);
-
-extern bool in_struct(void *struct_ptr, struct_desc *sd,
- pb_stream *ins, pb_stream *obj_pbs);
-extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name);
-
-extern bool out_struct(const void *struct_ptr, struct_desc *sd,
- pb_stream *outs, pb_stream *obj_pbs);
-extern bool out_generic(u_int8_t np, struct_desc *sd,
- pb_stream *outs, pb_stream *obj_pbs);
-extern bool out_generic_raw(u_int8_t np, struct_desc *sd,
- pb_stream *outs, const void *bytes, size_t len, const char *name);
-#define out_generic_chunk(np, sd, outs, ch, name) \
- out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
-extern bool out_zero(size_t len, pb_stream *outs, const char *name);
-extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name);
-#define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name))
-extern void close_output_pbs(pb_stream *pbs);
-
-#ifdef DEBUG
-extern void DBG_print_struct(const char *label, const void *struct_ptr,
- struct_desc *sd, bool len_meaningful);
-#endif
-
-/* ISAKMP Header: for all messages
- * layout from RFC 2408 "ISAKMP" section 3.1
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Initiator !
- * ! Cookie !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Responder !
- * ! Cookie !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Message ID !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * Although the drafts are a little unclear, there are a few
- * places that specify that messages should be padded with 0x00
- * octets (bytes) to make the length a multiple of something.
- *
- * RFC 2408 "ISAKMP" 3.6 specifies that all messages will be
- * padded to be a multiple of 4 octets in length.
- * ??? This looks vestigial, and we ignore this requirement.
- *
- * RFC 2409 "IKE" Appedix B specifies:
- * Each message should be padded up to the nearest block size
- * using bytes containing 0x00.
- * ??? This does not appear to be limited to encrypted messages,
- * but it surely must be: the block size is meant to be the encryption
- * block size, and that is meaningless for a non-encrypted message.
- *
- * RFC 2409 "IKE" 5.3 specifies:
- * Encrypted payloads are padded up to the nearest block size.
- * All padding bytes, except for the last one, contain 0x00. The
- * last byte of the padding contains the number of the padding
- * bytes used, excluding the last one. Note that this means there
- * will always be padding.
- * ??? This is nuts since payloads are not padded, messages are.
- * It also contradicts Appendix B. So we ignore it.
- *
- * Summary: we pad encrypted output messages with 0x00 to bring them
- * up to a multiple of the encryption block size. On input, we require
- * that any encrypted portion of a message be a multiple of the encryption
- * block size. After any decryption, we ignore padding (any bytes after
- * the first payload that specifies a next payload of none; we don't
- * require them to be zero).
- */
-
-struct isakmp_hdr
-{
- u_int8_t isa_icookie[COOKIE_SIZE];
- u_int8_t isa_rcookie[COOKIE_SIZE];
- u_int8_t isa_np; /* Next payload */
- u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
-#define ISA_MAJ_SHIFT 4
-#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
- u_int8_t isa_xchg; /* Exchange type */
- u_int8_t isa_flags;
- u_int32_t isa_msgid; /* Message ID (RAW) */
- u_int32_t isa_length; /* Length of message */
-};
-
-extern struct_desc isakmp_hdr_desc;
-
-/* Generic portion of all ISAKMP payloads.
- * layout from RFC 2408 "ISAKMP" section 3.2
- * This describes the first 32-bit chunk of all payloads.
- * The previous next payload depends on the actual payload type.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_generic
-{
- u_int8_t isag_np;
- u_int8_t isag_reserved;
- u_int16_t isag_length;
-};
-
-extern struct_desc isakmp_generic_desc;
-
-/* ISAKMP Data Attribute (generic representation within payloads)
- * layout from RFC 2408 "ISAKMP" section 3.3
- * This is not a payload type.
- * In TLV format, this is followed by a value field.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * !A! Attribute Type ! AF=0 Attribute Length !
- * !F! ! AF=1 Attribute Value !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * . AF=0 Attribute Value .
- * . AF=1 Not Transmitted .
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_attribute
-{
- /* The high order bit of isaat_af_type is the Attribute Format
- * If it is off, the format is TLV: lv is the length of the following
- * attribute value.
- * If it is on, the format is TV: lv is the value of the attribute.
- * ISAKMP_ATTR_AF_MASK is the mask in host form.
- *
- * The low order 15 bits of isaat_af_type is the Attribute Type.
- * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
- */
- u_int16_t isaat_af_type; /* high order bit: AF; lower 15: rtype */
- u_int16_t isaat_lv; /* Length or value */
-};
-
-#define ISAKMP_ATTR_AF_MASK 0x8000
-#define ISAKMP_ATTR_AF_TV ISAKMP_ATTR_AF_MASK /* value in lv */
-#define ISAKMP_ATTR_AF_TLV 0 /* length in lv; value follows */
-
-#define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
-
-extern struct_desc
- isakmp_oakley_attribute_desc,
- isakmp_ipsec_attribute_desc;
-
-/* ISAKMP Security Association Payload
- * layout from RFC 2408 "ISAKMP" section 3.4
- * A variable length Situation follows.
- * Previous next payload: ISAKMP_NEXT_SA
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Situation ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_sa
-{
- u_int8_t isasa_np; /* Next payload */
- u_int8_t isasa_reserved;
- u_int16_t isasa_length; /* Payload length */
- u_int32_t isasa_doi; /* DOI */
-};
-
-extern struct_desc isakmp_sa_desc;
-
-extern struct_desc ipsec_sit_desc;
-
-/* ISAKMP Proposal Payload
- * layout from RFC 2408 "ISAKMP" section 3.5
- * A variable length SPI follows.
- * Previous next payload: ISAKMP_NEXT_P
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Proposal # ! Protocol-Id ! SPI Size !# of Transforms!
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! SPI (variable) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_proposal
-{
- u_int8_t isap_np;
- u_int8_t isap_reserved;
- u_int16_t isap_length;
- u_int8_t isap_proposal;
- u_int8_t isap_protoid;
- u_int8_t isap_spisize;
- u_int8_t isap_notrans; /* Number of transforms */
-};
-
-extern struct_desc isakmp_proposal_desc;
-
-/* ISAKMP Transform Payload
- * layout from RFC 2408 "ISAKMP" section 3.6
- * Variable length SA Attributes follow.
- * Previous next payload: ISAKMP_NEXT_T
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Transform # ! Transform-Id ! RESERVED2 !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ SA Attributes ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_transform
-{
- u_int8_t isat_np;
- u_int8_t isat_reserved;
- u_int16_t isat_length;
- u_int8_t isat_transnum; /* Number of the transform */
- u_int8_t isat_transid;
- u_int16_t isat_reserved2;
-};
-
-extern struct_desc
- isakmp_isakmp_transform_desc,
- isakmp_ah_transform_desc,
- isakmp_esp_transform_desc,
- isakmp_ipcomp_transform_desc;
-
-/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.7
- * Variable Key Exchange Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_KE
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Key Exchange Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_keyex_desc;
-
-/* ISAKMP Identification Payload
- * layout from RFC 2408 "ISAKMP" section 3.8
- * See "struct identity" declared later.
- * Variable length Identification Data follow.
- * Previous next payload: ISAKMP_NEXT_ID
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! ID Type ! DOI Specific ID Data !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Identification Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_id
-{
- u_int8_t isaid_np;
- u_int8_t isaid_reserved;
- u_int16_t isaid_length;
- u_int8_t isaid_idtype;
- u_int8_t isaid_doi_specific_a;
- u_int16_t isaid_doi_specific_b;
-};
-
-extern struct_desc isakmp_identification_desc;
-
-/* IPSEC Identification Payload Content
- * layout from RFC 2407 "IPsec DOI" section 4.6.2
- * See struct isakmp_id declared earlier.
- * Note: Hashing skips the ISAKMP generic payload header
- * Variable length Identification Data follow.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! ID Type ! Protocol ID ! Port !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ~ Identification Data ~
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_ipsec_id
-{
- u_int8_t isaiid_np;
- u_int8_t isaiid_reserved;
- u_int16_t isaiid_length;
- u_int8_t isaiid_idtype;
- u_int8_t isaiid_protoid;
- u_int16_t isaiid_port;
-};
-
-extern struct_desc isakmp_ipsec_identification_desc;
-
-/* ISAKMP Certificate Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.9
- * Variable length Certificate Data follow the generic fields.
- * Previous next payload: ISAKMP_NEXT_CERT.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert Encoding ! !
- * +-+-+-+-+-+-+-+-+ !
- * ~ Certificate Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_cert
-{
- u_int8_t isacert_np;
- u_int8_t isacert_reserved;
- u_int16_t isacert_length;
- u_int8_t isacert_type;
-};
-
-/* NOTE: this packet type has a fixed portion that is not a
- * multiple of 4 octets. This means that sizeof(struct isakmp_cert)
- * yields the wrong value for the length.
- */
-#define ISAKMP_CERT_SIZE 5
-
-extern struct_desc isakmp_ipsec_certificate_desc;
-
-/* ISAKMP Certificate Request Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.10
- * Variable length Certificate Types and Certificate Authorities follow.
- * Previous next payload: ISAKMP_NEXT_CR.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Cert. Type ! !
- * +-+-+-+-+-+-+-+-+ !
- * ~ Certificate Authority ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_cr
-{
- u_int8_t isacr_np;
- u_int8_t isacr_reserved;
- u_int16_t isacr_length;
- u_int8_t isacr_type;
-};
-
-/* NOTE: this packet type has a fixed portion that is not a
- * multiple of 4 octets. This means that sizeof(struct isakmp_cr)
- * yields the wrong value for the length.
- */
-#define ISAKMP_CR_SIZE 5
-
-extern struct_desc isakmp_ipsec_cert_req_desc;
-
-/* ISAKMP Hash Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.11
- * Variable length Hash Data follow.
- * Previous next payload: ISAKMP_NEXT_HASH.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Hash Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_hash_desc;
-
-/* ISAKMP Signature Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.12
- * Variable length Signature Data follow.
- * Previous next payload: ISAKMP_NEXT_SIG.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Signature Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_signature_desc;
-
-/* ISAKMP Nonce Payload: no fixed fields beyond the generic ones.
- * layout from RFC 2408 "ISAKMP" section 3.13
- * Variable length Nonce Data follow.
- * Previous next payload: ISAKMP_NEXT_NONCE.
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Nonce Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_nonce_desc;
-
-/* ISAKMP Notification Payload
- * layout from RFC 2408 "ISAKMP" section 3.14
- * This is followed by a variable length SPI
- * and then possibly by variable length Notification Data.
- * Previous next payload: ISAKMP_NEXT_N
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Protocol-ID ! SPI Size ! Notify Message Type !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Security Parameter Index (SPI) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Notification Data ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_notification
-{
- u_int8_t isan_np;
- u_int8_t isan_reserved;
- u_int16_t isan_length;
- u_int32_t isan_doi;
- u_int8_t isan_protoid;
- u_int8_t isan_spisize;
- u_int16_t isan_type;
-};
-
-extern struct_desc isakmp_notification_desc;
-
-/* ISAKMP Delete Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length SPI.
- * Previous next payload: ISAKMP_NEXT_D
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Domain of Interpretation (DOI) !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Protocol-Id ! SPI Size ! # of SPIs !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Security Parameter Index(es) (SPI) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-struct isakmp_delete
-{
- u_int8_t isad_np;
- u_int8_t isad_reserved;
- u_int16_t isad_length;
- u_int32_t isad_doi;
- u_int8_t isad_protoid;
- u_int8_t isad_spisize;
- u_int16_t isad_nospi;
-};
-
-extern struct_desc isakmp_delete_desc;
-
-/* From draft-dukes-ike-mode-cfg
-3.2. Attribute Payload
- 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Next Payload ! RESERVED ! Payload Length !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Type ! RESERVED ! Identifier !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! !
- ! !
- ~ Attributes ~
- ! !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-struct isakmp_mode_attr
-{
- u_int8_t isama_np;
- u_int8_t isama_reserved;
- u_int16_t isama_length;
- u_int8_t isama_type;
- u_int8_t isama_reserved2;
- u_int16_t isama_identifier;
-};
-
-extern struct_desc isakmp_attr_desc;
-extern struct_desc isakmp_modecfg_attribute_desc;
-
-/* ISAKMP Vendor ID Payload
- * layout from RFC 2408 "ISAKMP" section 3.15
- * This is followed by a variable length VID.
- * Previous next payload: ISAKMP_NEXT_VID
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! Next Payload ! RESERVED ! Payload Length !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! !
- * ~ Vendor ID (VID) ~
- * ! !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-extern struct_desc isakmp_vendor_id_desc;
-
-struct isakmp_nat_oa
-{
- u_int8_t isanoa_np;
- u_int8_t isanoa_reserved_1;
- u_int16_t isanoa_length;
- u_int8_t isanoa_idtype;
- u_int8_t isanoa_reserved_2;
- u_int16_t isanoa_reserved_3;
-};
-
-extern struct_desc isakmp_nat_d;
-extern struct_desc isakmp_nat_oa;
-
-/* union of all payloads */
-
-union payload {
- struct isakmp_generic generic;
- struct isakmp_sa sa;
- struct isakmp_proposal proposal;
- struct isakmp_transform transform;
- struct isakmp_id id; /* Main Mode */
- struct isakmp_cert cert;
- struct isakmp_cr cr;
- struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
- struct isakmp_notification notification;
- struct isakmp_delete delete;
- struct isakmp_nat_oa nat_oa;
- struct isakmp_mode_attr attribute;
-};
-
-/* descriptor for each payload type
- *
- * There is a slight problem in that some payloads differ, depending
- * on the mode. Since this is table only used for top-level payloads,
- * Proposal and Transform payloads need not be handled.
- * That leaves only Identification payloads as a problem.
- * We make all these entries NULL
- */
-extern struct_desc *const payload_descs[ISAKMP_NEXT_ROOF];
-
-#endif /* _PACKET_H */
diff --git a/programs/pluto/pem.c b/programs/pluto/pem.c
deleted file mode 100644
index e8d381741..000000000
--- a/programs/pluto/pem.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/* Loading of PEM encoded files with optional encryption
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pem.c,v 1.4 2005/08/17 16:31:24 as Exp $
- */
-
-/* decrypt a PEM encoded data block using DES-EDE3-CBC
- * see RFC 1423 PEM: Algorithms, Modes and Identifiers
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#define HEADER_DES_LOCL_H /* stupid trick to force prototype decl in <des.h> */
-#include <crypto/des.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "md5.h"
-#include "whack.h"
-#include "pem.h"
-
-/*
- * check the presence of a pattern in a character string
- */
-static bool
-present(const char* pattern, chunk_t* ch)
-{
- u_int pattern_len = strlen(pattern);
-
- if (ch->len >= pattern_len && strncmp(ch->ptr, pattern, pattern_len) == 0)
- {
- ch->ptr += pattern_len;
- ch->len -= pattern_len;
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * compare string with chunk
- */
-static bool
-match(const char *pattern, const chunk_t *ch)
-{
- return ch->len == strlen(pattern) &&
- strncmp(pattern, ch->ptr, ch->len) == 0;
-}
-
-/*
- * find a boundary of the form -----tag name-----
- */
-static bool
-find_boundary(const char* tag, chunk_t *line)
-{
- chunk_t name = empty_chunk;
-
- if (!present("-----", line))
- return FALSE;
- if (!present(tag, line))
- return FALSE;
- if (*line->ptr != ' ')
- return FALSE;
- line->ptr++; line->len--;
-
- /* extract name */
- name.ptr = line->ptr;
- while (line->len > 0)
- {
- if (present("-----", line))
- {
- DBG(DBG_PARSING,
- DBG_log(" -----%s %.*s-----",
- tag, (int)name.len, name.ptr);
- )
- return TRUE;
- }
- line->ptr++; line->len--; name.len++;
- }
- return FALSE;
-}
-
-/*
- * eat whitespace
- */
-static void
-eat_whitespace(chunk_t *src)
-{
- while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
- {
- src->ptr++; src->len--;
- }
-}
-
-/*
- * extracts a token ending with a given termination symbol
- */
-static bool
-extract_token(chunk_t *token, char termination, chunk_t *src)
-{
- u_char *eot = memchr(src->ptr, termination, src->len);
-
- /* initialize empty token */
- *token = empty_chunk;
-
- if (eot == NULL) /* termination symbol not found */
- return FALSE;
-
- /* extract token */
- token->ptr = src->ptr;
- token->len = (u_int)(eot - src->ptr);
-
- /* advance src pointer after termination symbol */
- src->ptr = eot + 1;
- src->len -= (token->len + 1);
-
- return TRUE;
-}
-
-/*
- * extracts a name: value pair from the PEM header
- */
-static bool
-extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
-{
- DBG(DBG_PARSING,
- DBG_log(" %.*s", (int)line->len, line->ptr);
- )
-
- /* extract name */
- if (!extract_token(name,':', line))
- return FALSE;
-
- eat_whitespace(line);
-
- /* extract value */
- *value = *line;
- return TRUE;
-}
-
-/*
- * fetches a new line terminated by \n or \r\n
- */
-static bool
-fetchline(chunk_t *src, chunk_t *line)
-{
- if (src->len == 0) /* end of src reached */
- return FALSE;
-
- if (extract_token(line, '\n', src))
- {
- if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
- line->len--; /* remove optional \r */
- }
- else /*last line ends without newline */
- {
- *line = *src;
- src->ptr += src->len;
- src->len = 0;
- }
- return TRUE;
-}
-
-/*
- * decrypts a DES-EDE-CBC encrypted data block
- */
-static bool
-pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
-{
- MD5_CTX context;
- u_char digest[MD5_DIGEST_SIZE];
- u_char des_iv[DES_CBC_BLOCK_SIZE];
- u_char key[24];
- des_cblock *deskey = (des_cblock *)key;
- des_key_schedule ks[3];
- u_char padding, *last_padding_pos, *first_padding_pos;
-
- /* Convert passphrase to 3des key */
- MD5Init(&context);
- MD5Update(&context, passphrase, strlen(passphrase));
- MD5Update(&context, iv->ptr, iv->len);
- MD5Final(digest, &context);
-
- memcpy(key, digest, MD5_DIGEST_SIZE);
-
- MD5Init(&context);
- MD5Update(&context, digest, MD5_DIGEST_SIZE);
- MD5Update(&context, passphrase, strlen(passphrase));
- MD5Update(&context, iv->ptr, iv->len);
- MD5Final(digest, &context);
-
- memcpy(key + MD5_DIGEST_SIZE, digest, 24 - MD5_DIGEST_SIZE);
-
- (void) des_set_key(&deskey[0], ks[0]);
- (void) des_set_key(&deskey[1], ks[1]);
- (void) des_set_key(&deskey[2], ks[2]);
-
- /* decrypt data block */
- memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE);
- des_ede3_cbc_encrypt((des_cblock *)blob->ptr, (des_cblock *)blob->ptr,
- blob->len, ks[0], ks[1], ks[2], (des_cblock *)des_iv, FALSE);
-
- /* determine amount of padding */
- last_padding_pos = blob->ptr + blob->len - 1;
- padding = *last_padding_pos;
- first_padding_pos = (padding > blob->len)?
- blob->ptr : last_padding_pos - padding;
-
- /* check the padding pattern */
- while (--last_padding_pos > first_padding_pos)
- {
- if (*last_padding_pos != padding)
- return FALSE;
- }
-
- /* remove padding */
- blob->len -= padding;
- return TRUE;
-}
-
-/*
- * optionally prompts for a passphrase before decryption
- * currently we support DES-EDE3-CBC, only
- */
-static err_t
-pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
-{
- DBG(DBG_CRYPT,
- DBG_log(" decrypting file using 'DES-EDE3-CBC'");
- )
- if (iv->len != DES_CBC_BLOCK_SIZE)
- return "size of DES-EDE3-CBC IV is not 8 bytes";
-
- if (pass == NULL)
- return "no passphrase available";
-
- /* do we prompt for the passphrase? */
- if (pass->prompt && pass->fd != NULL_FD)
- {
- int i;
- chunk_t blob_copy;
- err_t ugh = "invalid passphrase, too many trials";
-
- whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
-
- for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
- {
- int n;
-
- if (i > 0)
- whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
-
- n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
-
- if (n == -1)
- {
- err_t ugh = "read(whackfd) failed";
-
- whack_log(RC_LOG_SERIOUS,ugh);
- return ugh;
- }
-
- pass->secret[n-1] = '\0';
-
- if (strlen(pass->secret) == 0)
- {
- err_t ugh = "no passphrase entered, aborted";
-
- whack_log(RC_LOG_SERIOUS, ugh);
- return ugh;
- }
-
- clonetochunk(blob_copy, blob->ptr, blob->len, "blob copy");
-
- if (pem_decrypt_3des(blob, iv, pass->secret))
- {
- whack_log(RC_SUCCESS, "valid passphrase");
- pfree(blob_copy.ptr);
- return NULL;
- }
-
- /* blob is useless after wrong decryption, restore the original */
- pfree(blob->ptr);
- *blob = blob_copy;
- }
- whack_log(RC_LOG_SERIOUS, ugh);
- return ugh;
- }
- else
- {
- if (pem_decrypt_3des(blob, iv, pass->secret))
- return NULL;
- else
- return "invalid passphrase";
- }
-}
-
-/* Converts a PEM encoded file into its binary form
- *
- * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
- * RFC 934 Message Encapsulation, January 1985
- */
-err_t
-pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
-{
- typedef enum {
- PEM_PRE = 0,
- PEM_MSG = 1,
- PEM_HEADER = 2,
- PEM_BODY = 3,
- PEM_POST = 4,
- PEM_ABORT = 5
- } state_t;
-
- bool encrypted = FALSE;
-
- state_t state = PEM_PRE;
-
- chunk_t src = *blob;
- chunk_t dst = *blob;
- chunk_t line = empty_chunk;
- chunk_t iv = empty_chunk;
-
- u_char iv_buf[MAX_DIGEST_LEN];
-
- /* zero size of converted blob */
- dst.len = 0;
-
- /* zero size of IV */
- iv.ptr = iv_buf;
- iv.len = 0;
-
- while (fetchline(&src, &line))
- {
- if (state == PEM_PRE)
- {
- if (find_boundary("BEGIN", &line))
- {
- *pgp = FALSE;
- state = PEM_MSG;
- }
- continue;
- }
- else
- {
- if (find_boundary("END", &line))
- {
- state = PEM_POST;
- break;
- }
- if (state == PEM_MSG)
- {
- state = (memchr(line.ptr, ':', line.len) == NULL)?
- PEM_BODY : PEM_HEADER;
- }
- if (state == PEM_HEADER)
- {
- chunk_t name = empty_chunk;
- chunk_t value = empty_chunk;
-
- /* an empty line separates HEADER and BODY */
- if (line.len == 0)
- {
- state = PEM_BODY;
- continue;
- }
-
- /* we are looking for a name: value pair */
- if (!extract_parameter(&name, &value, &line))
- continue;
-
- if (match("Proc-Type", &name) && *value.ptr == '4')
- encrypted = TRUE;
- else if (match("DEK-Info", &name))
- {
- const char *ugh = NULL;
- size_t len = 0;
- chunk_t dek;
-
- if (!extract_token(&dek, ',', &value))
- dek = value;
-
- /* we support DES-EDE3-CBC encrypted files, only */
- if (!match("DES-EDE3-CBC", &dek))
- return "we support DES-EDE3-CBC encrypted files, only";
-
- eat_whitespace(&value);
- ugh = ttodata(value.ptr, value.len, 16,
- iv.ptr, MAX_DIGEST_LEN, &len);
- if (ugh)
- return "error in IV";
-
- iv.len = len;
- }
- }
- else /* state is PEM_BODY */
- {
- const char *ugh = NULL;
- size_t len = 0;
- chunk_t data;
-
- /* remove any trailing whitespace */
- if (!extract_token(&data ,' ', &line))
- data = line;
-
- /* check for PGP armor checksum */
- if (*data.ptr == '=')
- {
- *pgp = TRUE;
- data.ptr++;
- data.len--;
- DBG(DBG_PARSING,
- DBG_log(" Armor checksum: %.*s", (int)data.len, data.ptr);
- )
- continue;
- }
-
- ugh = ttodata(data.ptr, data.len, 64,
- dst.ptr, blob->len - dst.len, &len);
- if (ugh)
- {
- DBG(DBG_PARSING,
- DBG_log(" %s", ugh);
- )
- state = PEM_ABORT;
- break;
- }
- else
- {
- dst.ptr += len;
- dst.len += len;
- }
- }
- }
- }
- /* set length to size of binary blob */
- blob->len = dst.len;
-
- if (state != PEM_POST)
- return "file coded in unknown format, discarded";
-
- if (encrypted)
- return pem_decrypt(blob, &iv, pass, label);
- else
- return NULL;
-}
diff --git a/programs/pluto/pem.h b/programs/pluto/pem.h
deleted file mode 100644
index 815b5d85b..000000000
--- a/programs/pluto/pem.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Loading of PEM encoded files with optional encryption
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pem.h,v 1.1 2004/03/15 20:35:28 as Exp $
- */
-
-extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label
- , bool *pgp);
diff --git a/programs/pluto/pgp.c b/programs/pluto/pgp.c
deleted file mode 100644
index 015319aaf..000000000
--- a/programs/pluto/pgp.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/* Support of OpenPGP certificates
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pgp.c,v 1.7 2006/01/04 21:00:43 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-#include "id.h"
-#include "pgp.h"
-#include "certs.h"
-#include "md5.h"
-#include "whack.h"
-#include "pkcs1.h"
-#include "keys.h"
-
-/*
- * chained list of OpenPGP end certificates
- */
-static pgpcert_t *pgpcerts = NULL;
-
-/*
- * OpenPGP packet tags defined in section 4.3 of RFC 2440
- */
-#define PGP_PKT_RESERVED 0
-#define PGP_PKT_PUBKEY_ENC_SESSION_KEY 1
-#define PGP_PKT_SIGNATURE 2
-#define PGP_PKT_SYMKEY_ENC_SESSION_KEY 3
-#define PGP_PKT_ONE_PASS_SIGNATURE_PKT 4
-#define PGP_PKT_SECRET_KEY 5
-#define PGP_PKT_PUBLIC_KEY 6
-#define PGP_PKT_SECRET_SUBKEY 7
-#define PGP_PKT_COMPRESSED_DATA 8
-#define PGP_PKT_SYMKEY_ENC_DATA 9
-#define PGP_PKT_MARKER 10
-#define PGP_PKT_LITERAL_DATA 11
-#define PGP_PKT_TRUST 12
-#define PGP_PKT_USER_ID 13
-#define PGP_PKT_PUBLIC_SUBKEY 14
-#define PGP_PKT_ROOF 15
-
-static const char *const pgp_packet_type_name[] = {
- "Reserved",
- "Public-Key Encrypted Session Key Packet",
- "Signature Packet",
- "Symmetric-Key Encrypted Session Key Packet",
- "One-Pass Signature Packet",
- "Secret Key Packet",
- "Public Key Packet",
- "Secret Subkey Packet",
- "Compressed Data Packet",
- "Symmetrically Encrypted Data Packet",
- "Marker Packet",
- "Literal Data Packet",
- "Trust Packet",
- "User ID Packet",
- "Public Subkey Packet"
-};
-
-/*
- * OpenPGP public key algorithms defined in section 9.1 of RFC 2440
- */
-#define PGP_PUBKEY_ALG_RSA 1
-#define PGP_PUBKEY_ALG_RSA_ENC_ONLY 2
-#define PGP_PUBKEY_ALG_RSA_SIGN_ONLY 3
-#define PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY 16
-#define PGP_PUBKEY_ALG_DSA 17
-#define PGP_PUBKEY_ALG_ECC 18
-#define PGP_PUBKEY_ALG_ECDSA 19
-#define PGP_PUBKEY_ALG_ELGAMAL 20
-
-/*
- * OpenPGP symmetric key algorithms defined in section 9.2 of RFC 2440
- */
-#define PGP_SYM_ALG_PLAIN 0
-#define PGP_SYM_ALG_IDEA 1
-#define PGP_SYM_ALG_3DES 2
-#define PGP_SYM_ALG_CAST5 3
-#define PGP_SYM_ALG_BLOWFISH 4
-#define PGP_SYM_ALG_SAFER 5
-#define PGP_SYM_ALG_DES 6
-#define PGP_SYM_ALG_AES 7
-#define PGP_SYM_ALG_AES_192 8
-#define PGP_SYM_ALG_AES_256 9
-#define PGP_SYM_ALG_TWOFISH 10
-#define PGP_SYM_ALG_ROOF 11
-
-static const char *const pgp_sym_alg_name[] = {
- "Plaintext",
- "IDEA",
- "3DES",
- "CAST5",
- "Blowfish",
- "SAFER",
- "DES",
- "AES",
- "AES-192",
- "AES-256",
- "Twofish"
-};
-
-/*
- * Size of PGP Key ID
- */
-#define PGP_KEYID_SIZE 8
-
-const pgpcert_t empty_pgpcert = {
- NULL , /* *next */
- 0 , /* installed */
- 0 , /* count */
- { NULL, 0 }, /* certificate */
- 0 , /* created */
- 0 , /* until */
- 0 , /* pubkeyAlgorithm */
- { NULL, 0 }, /* modulus */
- { NULL, 0 }, /* publicExponent */
- "" /* fingerprint */
-};
-
-static size_t
-pgp_size(chunk_t *blob, int len)
-{
- size_t size = 0;
-
- blob->len -= len;
- while (len-- > 0)
- size = 256*size + *blob->ptr++;
- return size;
-}
-
-/*
- * extracts the length of a PGP packet
- */
-static size_t
-pgp_old_packet_length(chunk_t *blob)
-{
- /* bits 0 and 1 define the packet length type */
- int len_type = 0x03 & *blob->ptr++;
-
- blob->len--;
-
- /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
- return pgp_size(blob, (len_type == 0)? 1: len_type << 1);
-}
-
-/*
- * extracts PGP packet version (V3 or V4)
- */
-static u_char
-pgp_version(chunk_t *blob)
-{
- u_char version = *blob->ptr++;
- blob->len--;
- DBG(DBG_PARSING,
- DBG_log("L3 - version:");
- DBG_log(" V%d", version)
- )
- return version;
-}
-
-/*
- * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440
- */
-static bool
-parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
-{
- u_char version = pgp_version(packet);
-
- if (version < 3 || version > 4)
- {
- plog("PGP packet version V%d not supported", version);
- return FALSE;
- }
-
- /* creation date - 4 bytes */
- cert->created = (time_t)pgp_size(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %s", timetoa(&cert->created, TRUE))
- )
-
- if (version == 3)
- {
- /* validity in days - 2 bytes */
- cert->until = (time_t)pgp_size(packet, 2);
-
- /* validity of 0 days means that the key never expires */
- if (cert->until > 0)
- cert->until = cert->created + 24*3600*cert->until;
-
- DBG(DBG_PARSING,
- DBG_log("L3 - until:");
- DBG_log(" %s", timetoa(&cert->until, TRUE));
- )
- }
-
- /* public key algorithm - 1 byte */
- DBG(DBG_PARSING,
- DBG_log("L3 - public key algorithm:")
- )
-
- switch (pgp_size(packet, 1))
- {
- case PGP_PUBKEY_ALG_RSA:
- case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
- cert->pubkeyAlg = PUBKEY_ALG_RSA;
- DBG(DBG_PARSING,
- DBG_log(" RSA")
- )
- /* modulus n */
- cert->modulus.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
- cert->modulus.ptr = packet->ptr;
- packet->ptr += cert->modulus.len;
- packet->len -= cert->modulus.len;
- DBG(DBG_PARSING,
- DBG_log("L3 - modulus:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", cert->modulus);
-
- /* public exponent e */
- cert->publicExponent.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
- cert->publicExponent.ptr = packet->ptr;
- packet->ptr += cert->publicExponent.len;
- packet->len -= cert->publicExponent.len;
- DBG(DBG_PARSING,
- DBG_log("L3 - public exponent:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", cert->publicExponent);
-
- if (version == 3)
- {
- /* a V3 fingerprint is the MD5 hash of modulus and public exponent */
- MD5_CTX context;
- MD5Init(&context);
- MD5Update(&context, cert->modulus.ptr, cert->modulus.len);
- MD5Update(&context, cert->publicExponent.ptr, cert->publicExponent.len);
- MD5Final(cert->fingerprint, &context);
- }
- else
- {
- plog(" computation of V4 key ID not implemented yet");
- }
- break;
- case PGP_PUBKEY_ALG_DSA:
- cert->pubkeyAlg = PUBKEY_ALG_DSA;
- DBG(DBG_PARSING,
- DBG_log(" DSA")
- )
- plog(" DSA public keys not supported");
- return FALSE;
- default:
- cert->pubkeyAlg = 0;
- DBG(DBG_PARSING,
- DBG_log(" other")
- )
- plog(" exotic not RSA public keys not supported");
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 2440
- */
-static bool
-parse_pgp_secretkey_packet(chunk_t *packet, RSA_private_key_t *key)
-{
- int i, s2k;
- pgpcert_t cert = empty_pgpcert;
-
- if (!parse_pgp_pubkey_packet(packet, &cert))
- return FALSE;
-
- init_RSA_public_key((RSA_public_key_t *)key, cert.publicExponent
- , cert.modulus);
-
- /* string-to-key usage */
- s2k = pgp_size(packet, 1);
-
- DBG(DBG_PARSING,
- DBG_log("L3 - string-to-key: %d", s2k)
- )
-
- if (s2k == 255)
- {
- plog(" string-to-key specifiers not supported");
- return FALSE;
- }
-
- if (s2k >= PGP_SYM_ALG_ROOF)
- {
- plog(" undefined symmetric key algorithm");
- return FALSE;
- }
-
- /* a known symmetric key algorithm is specified*/
- DBG(DBG_PARSING,
- DBG_log(" %s", pgp_sym_alg_name[s2k])
- )
-
- /* private key is unencrypted */
- if (s2k == PGP_SYM_ALG_PLAIN)
- {
- for (i = 2; i < RSA_PRIVATE_FIELD_ELEMENTS; i++)
- {
- mpz_t u; /* auxiliary variable */
-
- /* compute offset to private key component i*/
- MP_INT *n = (MP_INT*)((char *)key + RSA_private_field[i].offset);
-
- switch (i)
- {
- case 2:
- case 3:
- case 4:
- {
- size_t len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
-
- n_to_mpz(n, packet->ptr, len);
- DBG(DBG_PARSING,
- DBG_log("L3 - %s:", RSA_private_field[i].name)
- )
- DBG_cond_dump(DBG_PRIVATE, "", packet->ptr, len);
- packet->ptr += len;
- packet->len -= len;
- }
- break;
- case 5: /* dP = d mod (p-1) */
- mpz_init(u);
- mpz_sub_ui(u, &key->p, 1);
- mpz_mod(n, &key->d, u);
- mpz_clear(u);
- break;
- case 6: /* dQ = d mod (q-1) */
- mpz_init(u);
- mpz_sub_ui(u, &key->q, 1);
- mpz_mod(n, &key->d, u);
- mpz_clear(u);
- break;
- case 7: /* qInv = (q^-1) mod p */
- mpz_invert(n, &key->q, &key->p);
- if (mpz_cmp_ui(n, 0) < 0)
- mpz_add(n, n, &key->p);
- passert(mpz_cmp(n, &key->p) < 0);
- break;
- }
- }
- return TRUE;
- }
-
- plog(" %s encryption not supported", pgp_sym_alg_name[s2k]);
- return FALSE;
-}
-
-/*
- * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
- */
-static bool
-parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
-{
- time_t created;
- chunk_t keyid;
- u_char sig_type;
- u_char version = pgp_version(packet);
-
- /* we parse only V3 signature packets */
- if (version != 3)
- return TRUE;
-
- /* size byte must have the value 5 */
- if (pgp_size(packet, 1) != 5)
- {
- plog(" size must be 5");
- return FALSE;
- }
-
- /* signature type - 1 byte */
- sig_type = (u_char)pgp_size(packet, 1);
- DBG(DBG_PARSING,
- DBG_log("L3 - signature type: 0x%2x", sig_type)
- )
-
- /* creation date - 4 bytes */
- created = (time_t)pgp_size(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %s", timetoa(&cert->created, TRUE))
- )
-
- /* key ID of signer - 8 bytes */
- keyid.ptr = packet->ptr;
- keyid.len = PGP_KEYID_SIZE;
- DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
-
- return TRUE;
-}
-
-bool
-parse_pgp(chunk_t blob, pgpcert_t *cert, RSA_private_key_t *key)
-{
- DBG(DBG_PARSING,
- DBG_log("L0 - PGP file:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", blob);
-
- if (cert != NULL)
- {
- /* parse a PGP certificate file */
- cert->certificate = blob;
- time(&cert->installed);
- }
- else if (key == NULL)
- {
- /* should not occur, nothing to parse */
- return FALSE;
- }
-
- while (blob.len > 0)
- {
- chunk_t packet = empty_chunk;
- u_char packet_tag = *blob.ptr;
-
- DBG(DBG_PARSING,
- DBG_log("L1 - PGP packet: tag= 0x%2x", packet_tag)
- )
-
- /* bit 7 must be set */
- if (!(packet_tag & 0x80))
- {
- plog(" incorrect Packet Tag");
- return FALSE;
- }
-
- /* bit 6 set defines new packet format */
- if (packet_tag & 0x40)
- {
- plog(" new PGP packet format not supported");
- return FALSE;
- }
- else
- {
- int packet_type = (packet_tag & 0x3C) >> 2;
-
- packet.len = pgp_old_packet_length(&blob);
- packet.ptr = blob.ptr;
- blob.ptr += packet.len;
- blob.len -= packet.len;
- DBG(DBG_PARSING,
- DBG_log(" %s (%d), old format, %d bytes",
- (packet_type < PGP_PKT_ROOF) ?
- pgp_packet_type_name[packet_type] :
- "Undefined Packet Type", packet_type, (int)packet.len);
- DBG_log("L2 - body:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", packet);
-
- if (cert != NULL)
- {
- /* parse a PGP certificate */
- switch (packet_type)
- {
- case PGP_PKT_PUBLIC_KEY:
- if (!parse_pgp_pubkey_packet(&packet, cert))
- return FALSE;
- break;
- case PGP_PKT_SIGNATURE:
- if (!parse_pgp_signature_packet(&packet, cert))
- return FALSE;
- break;
- case PGP_PKT_USER_ID:
- DBG(DBG_PARSING,
- DBG_log("L3 - user ID:");
- DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
- )
- break;
- default:
- break;
- }
- }
- else
- {
- /* parse a PGP private key file */
- switch (packet_type)
- {
- case PGP_PKT_SECRET_KEY:
- if (!parse_pgp_secretkey_packet(&packet, key))
- return FALSE;
- break;
- default:
- break;
- }
- }
- }
- }
- return TRUE;
-}
-
-/*
- * compare two OpenPGP certificates
- */
-static bool
-same_pgpcert(pgpcert_t *a, pgpcert_t *b)
-{
- return a->certificate.len == b->certificate.len &&
- memcmp(a->certificate.ptr, b->certificate.ptr, b->certificate.len) == 0;
-}
-
-/*
- * for each link pointing to the certificate increase the count by one
- */
-void
-share_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- cert->count++;
-}
-
-/*
- * select the OpenPGP keyid as ID
- */
-void
-select_pgpcert_id(pgpcert_t *cert, struct id *end_id)
-{
- end_id->kind = ID_KEY_ID;
- end_id->name.len = PGP_FINGERPRINT_SIZE;
- end_id->name.ptr = cert->fingerprint;
- end_id->name.ptr = temporary_cyclic_buffer();
- memcpy(end_id->name.ptr, cert->fingerprint, PGP_FINGERPRINT_SIZE);
-}
-
-/*
- * add an OpenPGP user/host certificate to the chained list
- */
-pgpcert_t*
-add_pgpcert(pgpcert_t *cert)
-{
- pgpcert_t *c = pgpcerts;
-
- while (c != NULL)
- {
- if (same_pgpcert(c, cert)) /* already in chain, free cert */
- {
- free_pgpcert(cert);
- return c;
- }
- c = c->next;
- }
-
- /* insert new cert at the root of the chain */
- cert->next = pgpcerts;
- pgpcerts = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" pgp cert inserted")
- )
- return cert;
-}
-
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
- */
-void
-release_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL && --cert->count == 0)
- {
- pgpcert_t **pp = &pgpcerts;
- while (*pp != cert)
- pp = &(*pp)->next;
- *pp = cert->next;
- free_pgpcert(cert);
- }
-}
-
-/*
- * free a PGP certificate
- */
-void
-free_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- {
- if (cert->certificate.ptr != NULL)
- pfree(cert->certificate.ptr);
- pfree(cert);
- }
-}
-
-/*
- * list all PGP end certificates in a chained list
- */
-void
-list_pgp_end_certs(bool utc)
-{
- pgpcert_t *cert = pgpcerts;
- time_t now;
-
- /* determine the current time */
- time(&now);
-
- if (cert != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of PGP End certificates:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (cert != NULL)
- {
- unsigned keysize;
- char buf[BUF_LEN];
- cert_t c;
-
- c.type = CERT_PGP;
- c.u.pgp = cert;
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc), cert->count);
- datatot(cert->fingerprint, PGP_FINGERPRINT_SIZE, 'x', buf, BUF_LEN);
- whack_log(RC_COMMENT, " fingerprint: %s", buf);
- form_keyid(cert->publicExponent, cert->modulus, buf, &keysize);
- whack_log(RC_COMMENT, " pubkey: %4d RSA Key %s%s", 8*keysize, buf,
- (has_private_key(c))? ", has private key" : "");
- whack_log(RC_COMMENT, " created: %s", timetoa(&cert->created, utc));
- whack_log(RC_COMMENT, " until: %s %s", timetoa(&cert->until, utc),
- check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
- cert = cert->next;
- }
-}
-
diff --git a/programs/pluto/pgp.h b/programs/pluto/pgp.h
deleted file mode 100644
index 4f34debc9..000000000
--- a/programs/pluto/pgp.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Support of OpenPGP certificates
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pgp.h,v 1.3 2005/08/07 07:50:09 as Exp $
- */
-
-#ifndef _PGP_H
-#define _PGP_H
-
-#include "pkcs1.h"
-/*
- * Length of PGP V3 fingerprint
- */
-#define PGP_FINGERPRINT_SIZE MD5_DIGEST_SIZE
-
-typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
-
-/* access structure for an OpenPGP certificate */
-
-typedef struct pgpcert pgpcert_t;
-
-struct pgpcert {
- pgpcert_t *next;
- time_t installed;
- int count;
- chunk_t certificate;
- time_t created;
- time_t until;
- enum pubkey_alg pubkeyAlg;
- chunk_t modulus;
- chunk_t publicExponent;
- fingerprint_t fingerprint;
-};
-
-extern const pgpcert_t empty_pgpcert;
-extern bool parse_pgp(chunk_t blob, pgpcert_t *cert, RSA_private_key_t *key);
-extern void share_pgpcert(pgpcert_t *cert);
-extern void select_pgpcert_id(pgpcert_t *cert, struct id *end_id);
-extern pgpcert_t* add_pgpcert(pgpcert_t *cert);
-extern void list_pgp_end_certs(bool utc);
-extern void release_pgpcert(pgpcert_t *cert);
-extern void free_pgpcert(pgpcert_t *cert);
-
-#endif /* _PGP_H */
diff --git a/programs/pluto/pkcs1.c b/programs/pluto/pkcs1.c
deleted file mode 100644
index b3c0face9..000000000
--- a/programs/pluto/pkcs1.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/* Support of PKCS#1 private key data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs1.c,v 1.18 2007/02/21 14:21:05 as Exp $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-#include <libsha2/sha2.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "asn1.h"
-#include "oid.h"
-#include "log.h"
-#include "pkcs1.h"
-#include "md2.h"
-#include "md5.h"
-#include "sha1.h"
-#include "rnd.h"
-
-const struct fld RSA_private_field[] =
-{
- { "Modulus", offsetof(RSA_private_key_t, pub.n) },
- { "PublicExponent", offsetof(RSA_private_key_t, pub.e) },
-
- { "PrivateExponent", offsetof(RSA_private_key_t, d) },
- { "Prime1", offsetof(RSA_private_key_t, p) },
- { "Prime2", offsetof(RSA_private_key_t, q) },
- { "Exponent1", offsetof(RSA_private_key_t, dP) },
- { "Exponent2", offsetof(RSA_private_key_t, dQ) },
- { "Coefficient", offsetof(RSA_private_key_t, qInv) },
-};
-
-/* ASN.1 definition of a PKCS#1 RSA private key */
-
-static const asn1Object_t privkeyObjects[] = {
- { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
- { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
- { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 10 */
- { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
- { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
- { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
-};
-
-#define PKCS1_PRIV_KEY_VERSION 1
-#define PKCS1_PRIV_KEY_MODULUS 2
-#define PKCS1_PRIV_KEY_PUB_EXP 3
-#define PKCS1_PRIV_KEY_COEFF 9
-#define PKCS1_PRIV_KEY_ROOF 16
-
-
-/*
- * forms the FreeS/WAN keyid from the public exponent e and modulus n
- */
-void
-form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize)
-{
- /* eliminate leading zero bytes in modulus from ASN.1 coding */
- while (n.len > 1 && *n.ptr == 0x00)
- {
- n.ptr++; n.len--;
- }
-
- /* form the FreeS/WAN keyid */
- keyid[0] = '\0'; /* in case of splitkeytoid failure */
- splitkeytoid(e.ptr, e.len, n.ptr, n.len, keyid, KEYID_BUF);
-
- /* return the RSA modulus size in octets */
- *keysize = n.len;
-}
-
-/*
- * initialize an RSA_public_key_t object
- */
-void
-init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n)
-{
- n_to_mpz(&rsa->e, e.ptr, e.len);
- n_to_mpz(&rsa->n, n.ptr, n.len);
-
- form_keyid(e, n, rsa->keyid, &rsa->k);
-}
-
-#ifdef DEBUG
-static void
-RSA_show_key_fields(RSA_private_key_t *k, int fieldcnt)
-{
- const struct fld *p;
-
- DBG_log(" keyid: *%s", k->pub.keyid);
-
- for (p = RSA_private_field; p < &RSA_private_field[fieldcnt]; p++)
- {
- MP_INT *n = (MP_INT *) ((char *)k + p->offset);
- size_t sz = mpz_sizeinbase(n, 16);
- char buf[RSA_MAX_OCTETS * 2 + 2]; /* ought to be big enough */
-
- passert(sz <= sizeof(buf));
- mpz_get_str(buf, 16, n);
-
- DBG_log(" %s: 0x%s", p->name, buf);
- }
-}
-
-/* debugging info that compromises security! */
-void
-RSA_show_private_key(RSA_private_key_t *k)
-{
- RSA_show_key_fields(k, elemsof(RSA_private_field));
-}
-
-void
-RSA_show_public_key(RSA_public_key_t *k)
-{
- /* Kludge: pretend that it is a private key, but only display the
- * first two fields (which are the public key).
- */
- passert(offsetof(RSA_private_key_t, pub) == 0);
- RSA_show_key_fields((RSA_private_key_t *)k, 2);
-}
-#endif
-
-err_t
-RSA_private_key_sanity(RSA_private_key_t *k)
-{
- /* note that the *last* error found is reported */
- err_t ugh = NULL;
- mpz_t t, u, q1;
-
-#ifdef DEBUG /* debugging info that compromises security */
- DBG(DBG_PRIVATE, RSA_show_private_key(k));
-#endif
-
- /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
- * We actually require more (for security).
- */
- if (k->pub.k < RSA_MIN_OCTETS)
- return RSA_MIN_OCTETS_UGH;
-
- /* we picked a max modulus size to simplify buffer allocation */
- if (k->pub.k > RSA_MAX_OCTETS)
- return RSA_MAX_OCTETS_UGH;
-
- mpz_init(t);
- mpz_init(u);
- mpz_init(q1);
-
- /* check that n == p * q */
- mpz_mul(u, &k->p, &k->q);
- if (mpz_cmp(u, &k->pub.n) != 0)
- ugh = "n != p * q";
-
- /* check that e divides neither p-1 nor q-1 */
- mpz_sub_ui(t, &k->p, 1);
- mpz_mod(t, t, &k->pub.e);
- if (mpz_cmp_ui(t, 0) == 0)
- ugh = "e divides p-1";
-
- mpz_sub_ui(t, &k->q, 1);
- mpz_mod(t, t, &k->pub.e);
- if (mpz_cmp_ui(t, 0) == 0)
- ugh = "e divides q-1";
-
- /* check that d is e^-1 (mod lcm(p-1, q-1)) */
- /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
- mpz_sub_ui(q1, &k->q, 1);
- mpz_sub_ui(u, &k->p, 1);
- mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
- mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
- mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
-
- mpz_mul(t, &k->d, &k->pub.e);
- mpz_mod(t, t, u);
- if (mpz_cmp_ui(t, 1) != 0)
- ugh = "(d * e) mod (lcm(p-1, q-1)) != 1";
-
- /* check that dP is d mod (p-1) */
- mpz_sub_ui(u, &k->p, 1);
- mpz_mod(t, &k->d, u);
- if (mpz_cmp(t, &k->dP) != 0)
- ugh = "dP is not congruent to d mod (p-1)";
-
- /* check that dQ is d mod (q-1) */
- mpz_sub_ui(u, &k->q, 1);
- mpz_mod(t, &k->d, u);
- if (mpz_cmp(t, &k->dQ) != 0)
- ugh = "dQ is not congruent to d mod (q-1)";
-
- /* check that qInv is (q^-1) mod p */
- mpz_mul(t, &k->qInv, &k->q);
- mpz_mod(t, t, &k->p);
- if (mpz_cmp_ui(t, 1) != 0)
- ugh = "qInv is not conguent ot (q^-1) mod p";
-
- mpz_clear(t);
- mpz_clear(u);
- mpz_clear(q1);
- return ugh;
-}
-
-/*
- * Check the equality of two RSA public keys
- */
-bool
-same_RSA_public_key(const RSA_public_key_t *a, const RSA_public_key_t *b)
-{
- return a == b
- || (a->k == b->k && mpz_cmp(&a->n, &b->n) == 0 && mpz_cmp(&a->e, &b->e) == 0);
-}
-
-/*
- * Parses a PKCS#1 private key
- */
-bool
-pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key)
-{
- err_t ugh = NULL;
- asn1_ctx_t ctx;
- chunk_t object, modulus, exp;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_PRIVATE);
-
- while (objectID < PKCS1_PRIV_KEY_ROOF) {
-
- if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- if (objectID == PKCS1_PRIV_KEY_VERSION)
- {
- if (object.len > 0 && *object.ptr != 0)
- {
- plog(" wrong PKCS#1 private key version");
- return FALSE;
- }
- }
- else if (objectID >= PKCS1_PRIV_KEY_MODULUS &&
- objectID <= PKCS1_PRIV_KEY_COEFF)
- {
- MP_INT *u = (MP_INT *) ((char *)key
- + RSA_private_field[objectID - PKCS1_PRIV_KEY_MODULUS].offset);
-
- n_to_mpz(u, object.ptr, object.len);
-
- if (objectID == PKCS1_PRIV_KEY_MODULUS)
- modulus = object;
- else if (objectID == PKCS1_PRIV_KEY_PUB_EXP)
- exp = object;
- }
- objectID++;
- }
- form_keyid(exp, modulus, key->pub.keyid, &key->pub.k);
- ugh = RSA_private_key_sanity(key);
- return (ugh == NULL);
-}
-
-/*
- * compute a digest over a binary blob
- */
-bool
-compute_digest(chunk_t tbs, int alg, chunk_t *digest)
-{
- switch (alg)
- {
- case OID_MD2:
- case OID_MD2_WITH_RSA:
- {
- MD2_CTX context;
-
- MD2Init(&context);
- MD2Update(&context, tbs.ptr, tbs.len);
- MD2Final(digest->ptr, &context);
- digest->len = MD2_DIGEST_SIZE;
- return TRUE;
- }
- case OID_MD5:
- case OID_MD5_WITH_RSA:
- {
- MD5_CTX context;
-
- MD5Init(&context);
- MD5Update(&context, tbs.ptr, tbs.len);
- MD5Final(digest->ptr, &context);
- digest->len = MD5_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA1:
- case OID_SHA1_WITH_RSA:
- case OID_SHA1_WITH_RSA_OIW:
- {
- SHA1_CTX context;
-
- SHA1Init(&context);
- SHA1Update(&context, tbs.ptr, tbs.len);
- SHA1Final(digest->ptr, &context);
- digest->len = SHA1_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA256:
- case OID_SHA256_WITH_RSA:
- {
- sha256_context context;
-
- sha256_init(&context);
- sha256_write(&context, tbs.ptr, tbs.len);
- sha256_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_256_DIGEST_SIZE);
- digest->len = SHA2_256_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA384:
- case OID_SHA384_WITH_RSA:
- {
- sha512_context context;
-
- sha384_init(&context);
- sha512_write(&context, tbs.ptr, tbs.len);
- sha512_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_384_DIGEST_SIZE);
- digest->len = SHA2_384_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA512:
- case OID_SHA512_WITH_RSA:
- {
- sha512_context context;
-
- sha512_init(&context);
- sha512_write(&context, tbs.ptr, tbs.len);
- sha512_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_512_DIGEST_SIZE);
- digest->len = SHA2_512_DIGEST_SIZE;
- return TRUE;
- }
- default:
- digest->len = 0;
- return FALSE;
- }
-}
-
-/*
- * compute an RSA signature with PKCS#1 padding
- */
-void
-sign_hash(const RSA_private_key_t *k, const u_char *hash_val, size_t hash_len
- , u_char *sig_val, size_t sig_len)
-{
- chunk_t ch;
- mpz_t t1, t2;
- size_t padlen;
- u_char *p = sig_val;
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA Key *%s", k->pub.keyid)
- )
- /* PKCS#1 v1.5 8.1 encryption-block formatting */
- *p++ = 0x00;
- *p++ = 0x01; /* BT (block type) 01 */
- padlen = sig_len - 3 - hash_len;
- memset(p, 0xFF, padlen);
- p += padlen;
- *p++ = 0x00;
- memcpy(p, hash_val, hash_len);
- passert(p + hash_len - sig_val == (ptrdiff_t)sig_len);
-
- /* PKCS#1 v1.5 8.2 octet-string-to-integer conversion */
- n_to_mpz(t1, sig_val, sig_len); /* (could skip leading 0x00) */
-
- /* PKCS#1 v1.5 8.3 RSA computation y = x^c mod n
- * Better described in PKCS#1 v2.0 5.1 RSADP.
- * There are two methods, depending on the form of the private key.
- * We use the one based on the Chinese Remainder Theorem.
- */
- mpz_init(t2);
-
- mpz_powm(t2, t1, &k->dP, &k->p); /* m1 = c^dP mod p */
-
- mpz_powm(t1, t1, &k->dQ, &k->q); /* m2 = c^dQ mod Q */
-
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, &k->p);
- mpz_mul(t2, t2, &k->qInv);
- mpz_mod(t2, t2, &k->p);
-
- mpz_mul(t2, t2, &k->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- /* PKCS#1 v1.5 8.4 integer-to-octet-string conversion */
- ch = mpz_to_n(t1, sig_len);
- memcpy(sig_val, ch.ptr, sig_len);
- pfree(ch.ptr);
-
- mpz_clear(t1);
- mpz_clear(t2);
-}
-
-/*
- * encrypt data with an RSA public key after padding
- */
-chunk_t
-RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
-{
- u_char padded[RSA_MAX_OCTETS];
- u_char *pos = padded;
- int padding = key->k - in.len - 3;
- int i;
-
- if (padding < 8 || key->k > RSA_MAX_OCTETS)
- return empty_chunk;
-
- /* add padding according to PKCS#1 7.2.1 1.+2. */
- *pos++ = 0x00;
- *pos++ = 0x02;
-
- /* pad with pseudo random bytes unequal to zero */
- get_rnd_bytes(pos, padding);
- for (i = 0; i < padding; i++)
- {
- while (!*pos)
- get_rnd_bytes(pos, 1);
- pos++;
- }
-
- /* append the padding terminator */
- *pos++ = 0x00;
-
- /* now add the data */
- memcpy(pos, in.ptr, in.len);
- DBG(DBG_RAW,
- DBG_dump_chunk("data for rsa encryption:\n", in);
- DBG_dump("padded data for rsa encryption:\n", padded, key->k)
- )
-
- /* convert chunk to integer (PKCS#1 7.2.1 3.a) */
- {
- chunk_t out;
- mpz_t m, c;
-
- mpz_init(c);
- n_to_mpz(m, padded, key->k);
-
- /* encrypt(PKCS#1 7.2.1 3.b) */
- mpz_powm(c, m, &key->e, &key->n);
-
- /* convert integer back to a chunk (PKCS#1 7.2.1 3.c) */
- out = mpz_to_n(c, key->k);
- mpz_clear(c);
- mpz_clear(m);
-
- DBG(DBG_RAW,
- DBG_dump_chunk("rsa encrypted data:\n", out)
- )
- return out;
- }
-}
-
-/*
- * decrypt data with an RSA private key and remove padding
- */
-bool
-RSA_decrypt(const RSA_private_key_t *key, chunk_t in, chunk_t *out)
-{
- chunk_t padded;
- u_char *pos;
- mpz_t t1, t2;
-
- n_to_mpz(t1, in.ptr,in.len);
-
- /* PKCS#1 v1.5 8.3 RSA computation y = x^c mod n
- * Better described in PKCS#1 v2.0 5.1 RSADP.
- * There are two methods, depending on the form of the private key.
- * We use the one based on the Chinese Remainder Theorem.
- */
- mpz_init(t2);
-
- mpz_powm(t2, t1, &key->dP, &key->p); /* m1 = c^dP mod p */
- mpz_powm(t1, t1, &key->dQ, &key->q); /* m2 = c^dQ mod Q */
-
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, &key->p);
- mpz_mul(t2, t2, &key->qInv);
- mpz_mod(t2, t2, &key->p);
-
- mpz_mul(t2, t2, &key->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- padded = mpz_to_n(t1, key->pub.k);
- mpz_clear(t1);
- mpz_clear(t2);
-
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("rsa decrypted data with padding:\n", padded)
- )
- pos = padded.ptr;
-
- /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
-
- /* check for hex pattern 00 02 in decrypted message */
- if ((*pos++ != 0x00) || (*(pos++) != 0x02))
- {
- plog("incorrect padding - probably wrong RSA key");
- freeanychunk(padded);
- return FALSE;
- }
- padded.len -= 2;
-
- /* the plaintext data starts after first 0x00 byte */
- while (padded.len-- > 0 && *pos++ != 0x00)
-
- if (padded.len == 0)
- {
- plog("no plaintext data");
- freeanychunk(padded);
- return FALSE;
- }
-
- clonetochunk(*out, pos, padded.len, "decrypted data");
- freeanychunk(padded);
- return TRUE;
-}
-
-/*
- * build signatureValue
- */
-chunk_t
-pkcs1_build_signature(chunk_t tbs, int hash_alg, const RSA_private_key_t *key
-, bool bit_string)
-{
-
- size_t siglen = key->pub.k;
-
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest = { digest_buf, MAX_DIGEST_LEN };
- chunk_t digestInfo, alg_id, signatureValue;
- u_char *pos;
-
- switch (hash_alg)
- {
- case OID_MD5:
- case OID_MD5_WITH_RSA:
- alg_id = ASN1_md5_id;
- break;
- case OID_SHA1:
- case OID_SHA1_WITH_RSA:
- alg_id = ASN1_sha1_id;
- break;
- default:
- return empty_chunk;
- }
- compute_digest(tbs, hash_alg, &digest);
-
- /* according to PKCS#1 v2.1 digest must be packaged into
- * an ASN.1 structure for encryption
- */
- digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm"
- , alg_id
- , asn1_simple_object(ASN1_OCTET_STRING, digest));
-
- /* generate the RSA signature */
- if (bit_string)
- {
- pos = build_asn1_object(&signatureValue, ASN1_BIT_STRING, 1 + siglen);
- *pos++ = 0x00;
- }
- else
- {
- pos = build_asn1_object(&signatureValue, ASN1_OCTET_STRING, siglen);
- }
- sign_hash(key, digestInfo.ptr, digestInfo.len, pos, siglen);
- pfree(digestInfo.ptr);
-
- return signatureValue;
-}
-
-/*
- * build a DER-encoded PKCS#1 private key object
- */
-chunk_t
-pkcs1_build_private_key(const RSA_private_key_t *key)
-{
- chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm"
- , ASN1_INTEGER_0
- , asn1_integer_from_mpz(&key->pub.n)
- , asn1_integer_from_mpz(&key->pub.e)
- , asn1_integer_from_mpz(&key->d)
- , asn1_integer_from_mpz(&key->p)
- , asn1_integer_from_mpz(&key->q)
- , asn1_integer_from_mpz(&key->dP)
- , asn1_integer_from_mpz(&key->dQ)
- , asn1_integer_from_mpz(&key->qInv));
-
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("PKCS#1 encoded private key:", pkcs1)
- )
- return pkcs1;
-}
-
-/*
- * build a DER-encoded PKCS#1 public key object
- */
-chunk_t
-pkcs1_build_public_key(const RSA_public_key_t *rsa)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , asn1_integer_from_mpz(&rsa->n)
- , asn1_integer_from_mpz(&rsa->e));
-}
-
-/*
- * build a DER-encoded publicKeyInfo object
- */
-chunk_t
-pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa)
-{
- chunk_t publicKey;
- chunk_t rawKey = pkcs1_build_public_key(rsa);
-
- u_char *pos = build_asn1_object(&publicKey, ASN1_BIT_STRING
- , 1 + rawKey.len);
- *pos++ = 0x00;
- mv_chunk(&pos, rawKey);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_rsaEncryption_id
- , publicKey);
-}
-void
-free_RSA_public_content(RSA_public_key_t *rsa)
-{
- mpz_clear(&rsa->n);
- mpz_clear(&rsa->e);
-}
-
-void
-free_RSA_private_content(RSA_private_key_t *rsak)
-{
- free_RSA_public_content(&rsak->pub);
- mpz_clear(&rsak->d);
- mpz_clear(&rsak->p);
- mpz_clear(&rsak->q);
- mpz_clear(&rsak->dP);
- mpz_clear(&rsak->dQ);
- mpz_clear(&rsak->qInv);
-}
-
diff --git a/programs/pluto/pkcs1.h b/programs/pluto/pkcs1.h
deleted file mode 100644
index c927db0f8..000000000
--- a/programs/pluto/pkcs1.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Support of PKCS#1 private key data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs1.h,v 1.14 2005/12/06 22:52:12 as Exp $
- */
-
-#ifndef _PKCS1_H
-#define _PKCS1_H
-
-#include <gmp.h> /* GNU Multi Precision library */
-
-#include "defs.h"
-
-typedef struct RSA_public_key RSA_public_key_t;
-
-struct RSA_public_key
-{
- char keyid[KEYID_BUF]; /* see ipsec_keyblobtoid(3) */
-
- /* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */
- unsigned k;
-
- /* public: */
- MP_INT
- n, /* modulus: p * q */
- e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
-};
-
-typedef struct RSA_private_key RSA_private_key_t;
-
-struct RSA_private_key {
- struct RSA_public_key pub; /* must be at start for RSA_show_public_key */
-
- MP_INT
- d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
- /* help for Chinese Remainder Theorem speedup: */
- p, /* first secret prime */
- q, /* second secret prime */
- dP, /* first factor's exponent: (e^-1) mod (p-1) == d mod (p-1) */
- dQ, /* second factor's exponent: (e^-1) mod (q-1) == d mod (q-1) */
- qInv; /* (q^-1) mod p */
-};
-
-struct fld {
- const char *name;
- size_t offset;
-};
-
-extern const struct fld RSA_private_field[];
-#define RSA_PRIVATE_FIELD_ELEMENTS 8
-
-extern void init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n);
-extern bool pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key);
-extern chunk_t pkcs1_build_private_key(const RSA_private_key_t *key);
-extern chunk_t pkcs1_build_public_key(const RSA_public_key_t *rsa);
-extern chunk_t pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa);
-extern chunk_t pkcs1_build_signature(chunk_t tbs, int hash_alg
- , const RSA_private_key_t *key, bool bit_string);
-extern bool compute_digest(chunk_t tbs, int alg, chunk_t *digest);
-extern void sign_hash(const RSA_private_key_t *k, const u_char *hash_val
- , size_t hash_len, u_char *sig_val, size_t sig_len);
-extern chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in);
-extern bool RSA_decrypt(const RSA_private_key_t *key, chunk_t in
- , chunk_t *out);
-extern bool same_RSA_public_key(const RSA_public_key_t *a
- , const RSA_public_key_t *b);
-extern void form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize);
-extern err_t RSA_private_key_sanity(RSA_private_key_t *k);
-#ifdef DEBUG
-extern void RSA_show_public_key(RSA_public_key_t *k);
-extern void RSA_show_private_key(RSA_private_key_t *k);
-#endif
-extern void free_RSA_public_content(RSA_public_key_t *rsa);
-extern void free_RSA_private_content(RSA_private_key_t *rsak);
-
-#endif /* _PKCS1_H */
diff --git a/programs/pluto/pkcs7.c b/programs/pluto/pkcs7.c
deleted file mode 100644
index 0691a80d6..000000000
--- a/programs/pluto/pkcs7.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/* Support of PKCS#7 data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs7.c,v 1.13 2005/12/22 22:11:24 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <crypto/des.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "asn1.h"
-#include "oid.h"
-#include "log.h"
-#include "x509.h"
-#include "certs.h"
-#include "pkcs7.h"
-#include "rnd.h"
-
-const contentInfo_t empty_contentInfo = {
- OID_UNKNOWN , /* type */
- { NULL, 0 } /* content */
-};
-
-/* ASN.1 definition of the PKCS#7 ContentInfo type */
-
-static const asn1Object_t contentInfoObjects[] = {
- { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define PKCS7_INFO_TYPE 1
-#define PKCS7_INFO_CONTENT 2
-#define PKCS7_INFO_ROOF 4
-
-/* ASN.1 definition of the PKCS#7 signedData type */
-
-static const asn1Object_t signedDataObjects[] = {
- { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 6 */
- { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
- { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_LOOP }, /* 9 */
- { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
- { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
- { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
- { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
- { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
- { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
- { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */
-};
-
-#define PKCS7_DIGEST_ALG 3
-#define PKCS7_SIGNED_CONTENT_INFO 5
-#define PKCS7_SIGNED_CERT 7
-#define PKCS7_SIGNER_INFO 13
-#define PKCS7_SIGNED_ISSUER 16
-#define PKCS7_SIGNED_SERIAL_NUMBER 17
-#define PKCS7_DIGEST_ALGORITHM 18
-#define PKCS7_AUTH_ATTRIBUTES 19
-#define PKCS7_DIGEST_ENC_ALGORITHM 21
-#define PKCS7_ENCRYPTED_DIGEST 22
-#define PKCS7_SIGNED_ROOF 26
-
-/* ASN.1 definition of the PKCS#7 envelopedData type */
-
-static const asn1Object_t envelopedDataObjects[] = {
- { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
- { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
- { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
- { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */
-};
-
-#define PKCS7_ENVELOPED_VERSION 1
-#define PKCS7_RECIPIENT_INFO_VERSION 4
-#define PKCS7_ISSUER 6
-#define PKCS7_SERIAL_NUMBER 7
-#define PKCS7_ENCRYPTION_ALG 8
-#define PKCS7_ENCRYPTED_KEY 9
-#define PKCS7_CONTENT_TYPE 12
-#define PKCS7_CONTENT_ENC_ALGORITHM 13
-#define PKCS7_ENCRYPTED_CONTENT 14
-#define PKCS7_ENVELOPED_ROOF 15
-
-/* PKCS7 contentInfo OIDs */
-
-static u_char ASN1_pkcs7_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
-};
-
-static u_char ASN1_pkcs7_signed_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
-};
-
-static u_char ASN1_pkcs7_enveloped_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
-};
-
-static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
-};
-
-static u_char ASN1_pkcs7_digested_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
-};
-
-static char ASN1_pkcs7_encrypted_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
-};
-
-static const chunk_t ASN1_pkcs7_data_oid =
- strchunk(ASN1_pkcs7_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_data_oid =
- strchunk(ASN1_pkcs7_signed_data_oid_str);
-static const chunk_t ASN1_pkcs7_enveloped_data_oid =
- strchunk(ASN1_pkcs7_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid =
- strchunk(ASN1_pkcs7_signed_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_digested_data_oid =
- strchunk(ASN1_pkcs7_digested_data_oid_str);
-static const chunk_t ASN1_pkcs7_encrypted_data_oid =
- strchunk(ASN1_pkcs7_encrypted_data_oid_str);
-
-/* 3DES and DES encryption OIDs */
-
-static u_char ASN1_3des_ede_cbc_oid_str[] = {
- 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
-};
-
-static u_char ASN1_des_cbc_oid_str[] = {
- 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x07
-};
-
-static const chunk_t ASN1_3des_ede_cbc_oid =
- strchunk(ASN1_3des_ede_cbc_oid_str);
-static const chunk_t ASN1_des_cbc_oid =
- strchunk(ASN1_des_cbc_oid_str);
-
-/* PKCS#7 attribute type OIDs */
-
-static u_char ASN1_contentType_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03
-};
-
-static u_char ASN1_messageDigest_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04
-};
-
-static const chunk_t ASN1_contentType_oid =
- strchunk(ASN1_contentType_oid_str);
-static const chunk_t ASN1_messageDigest_oid =
- strchunk(ASN1_messageDigest_oid_str);
-
-/*
- * Parse PKCS#7 ContentInfo object
- */
-bool
-pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < PKCS7_INFO_ROOF)
- {
- if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- if (objectID == PKCS7_INFO_TYPE)
- {
- cInfo->type = known_oid(object);
- if (cInfo->type < OID_PKCS7_DATA
- || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
- {
- plog("unknown pkcs7 content type");
- return FALSE;
- }
- }
- else if (objectID == PKCS7_INFO_CONTENT)
- {
- cInfo->content = object;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/*
- * Parse a PKCS#7 signedData object
- */
-bool
-pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
-, chunk_t *attributes, const x509cert_t *cacert)
-{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int digest_alg = OID_UNKNOWN;
- int enc_alg = OID_UNKNOWN;
- int signerInfos = 0;
- int objectID = 0;
-
- contentInfo_t cInfo = empty_contentInfo;
- chunk_t encrypted_digest = empty_chunk;
-
- if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
- return FALSE;
-
- if (cInfo.type != OID_PKCS7_SIGNED_DATA)
- {
- plog("pkcs7 content type is not signedData");
- return FALSE;
- }
-
- asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
-
- while (objectID < PKCS7_SIGNED_ROOF)
- {
- if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case PKCS7_DIGEST_ALG:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_SIGNED_CONTENT_INFO:
- if (data != NULL)
- {
- pkcs7_parse_contentInfo(object, level, data);
- }
- break;
- case PKCS7_SIGNED_CERT:
- if (cert != NULL)
- {
- chunk_t cert_blob;
-
- x509cert_t *newcert = alloc_thing(x509cert_t
- , "pkcs7 wrapped x509cert");
-
- clonetochunk(cert_blob, object.ptr, object.len
- , "pkcs7 cert blob");
- *newcert = empty_x509cert;
-
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("parsing pkcs7-wrapped certificate")
- )
- if (parse_x509cert(cert_blob, level+1, newcert))
- {
- newcert->next = *cert;
- *cert = newcert;
- }
- else
- {
- free_x509cert(newcert);
- }
- }
- break;
- case PKCS7_SIGNER_INFO:
- signerInfos++;
- DBG(DBG_PARSING,
- DBG_log(" signer #%d", signerInfos)
- )
- break;
- case PKCS7_SIGNED_ISSUER:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case PKCS7_AUTH_ATTRIBUTES:
- if (attributes != NULL)
- {
- *attributes = object;
- *attributes->ptr = ASN1_SET;
- }
- break;
- case PKCS7_DIGEST_ALGORITHM:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_DIGEST_ENC_ALGORITHM:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_ENCRYPTED_DIGEST:
- encrypted_digest = object;
- }
- objectID++;
- }
-
- /* check the signature only if a cacert is available */
- if (cacert != NULL)
- {
- if (signerInfos == 0)
- {
- plog("no signerInfo object found");
- return FALSE;
- }
- else if (signerInfos > 1)
- {
- plog("more than one signerInfo object found");
- return FALSE;
- }
- if (attributes->ptr == NULL)
- {
- plog("no authenticatedAttributes object found");
- return FALSE;
- }
- if (!check_signature(*attributes, encrypted_digest, digest_alg
- , enc_alg, cacert))
- {
- plog("invalid signature");
- return FALSE;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("signature is valid")
- )
- }
- }
- return TRUE;
-}
-
-/*
- * Parse a PKCS#7 envelopedData object
- */
-bool
-pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
-, chunk_t serialNumber, const RSA_private_key_t *key)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- chunk_t iv = empty_chunk;
- chunk_t symmetric_key = empty_chunk;
- chunk_t encrypted_content = empty_chunk;
-
- u_char buf[BUF_LEN];
- u_int level;
- u_int total_keys = 3;
- int enc_alg = OID_UNKNOWN;
- int content_enc_alg = OID_UNKNOWN;
- int objectID = 0;
-
- contentInfo_t cInfo = empty_contentInfo;
- *data = empty_chunk;
-
- if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
- goto failed;
-
- if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
- {
- plog("pkcs7 content type is not envelopedData");
- return FALSE;
- }
-
- asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
-
- while (objectID < PKCS7_ENVELOPED_ROOF)
- {
- if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
- goto failed;
-
- switch (objectID)
- {
- case PKCS7_ENVELOPED_VERSION:
- if (*object.ptr != 0)
- {
- plog("envelopedData version is not 0");
- goto failed;
- }
- break;
- case PKCS7_RECIPIENT_INFO_VERSION:
- if (*object.ptr != 0)
- {
- plog("recipient info version is not 0");
- goto failed;
- }
- break;
- case PKCS7_ISSUER:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'", buf)
- )
- break;
- case PKCS7_SERIAL_NUMBER:
- if (!same_chunk(serialNumber, object))
- {
- plog("serial numbers do not match");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTION_ALG:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- if (enc_alg != OID_RSA_ENCRYPTION)
- {
- plog("only rsa encryption supported");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTED_KEY:
- if (!RSA_decrypt(key, object, &symmetric_key))
- {
- plog("symmetric key could not be decrypted with rsa");
- goto failed;
- }
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("symmetric key :", symmetric_key)
- )
- break;
- case PKCS7_CONTENT_TYPE:
- if (known_oid(object) != OID_PKCS7_DATA)
- {
- plog("encrypted content not of type pkcs7 data");
- goto failed;
- }
- break;
- case PKCS7_CONTENT_ENC_ALGORITHM:
- content_enc_alg = parse_algorithmIdentifier(object, level, &iv);
-
- switch (content_enc_alg)
- {
- case OID_DES_CBC:
- total_keys = 1;
- break;
- case OID_3DES_EDE_CBC:
- total_keys = 3;
- break;
- default:
- plog("Only DES and 3DES supported for symmetric encryption");
- goto failed;
- }
- if (symmetric_key.len != (total_keys * DES_CBC_BLOCK_SIZE))
- {
- plog("key length is not %d",(total_keys * DES_CBC_BLOCK_SIZE));
- goto failed;
- }
- if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
- {
- plog("IV could not be parsed");
- goto failed;
- }
- if (iv.len != DES_CBC_BLOCK_SIZE)
- {
- plog("IV has wrong length");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTED_CONTENT:
- encrypted_content = object;
- break;
- }
- objectID++;
- }
-
- /* decrypt the content */
- {
- u_int i;
- des_cblock des_key[3], des_iv;
- des_key_schedule key_s[3];
-
- memcpy((char *)des_key, symmetric_key.ptr, symmetric_key.len);
- memcpy((char *)des_iv, iv.ptr, iv.len);
-
- for (i = 0; i < total_keys; i++)
- {
- if (des_set_key(&des_key[i], key_s[i]))
- {
- plog("des key schedule failed");
- goto failed;
- }
- }
-
- data->len = encrypted_content.len;
- data->ptr = alloc_bytes(data->len, "decrypted data");
-
- switch (content_enc_alg)
- {
- case OID_DES_CBC:
- des_cbc_encrypt((des_cblock*)encrypted_content.ptr
- , (des_cblock*)data->ptr, data->len
- , key_s[0], &des_iv, DES_DECRYPT);
- break;
- case OID_3DES_EDE_CBC:
- des_ede3_cbc_encrypt( (des_cblock*)encrypted_content.ptr
- , (des_cblock*)data->ptr, data->len
- , key_s[0], key_s[1], key_s[2]
- , &des_iv, DES_DECRYPT);
- }
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("decrypted content with padding:\n", *data)
- )
- }
-
- /* remove the padding */
- {
- u_char *pos = data->ptr + data->len - 1;
- u_char pattern = *pos;
- size_t padding = pattern;
-
- if (padding > data->len)
- {
- plog("padding greater than data length");
- goto failed;
- }
- data->len -= padding;
-
- while (padding-- > 0)
- {
- if (*pos-- != pattern)
- {
- plog("wrong padding pattern");
- goto failed;
- }
- }
- }
- freeanychunk(symmetric_key);
- return TRUE;
-
-failed:
- freeanychunk(symmetric_key);
- pfreeany(data->ptr);
- return FALSE;
-}
-
-/**
- * @brief Builds a contentType attribute
- *
- * @return ASN.1 encoded contentType attribute
- */
-chunk_t
-pkcs7_contentType_attribute(void)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_contentType_oid
- , asn1_simple_object(ASN1_SET, ASN1_pkcs7_data_oid));
-}
-
-/**
- * @brief Builds a messageDigest attribute
- *
- *
- * @param[in] blob content to create digest of
- * @param[in] digest_alg digest algorithm to be used
- * @return ASN.1 encoded messageDigest attribute
- *
- */
-chunk_t
-pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
-{
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest = { digest_buf, MAX_DIGEST_LEN };
-
- compute_digest(content, digest_alg, &digest);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_messageDigest_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_OCTET_STRING, digest)
- )
- );
-}
-/*
- * build a DER-encoded contentInfo object
- */
-static chunk_t
-pkcs7_build_contentInfo(contentInfo_t *cInfo)
-{
- chunk_t content_type;
-
- /* select DER-encoded OID for pkcs7 contentInfo type */
- switch(cInfo->type)
- {
- case OID_PKCS7_DATA:
- content_type = ASN1_pkcs7_data_oid;
- break;
- case OID_PKCS7_SIGNED_DATA:
- content_type = ASN1_pkcs7_signed_data_oid;
- break;
- case OID_PKCS7_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_enveloped_data_oid;
- break;
- case OID_PKCS7_SIGNED_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_signed_enveloped_data_oid;
- break;
- case OID_PKCS7_DIGESTED_DATA:
- content_type = ASN1_pkcs7_digested_data_oid;
- break;
- case OID_PKCS7_ENCRYPTED_DATA:
- content_type = ASN1_pkcs7_encrypted_data_oid;
- break;
- case OID_UNKNOWN:
- default:
- fprintf(stderr, "invalid pkcs7 contentInfo type");
- return empty_chunk;
- }
-
- return (cInfo->content.ptr == NULL)
- ? asn1_simple_object(ASN1_SEQUENCE, content_type)
- : asn1_wrap(ASN1_SEQUENCE, "cm"
- , content_type
- , asn1_simple_object(ASN1_CONTEXT_C_0, cInfo->content)
- );
-}
-
-/*
- * build issuerAndSerialNumber object
- */
-chunk_t
-pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , cert->issuer
- , asn1_simple_object(ASN1_INTEGER, cert->serialNumber));
-}
-
-/*
- * create a signed pkcs7 contentInfo object
- */
-chunk_t
-pkcs7_build_signedData(chunk_t data, chunk_t attributes, const x509cert_t *cert
-, int digest_alg, const RSA_private_key_t *key)
-{
- contentInfo_t pkcs7Data, signedData;
- chunk_t authenticatedAttributes, encryptedDigest, signerInfo, cInfo;
-
- chunk_t digestAlgorithm = asn1_algorithmIdentifier(digest_alg);
-
- if (attributes.ptr != NULL)
- {
- encryptedDigest = pkcs1_build_signature(attributes, digest_alg
- , key, FALSE);
- clonetochunk(authenticatedAttributes, attributes.ptr, attributes.len
- , "authenticatedAttributes");
- *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
- }
- else
- {
- encryptedDigest = (data.ptr == NULL)? empty_chunk
- : pkcs1_build_signature(data, digest_alg, key, FALSE);
- authenticatedAttributes = empty_chunk;
- }
-
- signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm"
- , ASN1_INTEGER_1
- , pkcs7_build_issuerAndSerialNumber(cert)
- , digestAlgorithm
- , authenticatedAttributes
- , ASN1_rsaEncryption_id
- , encryptedDigest);
-
- pkcs7Data.type = OID_PKCS7_DATA;
- pkcs7Data.content = (data.ptr == NULL)? empty_chunk
- : asn1_simple_object(ASN1_OCTET_STRING, data);
-
- signedData.type = OID_PKCS7_SIGNED_DATA;
- signedData.content = asn1_wrap(ASN1_SEQUENCE, "cmmmm"
- , ASN1_INTEGER_1
- , asn1_simple_object(ASN1_SET, digestAlgorithm)
- , pkcs7_build_contentInfo(&pkcs7Data)
- , asn1_simple_object(ASN1_CONTEXT_C_0, cert->certificate)
- , asn1_wrap(ASN1_SET, "m", signerInfo));
-
- cInfo = pkcs7_build_contentInfo(&signedData);
- DBG(DBG_RAW,
- DBG_dump_chunk("signedData:\n", cInfo)
- )
-
- freeanychunk(pkcs7Data.content);
- freeanychunk(signedData.content);
- return cInfo;
-}
-
-/*
- * create a symmetrically encrypted pkcs7 contentInfo object
- */
-chunk_t
-pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int cipher)
-{
- bool des_check_key_save;
- des_key_schedule ks[3];
- des_cblock key[3], des_iv, des_iv_buf;
-
- chunk_t iv = { (u_char *)des_iv_buf, DES_CBC_BLOCK_SIZE };
- chunk_t out;
- chunk_t cipher_oid;
-
- u_int total_keys, i;
- size_t padding = pad_up(data.len, DES_CBC_BLOCK_SIZE);
-
- RSA_public_key_t public_key;
-
- init_RSA_public_key(&public_key, cert->publicExponent
- , cert->modulus);
-
- if (padding == 0)
- padding += DES_CBC_BLOCK_SIZE;
-
- out.len = data.len + padding;
- out.ptr = alloc_bytes(out.len, "DES-encrypted output");
-
- DBG(DBG_CONTROL,
- DBG_log("padding %d bytes of data to multiple DES block size of %d bytes"
- , (int)data.len, (int)out.len)
- )
-
- /* copy data */
- memcpy(out.ptr, data.ptr, data.len);
- /* append padding */
- memset(out.ptr + data.len, padding, padding);
-
- DBG(DBG_RAW,
- DBG_dump_chunk("Padded unencrypted data:\n", out)
- )
-
- /* select OID and keylength for specified cipher */
- switch (cipher)
- {
- case OID_DES_CBC:
- total_keys = 1;
- cipher_oid = ASN1_des_cbc_oid;
- break;
- case OID_3DES_EDE_CBC:
- default:
- total_keys = 3;
- cipher_oid = ASN1_3des_ede_cbc_oid;
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs7 encryption cipher: %s", oid_names[cipher].name)
- )
-
- /* generate a strong random key for DES/3DES */
- des_check_key_save = des_check_key;
- des_check_key = TRUE;
- for (i = 0; i < total_keys;i++)
- {
- for (;;)
- {
- get_rnd_bytes((char*)key[i], DES_CBC_BLOCK_SIZE);
- des_set_odd_parity(&key[i]);
- if (!des_set_key(&key[i], ks[i]))
- break;
- plog("weak DES key discarded - we try again");
- }
- DBG(DBG_PRIVATE,
- DBG_dump("DES key:", key[i], 8)
- )
- }
- des_check_key = des_check_key_save;
-
- /* generate an iv for DES/3DES CBC */
- get_rnd_bytes(des_iv, DES_CBC_BLOCK_SIZE);
- memcpy(iv.ptr, des_iv, DES_CBC_BLOCK_SIZE);
- DBG(DBG_RAW,
- DBG_dump_chunk("DES IV :", iv)
- )
-
- /* encryption using specified cipher */
- switch (cipher)
- {
- case OID_DES_CBC:
- des_cbc_encrypt((des_cblock*)out.ptr, (des_cblock*)out.ptr, out.len
- , ks[0], &des_iv, DES_ENCRYPT);
- break;
- case OID_3DES_EDE_CBC:
- default:
- des_ede3_cbc_encrypt((des_cblock*)out.ptr, (des_cblock*)out.ptr, out.len
- , ks[0], ks[1], ks[2], &des_iv, DES_ENCRYPT);
- }
- DBG(DBG_RAW,
- DBG_dump_chunk("Encrypted data:\n", out));
-
- /* build pkcs7 enveloped data object */
- {
- chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm"
- , cipher_oid
- , asn1_simple_object(ASN1_OCTET_STRING, iv));
-
- chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_pkcs7_data_oid
- , contentEncryptionAlgorithm
- , asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
-
- chunk_t plainKey = { (u_char *)key, DES_CBC_BLOCK_SIZE * total_keys };
-
- chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m"
- , RSA_encrypt(&public_key, plainKey));
-
- chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm"
- , ASN1_INTEGER_0
- , pkcs7_build_issuerAndSerialNumber(cert)
- , ASN1_rsaEncryption_id
- , encryptedKey);
-
- chunk_t cInfo;
- contentInfo_t envelopedData;
-
- envelopedData.type = OID_PKCS7_ENVELOPED_DATA;
- envelopedData.content = asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_INTEGER_0
- , asn1_wrap(ASN1_SET, "m", recipientInfo)
- , encryptedContentInfo);
-
- cInfo = pkcs7_build_contentInfo(&envelopedData);
- DBG(DBG_RAW,
- DBG_dump_chunk("envelopedData:\n", cInfo)
- )
-
- free_RSA_public_content(&public_key);
- freeanychunk(envelopedData.content);
- return cInfo;
- }
-}
diff --git a/programs/pluto/pkcs7.h b/programs/pluto/pkcs7.h
deleted file mode 100644
index 38c633f4e..000000000
--- a/programs/pluto/pkcs7.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Support of PKCS#7 data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs7.h,v 1.10 2005/12/22 22:11:24 as Exp $
- */
-
-#ifndef _PKCS7_H
-#define _PKCS7_H
-
-#include "defs.h"
-#include "pkcs1.h"
-#include "x509.h"
-
-/* Access structure for a PKCS#7 ContentInfo object */
-
-typedef struct contentInfo contentInfo_t;
-
-struct contentInfo {
- int type;
- chunk_t content;
-};
-
-extern const contentInfo_t empty_contentInfo;
-
-extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0
- , contentInfo_t *cInfo);
-extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data
- , x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert);
-extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
- , chunk_t serialNumber, const RSA_private_key_t *key);
-extern chunk_t pkcs7_contentType_attribute(void);
-extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg);
-extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert);
-extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes
- ,const x509cert_t *cert, int digest_alg, const RSA_private_key_t *key);
-extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert
- , int cipher);
-
-#endif /* _PKCS7_H */
diff --git a/programs/pluto/pluto-style.el b/programs/pluto/pluto-style.el
deleted file mode 100644
index 0de474e44..000000000
--- a/programs/pluto/pluto-style.el
+++ /dev/null
@@ -1,4 +0,0 @@
-(c-add-style "pluto" '("bsd"
- (c-basic-offset . 4)
- (c-offsets-alias . ((substatement-open . 0)))))
-
diff --git a/programs/pluto/pluto.8 b/programs/pluto/pluto.8
deleted file mode 100644
index b80d13772..000000000
--- a/programs/pluto/pluto.8
+++ /dev/null
@@ -1,1649 +0,0 @@
-.TH IPSEC_PLUTO 8 "28 March 1999"
-.SH NAME
-ipsec pluto \- IPsec IKE keying daemon
-.br
-ipsec whack \- control interface for IPSEC keying daemon
-.SH SYNOPSIS
-.na
-.nh
-.HP
-.ft B
-ipsec pluto
-[\-\-help]
-[\-\-version]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-nofork]
-[\-\-stderrlog]
-[\-\-noklips]
-[\-\-uniqueids]
-[\fB\-\-interface\fP \fIinterfacename\fP]
-[\-\-ikeport\ \c
-\fIportnumber\fP]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-secretsfile\ \c
-\fIsecrets\(hyfile\fP]
-[\-\-adns \fIpathname\fP]
-[\-\-lwdnsq \fIpathname\fP]
-[\-\-perpeerlog]
-[\-\-perpeerlogbase\ \c
-\fIdirname\fP]
-[\-\-debug\(hynone]
-[\-\-debug\(hyall]
-[\-\-debug\(hyraw]
-[\-\-debug\(hycrypt]
-[\-\-debug\(hyparsing]
-[\-\-debug\(hyemitting]
-[\-\-debug\(hycontrol]
-[\-\-debug\(hylifecycle]
-[\-\-debug\(hyklips]
-[\-\-debug\(hydns]
-[\-\-debug\(hyoppo]
-[\-\-debug\(hyprivate]
-.HP
-.ft B
-ipsec whack
-[\-\-help]
-[\-\-version]
-.HP
-.ft B
-ipsec whack
-\-\-name\ \c
-\fIconnection-name\fP
-.br
-[\-\-id\ \c
-\fIid\fP] \c
-[\-\-host\ \c
-\fIip\(hyaddress\fP]
-[\-\-ikeport\ \c
-\fIport\(hynumber\fP]
-[\-\-nexthop\ \c
-\fIip\(hyaddress\fP]
-[\-\-client\ \c
-\fIsubnet\fP]
-[\-\-dnskeyondemand]
-[\-\-updown\ \c
-\fIupdown\fP]
-.br
-\-\-to
-.br
-[\-\-id\ \c
-\fIid\fP]
-[\-\-host\ \c
-\fIip\(hyaddress\fP]
-[\-\-ikeport\ \c
-\fIport\(hynumber\fP]
-[\-\-nexthop\ \c
-\fIip\(hyaddress\fP]
-[\-\-client\ \c
-\fIsubnet\fP]
-[\-\-dnskeyondemand]
-[\-\-updown\ \c
-\fIupdown\fP]
-.br
-[\-\-psk]
-[\-\-rsasig]
-[\-\-encrypt]
-[\-\-authenticate]
-[\-\-compress]
-[\-\-tunnel]
-[\-\-pfs]
-[\-\-disablearrivalcheck]
-[\-\-ipv4]
-[\-\-ipv6]
-[\-\-tunnelipv4]
-[\-\-tunnelipv6]
-[\-\-ikelifetime\ \c
-\fIseconds\fP]
-[\-\-ipseclifetime\ \c
-\fIseconds\fP]
-[\-\-rekeymargin\ \c
-\fIseconds\fP]
-[\-\-rekeyfuzz\ \c
-\fIpercentage\fP]
-[\-\-keyingtries\ \c
-\fIcount\fP]
-[\-\-dontrekey]
-[\-\-delete]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-keyid\ \c
-\fIid\fP
-[\-\-addkey]
-[\-\-pubkeyrsa\ \c
-\fIkey\fP]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-myid\ \c
-\fIid\fP
-.HP
-.ft B
-ipsec whack
-\-\-listen|\-\-unlisten
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-route|\-\-unroute
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-initiate|\-\-terminate
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-asynchronous]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-[\-\-tunnelipv4]
-[\-\-tunnelipv6]
-\-\-oppohere \fIip\(hyaddress\fP
-\-\-oppothere \fIip\(hyaddress\fP
-.HP
-.ft B
-ipsec whack
-\-\-delete
-\-\-name\ \c
-\fIconnection-name\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-deletestate\ \c
-\fIstate-number\fP
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-[\-\-name\ \c
-\fIconnection-name\fP]
-[\-\-debug\(hynone]
-[\-\-debug\(hyall]
-[\-\-debug\(hyraw]
-[\-\-debug\(hycrypt]
-[\-\-debug\(hyparsing]
-[\-\-debug\(hyemitting]
-[\-\-debug\(hycontrol]
-[\-\-debug\(hylifecycle]
-[\-\-debug\(hyklips]
-[\-\-debug\(hydns]
-[\-\-debug\(hyoppo]
-[\-\-debug\(hyprivate]
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-status
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.HP
-.ft B
-ipsec whack
-\-\-shutdown
-[\-\-ctlbase\ \c
-\fIpath\fP]
-[\-\-optionsfrom\ \c
-\fIfilename\fP]
-[\-\-label\ \c
-\fIstring\fP]
-.ft R
-.hy
-.ad
-.SH DESCRIPTION
-.BR pluto
-is an IKE (``IPsec Key Exchange'') daemon.
-.BR whack
-is an auxiliary program to allow requests to be made to a running
-.BR pluto .
-.LP
-.BR pluto
-is used to automatically build shared ``security associations'' on a
-system that has IPsec, the secure IP protocol.
-In other words,
-.BR pluto
-can eliminate much of the work of manual keying.
-The actual
-secure transmission of packets is the responsibility of other parts of
-the system (see
-.BR KLIPS ,
-the companion implementation of IPsec).
-\fIipsec_auto\fP(8) provides a more convenient interface to
-\fBpluto\fP and \fBwhack\fP.
-.SS IKE's Job
-.LP
-A \fISecurity Association\fP (\fISA\fP) is an agreement between two network nodes on
-how to process certain traffic between them. This processing involves
-encapsulation, authentication, encryption, or compression.
-.LP
-IKE can be deployed on a network node to negotiate Security
-Associations for that node. These IKE implementations can only
-negotiate with other IKE implementations, so IKE must be on each node
-that is to be an endpoint of an IKE-negotiated Security Association.
-No other nodes need to be running IKE.
-.LP
-An IKE instance (i.e. an IKE implementation on a particular network
-node) communicates with another IKE instance using UDP IP packets, so
-there must be a route between the nodes in each direction.
-.LP
-The negotiation of Security Associations requires a number of choices
-that involve tradeoffs between security, convenience, trust, and
-efficiency. These are policy issues and are normally specified to the
-IKE instance by the system administrator.
-.LP
-IKE deals with two kinds of Security Associations. The first part of
-a negotiation between IKE instances is to build an ISAKMP SA. An
-ISAKMP SA is used to protect communication between the two IKEs.
-IPsec SAs can then be built by the IKEs \- these are used to carry
-protected IP traffic between the systems.
-.LP
-The negotiation of the ISAKMP SA is known as Phase 1. In theory,
-Phase 1 can be accomplished by a couple of different exchange types,
-but we only implement one called Main Mode (we don't implement
-Aggressive Mode).
-.LP
-Any negotiation under the protection of an ISAKMP SA, including the
-negotiation of IPsec SAs, is part of Phase 2. The exchange type
-that we use to negotiate an IPsec SA is called Quick Mode.
-.LP
-IKE instances must be able to authenticate each other as part of their
-negotiation of an ISAKMP SA. This can be done by several mechanisms
-described in the draft standards.
-.LP
-IKE negotiation can be initiated by any instance with any other. If
-both can find an agreeable set of characteristics for a Security
-Association, and both recognize each others authenticity, they can set
-up a Security Association. The standards do not specify what causes
-an IKE instance to initiate a negotiation.
-.LP
-In summary, an IKE instance is prepared to automate the management of
-Security Associations in an IPsec environment, but a number of issues
-are considered policy and are left in the system administrator's hands.
-.SS Pluto
-.LP
-\fBpluto\fP is an implementation of IKE. It runs as a daemon on a network
-node. Currently, this network node must be a LINUX system running the
-\fBKLIPS\fP implementation of IPsec.
-.LP
-\fBpluto\fP only implements a subset of IKE. This is enough for it to
-interoperate with other instances of \fBpluto\fP, and many other IKE
-implementations. We are working on implementing more of IKE.
-.LP
-The policy for acceptable characteristics for Security Associations is
-mostly hardwired into the code of \fBpluto\fP (spdb.c). Eventually
-this will be moved into a security policy database with reasonable
-expressive power and more convenience.
-.LP
-\fBpluto\fP uses shared secrets or RSA signatures to authenticate
-peers with whom it is negotiating.
-.LP
-\fBpluto\fP initiates negotiation of a Security Association when it is
-manually prodded: the program \fBwhack\fP is run to trigger this.
-It will also initiate a negotiation when \fBKLIPS\fP traps an outbound packet
-for Opportunistic Encryption.
-.LP
-\fBpluto\fP implements ISAKMP SAs itself. After it has negotiated the
-characteristics of an IPsec SA, it directs \fBKLIPS\fP to implement it.
-It also invokes a script to adjust any firewall and issue \fIroute\fP(8)
-commands to direct IP packets through \fBKLIPS\fP.
-.LP
-When \fBpluto\fP shuts down, it closes all Security Associations.
-.SS Before Running Pluto
-.LP
-\fBpluto\fP runs as a daemon with userid root. Before running it, a few
-things must be set up.
-.LP
-\fBpluto\fP requires \fBKLIPS\fP, the FreeS/WAN implementation of IPsec.
-All of the components of \fBKLIPS\fP and \fBpluto\fP should be installed.
-.LP
-\fBpluto\fP supports multiple public networks (that is, networks
-that are considered insecure and thus need to have their traffic
-encrypted or authenticated). It discovers the
-public interfaces to use by looking at all interfaces that are
-configured (the \fB\-\-interface\fP option can be used to limit
-the interfaces considered).
-It does this only when \fBwhack\fP tells it to \-\-listen,
-so the interfaces must be configured by then. Each interface with a name of the form
-\fBipsec\fP[\fB0\fP-\fB9\fP] is taken as a \fBKLIPS\fP virtual public interface.
-Another network interface with the same IP address (there should be only
-one) is taken as the corresponding real public
-interface. \fIifconfig\fP(8) with the \fB\-a\fP flag will show
-the name and status of each network interface.
-.LP
-\fBpluto\fP requires a database of preshared secrets and RSA private keys.
-This is described in the
-.IR ipsec.secrets (5).
-\fBpluto\fP is told of RSA public keys via \fBwhack\fP commands.
-If the connection is Opportunistic, and no RSA public key is known,
-\fBpluto\fP will attempt to fetch RSA keys using the Domain Name System.
-.SS Setting up \fBKLIPS\fP for \fBpluto\fP
-.LP
-The most basic network topology that \fBpluto\fP supports has two security
-gateways negotiating on behalf of client subnets. The diagram of RGB's
-testbed is a good example (see \fIklips/doc/rgb_setup.txt\fP).
-.LP
-The file \fIINSTALL\fP in the base directory of this distribution
-explains how to start setting up the whole system, including \fBKLIPS\fP.
-.LP
-Make sure that the security gateways have routes to each other. This
-is usually covered by the default route, but may require issuing
-.IR route (8)
-commands. The route must go through a particular IP
-interface (we will assume it is \fIeth0\fP, but it need not be). The
-interface that connects the security gateway to its client must be a
-different one.
-.LP
-It is necessary to issue a
-.IR ipsec_tncfg (8)
-command on each gateway. The required command is:
-
-\ \ \ ipsec tncfg \-\-attach\ \-\-virtual\ ipsec0 \-\-physical\ eth0
-
-A command to set up the ipsec0 virtual interface will also need to be
-run. It will have the same parameters as the command used to set up
-the physical interface to which it has just been connected using
-.IR ipsec_tncfg (8).
-.SS ipsec.secrets file
-.LP
-A \fBpluto\fP daemon and another IKE daemon (for example, another instance
-of \fBpluto\fP) must convince each other that they are who they are supposed
-to be before any negotiation can succeed. This authentication is
-accomplished by using either secrets that have been shared beforehand
-(manually) or by using RSA signatures. There are other techniques,
-but they have not been implemented in \fBpluto\fP.
-.LP
-The file \fI/etc/ipsec.secrets\fP is used to keep preshared secret keys
-and RSA private keys for
-authentication with other IKE daemons. For debugging, there is an
-argument to the \fBpluto\fP command to use a different file.
-This file is described in
-.IR ipsec.secrets (5).
-.SS Running Pluto
-.LP
-To fire up the daemon, just type \fBpluto\fP (be sure to be running as
-the superuser).
-The default IKE port number is 500, the UDP port assigned by IANA for IKE Daemons.
-\fBpluto\fP must be run by the superuser to be able to use the UDP 500 port.
-.LP
-\fBpluto\fP attempts to create a lockfile with the name
-\fI/var/run/pluto.pid\fP. If the lockfile cannot be created,
-\fBpluto\fP exits \- this prevents multiple \fBpluto\fPs from
-competing Any ``leftover'' lockfile must be removed before
-\fBpluto\fP will run. \fBpluto\fP writes its pid into this file so
-that scripts can find it. This lock will not function properly if it
-is on an NFS volume (but sharing locks on multiple machines doesn't
-make sense anyway).
-.LP
-\fBpluto\fP then forks and the parent exits. This is the conventional
-``daemon fork''. It can make debugging awkward, so there is an option
-to suppress this fork.
-.LP
-All logging, including diagnostics, is sent to
-.IR syslog (3)
-with facility=authpriv;
-it decides where to put these messages (possibly in /var/log/secure).
-Since this too can make debugging awkward, there is an option to
-steer logging to stderr.
-.LP
-If the \fB\-\-perpeerlog\fP option is given, then pluto will open
-a log file per connection. By default, this is in /var/log/pluto/peer,
-in a subdirectory formed by turning all dot (.) [IPv4} or colon (:)
-[IPv6] into slashes (/).
-.LP
-The base directory can be changed with the \fB\-\-perpeerlogbase\fP.
-.LP
-Once \fBpluto\fP is started, it waits for requests from \fBwhack\fP.
-.SS Pluto's Internal State
-.LP
-To understand how to use \fBpluto\fP, it is helpful to understand a little
-about its internal state. Furthermore, the terminology is needed to decipher
-some of the diagnostic messages.
-.LP
-The \fI(potential) connection\fP database describes attributes of a
-connection. These include the IP addresses of the hosts and client
-subnets and the security characteristics desired. \fBpluto\fP
-requires this information (simply called a connection) before it can
-respond to a request to build an SA. Each connection is given a name
-when it is created, and all references are made using this name.
-.LP
-During the IKE exchange to build an SA, the information about the
-negotiation is represented in a \fIstate object\fP. Each state object
-reflects how far the negotiation has reached. Once the negotiation is
-complete and the SA established, the state object remains to represent
-the SA. When the SA is terminated, the state object is discarded.
-Each State object is given a serial number and this is used to refer
-to the state objects in logged messages.
-.LP
-Each state object corresponds to a connection and can be thought of
-as an instantiation of that connection.
-At any particular time, there may be any number of state objects
-corresponding to a particular connection.
-Often there is one representing an ISAKMP SA and another representing
-an IPsec SA.
-.LP
-\fBKLIPS\fP hooks into the routing code in a LINUX kernel.
-Traffic to be processed by an IPsec SA must be directed through
-\fBKLIPS\fP by routing commands. Furthermore, the processing to be
-done is specified by \fIipsec eroute(8)\fP commands.
-\fBpluto\fP takes the responsibility of managing both of these special
-kinds of routes.
-.LP
-Each connection may be routed, and must be while it has an IPsec SA.
-The connection specifies the characteristics of the route: the
-interface on this machine, the ``gateway'' (the nexthop),
-and the peer's client subnet. Two
-connections may not be simultaneously routed if they are for the same
-peer's client subnet but use different interfaces or gateways
-(\fBpluto\fP's logic does not reflect any advanced routing capabilities).
-.LP
-Each eroute is associated with the state object for an IPsec SA
-because it has the particular characteristics of the SA.
-Two eroutes conflict if they specify the identical local
-and remote clients (unlike for routes, the local clients are
-taken into account).
-.LP
-When \fBpluto\fP needs to install a route for a connection,
-it must make sure that no conflicting route is in use. If another
-connection has a conflicting route, that route will be taken down, as long
-as there is no IPsec SA instantiating that connection.
-If there is such an IPsec SA, the attempt to install a route will fail.
-.LP
-There is an exception. If \fBpluto\fP, as Responder, needs to install
-a route to a fixed client subnet for a connection, and there is
-already a conflicting route, then the SAs using the route are deleted
-to make room for the new SAs. The rationale is that the new
-connection is probably more current. The need for this usually is a
-product of Road Warrior connections (these are explained later; they
-cannot be used to initiate).
-.LP
-When \fBpluto\fP needs to install an eroute for an IPsec SA (for a
-state object), first the state object's connection must be routed (if
-this cannot be done, the eroute and SA will not be installed).
-If a conflicting eroute is already in place for another connection,
-the eroute and SA will not be installed (but note that the routing
-exception mentioned above may have already deleted potentially conflicting SAs).
-If another IPsec
-SA for the same connection already has an eroute, all its outgoing traffic
-is taken over by the new eroute. The incoming traffic will still be
-processed. This characteristic is exploited during rekeying.
-.LP
-All of these routing characteristics are expected change when
-\fBKLIPS\fP is modified to use the firewall hooks in the LINUX 2.4.x
-kernel.
-.SS Using Whack
-.LP
-\fBwhack\fP is used to command a running \fBpluto\fP.
-\fBwhack\fP uses a UNIX domain socket to speak to \fBpluto\fP
-(by default, \fI/var/pluto.ctl\fP).
-.LP
-\fBwhack\fP has an intricate argument syntax.
-This syntax allows many different functions to be specified.
-The help form shows the usage or version information.
-The connection form gives \fBpluto\fP a description of a potential connection.
-The public key form informs \fBpluto\fP of the RSA public key for a potential peer.
-The delete form deletes a connection description and all SAs corresponding
-to it.
-The listen form tells \fBpluto\fP to start or stop listening on the public interfaces
-for IKE requests from peers.
-The route form tells \fBpluto\fP to set up routing for a connection;
-the unroute form undoes this.
-The initiate form tells \fBpluto\fP to negotiate an SA corresponding to a connection.
-The terminate form tells \fBpluto\fP to remove all SAs corresponding to a connection,
-including those being negotiated.
-The status form displays the \fBpluto\fP's internal state.
-The debug form tells \fBpluto\fP to change the selection of debugging output
-``on the fly''. The shutdown form tells
-\fBpluto\fP to shut down, deleting all SAs.
-.LP
-Most options are specific to one of the forms, and will be described
-with that form. There are three options that apply to all forms.
-.TP
-\fB\-\-ctlbase\fP\ \fIpath\fP
-\fIpath\fP.ctl is used as the UNIX domain socket for talking
-to \fBpluto\fP.
-This option facilitates debugging.
-.TP
-\fB\-\-optionsfrom\fP\ \fIfilename\fP
-adds the contents of the file to the argument list.
-.TP
-\fB\-\-label\fP\ \fIstring\fP
-adds the string to all error messages generated by \fBwhack\fP.
-.LP
-The help form of \fBwhack\fP is self-explanatory.
-.TP
-\fB\-\-help\fP
-display the usage message.
-.TP
-\fB\-\-version\fP
-display the version of \fBwhack\fP.
-.LP
-The connection form describes a potential connection to \fBpluto\fP.
-\fBpluto\fP needs to know what connections can and should be negotiated.
-When \fBpluto\fP is the initiator, it needs to know what to propose.
-When \fBpluto\fP is the responder, it needs to know enough to decide whether
-is is willing to set up the proposed connection.
-.LP
-The description of a potential connection can specify a large number
-of details. Each connection has a unique name. This name will appear
-in a updown shell command, so it should not contain punctuation
-that would make the command ill-formed.
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The topology of
-a connection is symmetric, so to save space here is half a picture:
-
-\ \ \ client_subnet<\-\->host:ikeport<\-\->nexthop<\-\-\-
-
-A similar trick is used in the flags. The same flag names are used for
-both ends. Those before the \fB\-\-to\fP flag describe the left side
-and those afterwards describe the right side. When \fBpluto\fP attempts
-to use the connection, it decides whether it is the left side or the right
-side of the connection, based on the IP numbers of its interfaces.
-.TP
-\fB\-\-id\fP\ \fIid\fP
-the identity of the end. Currently, this can be an IP address (specified
-as dotted quad or as a Fully Qualified Domain Name, which will be resolved
-immediately) or as a Fully Qualified Domain Name itself (prefixed by ``@''
-to signify that it should not be resolved), or as user@FQDN, or as the
-magic value \fB%myid\fP.
-\fBPluto\fP only authenticates the identity, and does not use it for
-addressing, so, for example, an IP address need not be the one to which
-packets are to be sent. If the option is absent, the
-identity defaults to the IP address specified by \fB\-\-host\fP.
-\fB%myid\fP allows the identity to be separately specified (by the \fBpluto\fP or \fBwhack\fP option \fB\-\-myid\fP
-or by the \fBipsec.conf\fP(5) \fBconfig setup\fP parameter \fPmyid\fP).
-Otherwise, \fBpluto\fP tries to guess what \fB%myid\fP should stand for:
-the IP address of \fB%defaultroute\fP, if it is supported by a suitable TXT record in the reverse domain for that IP address,
-or the system's hostname, if it is supported by a suitable TXT record in its forward domain.
-.\" The identity is transmitted in the IKE protocol, and is what is authenticated.
-.TP
-\fB\-\-host\fP\ \fIip\(hyaddress\fP
-.TP
-\fB\-\-host\fP\ \fB%any\fP
-.TP
-\fB\-\-host\fP\ \fB%opportunistic\fP
-the IP address of the end (generally the public interface).
-If \fBpluto\fP is to act as a responder
-for IKE negotiations initiated from unknown IP addresses (the
-``Road Warrior'' case), the
-IP address should be specified as \fB%any\fP (currently,
-the obsolete notation \fB0.0.0.0\fP is also accepted for this).
-If \fBpluto\fP is to opportunistically initiate the connection,
-use \fB%opportunistic\fP
-.TP
-\fB\-\-ikeport\fP\ \fIport\(hynumber\fP
-the UDP port that IKE listens to on that host. The default is 500.
-(\fBpluto\fP on this machine uses the port specified by its own command
-line argument, so this only affects where \fBpluto\fP sends messages.)
-.TP
-\fB\-\-nexthop\fP\ \fIip\(hyaddress\fP
-where to route packets for the peer's client (presumably for the peer too,
-but it will not be used for this).
-When \fBpluto\fP installs an IPsec SA, it issues a route command.
-It uses the nexthop as the gateway.
-The default is the peer's IP address (this can be explicitly written as
-\fB%direct\fP; the obsolete notation \fB0.0.0.0\fP is accepted).
-This option is necessary if \fBpluto\fP's host's interface used for sending
-packets to the peer is neither point-to-point nor directly connected to the
-peer.
-.TP
-\fB\-\-client\fP\ \fIsubnet\fP
-the subnet for which the IPsec traffic will be destined. If not specified,
-the host will be the client.
-The subnet can be specified in any of the forms supported by \fIipsec_atosubnet\fP(3).
-The general form is \fIaddress\fP/\fImask\fP. The \fIaddress\fP can be either
-a domain name or four decimal numbers (specifying octets) separated by dots.
-The most convenient form of the \fImask\fP is a decimal integer, specifying
-the number of leading one bits in the mask. So, for example, 10.0.0.0/8
-would specify the class A network ``Net 10''.
-.TP
-\fB\-\-dnskeyondemand]\fP
-specifies that when an RSA public key is needed to authenticate this
-host, and it isn't already known, fetch it from DNS.
-.TP
-\fB\-\-updown\fP\ \fIupdown\fP
-specifies an external shell command to be run whenever \fBpluto\fP
-brings up or down a connection.
-The script is used to build a shell command, so it may contain positional
-parameters, but ought not to have punctuation that would cause the
-resulting command to be ill-formed.
-The default is \fIipsec _updown\fP.
-.TP
-\fB\-\-to\fP
-separates the specification of the left and right ends of the connection.
-.LP
-The potential connection description also specifies characteristics of
-rekeying and security.
-.TP
-\fB\-\-psk\fP
-Propose and allow preshared secret authentication for IKE peers. This authentication
-requires that each side use the same secret. May be combined with \fB\-\-rsasig\fP;
-at least one must be specified.
-.TP
-\fB\-\-rsasig\fP
-Propose and allow RSA signatures for authentication of IKE peers. This authentication
-requires that each side have have a private key of its own and know the
-public key of its peer. May be combined with \fB\-\-psk\fP;
-at least one must be specified.
-.TP
-\fB\-\-encrypt\fP
-All proposed or accepted IPsec SAs will include non-null ESP.
-The actual choices of transforms are wired into \fBpluto\fP.
-.TP
-\fB\-\-authenticate\fP
-All proposed IPsec SAs will include AH.
-All accepted IPsec SAs will include AH or ESP with authentication.
-The actual choices of transforms are wired into \fBpluto\fP.
-Note that this has nothing to do with IKE authentication.
-.TP
-\fB\-\-compress\fP
-All proposed IPsec SAs will include IPCOMP (compression).
-This will be ignored if KLIPS is not configured with IPCOMP support.
-.TP
-\fB\-\-tunnel\fP
-the IPsec SA should use tunneling. Implicit if the SA is for clients.
-Must only be used with \fB\-\-authenticate\fP or \fB\-\-encrypt\fP.
-.TP
-\fB\-\-ipv4\fP
-The host addresses will be interpreted as IPv4 addresses. This is the
-default. Note that for a connection, all host addresses must be of
-the same Address Family (IPv4 and IPv6 use different Address Families).
-.TP
-\fB\-\-ipv6\fP
-The host addresses (including nexthop) will be interpreted as IPv6 addresses.
-Note that for a connection, all host addresses must be of
-the same Address Family (IPv4 and IPv6 use different Address Families).
-.TP
-\fB\-\-tunnelipv4\fP
-The client addresses will be interpreted as IPv4 addresses. The default is
-to match what the host will be. This does not imply \fB\-\-tunnel\fP so the
-flag can be safely used when no tunnel is actually specified.
-Note that for a connection, all tunnel addresses must be of the same
-Address Family.
-.TP
-\fB\-\-tunnelipv6\fP
-The client addresses will be interpreted as IPv6 addresses. The default is
-to match what the host will be. This does not imply \fB\-\-tunnel\fP so the
-flag can be safely used when no tunnel is actually specified.
-Note that for a connection, all tunnel addresses must be of the same
-Address Family.
-.TP
-\fB\-\-pfs\fP
-There should be Perfect Forward Secrecy \- new keying material will
-be generated for each IPsec SA rather than being derived from the ISAKMP
-SA keying material.
-Since the group to be used cannot be negotiated (a dubious feature of the
-standard), \fBpluto\fP will propose the same group that was used during Phase 1.
-We don't implement a stronger form of PFS which would require that the
-ISAKMP SA be deleted after the IPSEC SA is negotiated.
-.TP
-\fB\-\-disablearrivalcheck\fP
-If the connection is a tunnel, allow packets arriving through the tunnel
-to have any source and destination addresses.
-.LP
-If none of the \fB\-\-encrypt\fP, \fB\-\-authenticate\fP, \fB\-\-compress\fP,
-or \fB\-\-pfs\fP flags is given, the initiating the connection will
-only build an ISAKMP SA. For such a connection, client subnets have
-no meaning and must not be specified.
-.LP
-More work is needed to allow for flexible policies. Currently
-policy is hardwired in the source file spdb.c. The ISAKMP SAs may use
-Oakley groups MODP1024 and MODP1536; 3DES encryption; SHA1-96
-and MD5-96 authentication. The IPsec SAs may use 3DES and
-MD5-96 or SHA1-96 for ESP, or just MD5-96 or SHA1-96 for AH.
-IPCOMP Compression is always Deflate.
-.TP
-\fB\-\-ikelifetime\fP\ \fIseconds\fP
-how long \fBpluto\fP will propose that an ISAKMP SA be allowed to live.
-The default is 10800 (three hours) and the maximum is 86400 (one day).
-This option will not affect what is accepted.
-\fBpluto\fP will reject proposals that exceed the maximum.
-.TP
-\fB\-\-ipseclifetime\fP\ \fIseconds\fP
-how long \fBpluto\fP will propose that an IPsec SA be allowed to live.
-The default is 3600 (one hour) and the maximum is 86400 (one day).
-This option will not affect what is accepted.
-\fBpluto\fP will reject proposals that exceed the maximum.
-.TP
-\fB\-\-rekeymargin\fP\ \fIseconds\fP
-how long before an SA's expiration should \fBpluto\fP try to negotiate
-a replacement SA. This will only happen if \fBpluto\fP was the initiator.
-The default is 540 (nine minutes).
-.TP
-\fB\-\-rekeyfuzz\fP\ \fIpercentage\fP
-maximum size of random component to add to rekeymargin, expressed as
-a percentage of rekeymargin. \fBpluto\fP will select a delay uniformly
-distributed within this range. By default, the percentage will be 100.
-If greater determinism is desired, specify 0. It may be appropriate
-for the percentage to be much larger than 100.
-.TP
-\fB\-\-keyingtries\fP\ \fIcount\fP
-how many times \fBpluto\fP should try to negotiate an SA,
-either for the first time or for rekeying.
-A value of 0 is interpreted as a very large number: never give up.
-The default is three.
-.TP
-\fB\-\-dontrekey\fP
-A misnomer.
-Only rekey a connection if we were the Initiator and there was recent
-traffic on the existing connection.
-This applies to Phase 1 and Phase 2.
-This is currently the only automatic way for a connection to terminate.
-It may be useful with Road Warrior or Opportunistic connections.
-.br
-Since SA lifetime negotiation is take-it-or-leave it, a Responder
-normally uses the shorter of the negotiated or the configured lifetime.
-This only works because if the lifetime is shorter than negotiated,
-the Responder will rekey in time so that everything works.
-This interacts badly with \fB\-\-dontrekey\fP. In this case,
-the Responder will end up rekeying to rectify a shortfall in an IPsec SA
-lifetime; for an ISAKMP SA, the Responder will accept the negotiated
-lifetime.
-.TP
-\fB\-\-delete\fP
-when used in the connection form, it causes any previous connection
-with this name to be deleted before this one is added. Unlike a
-normal delete, no diagnostic is produced if there was no previous
-connection to delete. Any routing in place for the connection is undone.
-.LP
-The delete form deletes a named connection description and any
-SAs established or negotiations initiated using this connection.
-Any routing in place for the connection is undone.
-.TP
-\fB\-\-delete\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The deletestate form deletes the state object with the specified serial number.
-This is useful for selectively deleting instances of connections.
-.TP
-\fB\-\-deletestate\fP\ \fIstate-number\fP
-.LP
-The route form of the \fBwhack\fP command tells \fBpluto\fP to set up
-routing for a connection.
-Although like a traditional route, it uses an ipsec device as a
-virtual interface.
-Once routing is set up, no packets will be
-sent ``in the clear'' to the peer's client specified in the connection.
-A TRAP shunt eroute will be installed; if outbound traffic is caught,
-Pluto will initiate the connection.
-An explicit \fBwhack\fP route is not always needed: if it hasn't been
-done when an IPsec SA is being installed, one will be automatically attempted.
-.LP
-When a routing is attempted for a connection, there must not already
-be a routing for a different connection with the same subnet but different
-interface or destination, or if
-there is, it must not be being used by an IPsec SA. Otherwise the
-attempt will fail.
-.TP
-\fB\-\-route\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The unroute form of the \fBwhack\fP command tells \fBpluto\fP to undo
-a routing. \fBpluto\fP will refuse if an IPsec SA is using the connection.
-If another connection is sharing the same routing, it will be left in place.
-Without a routing, packets will be sent without encryption or authentication.
-.TP
-\fB\-\-unroute\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The initiate form tells \fBpluto\fP to initiate a negotiation with another
-\fBpluto\fP (or other IKE daemon) according to the named connection.
-Initiation requires a route that \fB\-\-route\fP would provide;
-if none is in place at the time an IPsec SA is being installed,
-\fBpluto\fP attempts to set one up.
-.TP
-\fB\-\-initiate\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.TP
-\fB\-\-asynchronous
-.LP
-The initiate form of the \fBwhack\fP command will relay back from
-\fBpluto\fP status information via the UNIX domain socket (unless
-\-\-asynchronous is specified). The status information is meant to
-look a bit like that from \fBFTP\fP. Currently \fBwhack\fP simply
-copies this to stderr. When the request is finished (eg. the SAs are
-established or \fBpluto\fP gives up), \fBpluto\fP closes the channel,
-causing \fBwhack\fP to terminate.
-.LP
-The opportunistic initiate form is mainly used for debugging.
-.TP
-\fB\-\-tunnelipv4\fP
-.TP
-\fB\-\-tunnelipv6\fP
-.TP
-\fB\-\-oppohere\fP\ \fIip-address\fP
-.TP
-\fB\-\-oppothere\fP\ \fIip-address\fP
-.LP
-This will cause \fBpluto\fP to attempt to opportunistically initiate a
-connection from here to the there, even if a previous attempt
-had been made.
-The whack log will show the progress of this attempt.
-.LP
-The terminate form tells \fBpluto\fP to delete any SAs that use the specified
-connection and to stop any negotiations in process.
-It does not prevent new negotiations from starting (the delete form
-has this effect).
-.TP
-\fB\-\-terminate\fP
-.TP
-\fB\-\-name\fP\ \fIconnection-name\fP
-.LP
-The public key for informs \fBpluto\fP of the RSA public key for a potential peer.
-Private keys must be kept secret, so they are kept in
-.IR ipsec.secrets (5).
-.TP
-\fB\-\-keyid\ \fP\fIid\fP
-specififies the identity of the peer for which a public key should be used.
-Its form is identical to the identity in the connection.
-If no public key is specified, \fBpluto\fP attempts to find KEY records
-from DNS for the id (if a FQDN) or through reverse lookup (if an IP address).
-Note that there several interesting ways in which this is not secure.
-.TP
-\fB\-\-addkey\fP
-specifies that the new key is added to the collection; otherwise the
-new key replaces any old ones.
-.TP
-\fB\-\-pubkeyrsa\ \fP\fIkey\fP
-specifies the value of the RSA public key. It is a sequence of bytes
-as described in RFC 2537 ``RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)''.
-It is denoted in a way suitable for \fIipsec_ttodata\fP(3).
-For example, a base 64 numeral starts with 0s.
-.LP
-The listen form tells \fBpluto\fP to start listening for IKE requests
-on its public interfaces. To avoid race conditions, it is normal to
-load the appropriate connections into \fBpluto\fP before allowing it
-to listen. If \fBpluto\fP isn't listening, it is pointless to
-initiate negotiations, so it will refuse requests to do so. Whenever
-the listen form is used, \fBpluto\fP looks for public interfaces and
-will notice when new ones have been added and when old ones have been
-removed. This is also the trigger for \fBpluto\fP to read the
-\fIipsec.secrets\fP file. So listen may useful more than once.
-.TP
-\fB\-\-listen\fP
-start listening for IKE traffic on public interfaces.
-.TP
-\fB\-\-unlisten\fP
-stop listening for IKE traffic on public interfaces.
-.LP
-The status form will display information about the internal state of
-\fBpluto\fP: information about each potential connection, about
-each state object, and about each shunt that \fBpluto\fP is managing
-without an associated connection.
-.TP
-\fB\-\-status\fP
-.LP
-The shutdown form is the proper way to shut down \fBpluto\fP.
-It will tear down the SAs on this machine that \fBpluto\fP has negotiated.
-It does not inform its peers, so the SAs on their machines remain.
-.TP
-\fB\-\-shutdown\fP
-.SS Examples
-.LP
-It would be normal to start \fBpluto\fP in one of the system initialization
-scripts. It needs to be run by the superuser. Generally, no arguments are needed.
-To run in manually, the superuser can simply type
-
-\ \ \ ipsec pluto
-
-The command will immediately return, but a \fBpluto\fP process will be left
-running, waiting for requests from \fBwhack\fP or a peer.
-.LP
-Using \fBwhack\fP, several potential connections would be described:
-.HP
-.na
-\ \ \ ipsec whack \-\-name\ silly
-\-\-host\ 127.0.0.1 \-\-to \-\-host\ 127.0.0.2
-\-\-ikelifetime\ 900 \-\-ipseclifetime\ 800 \-\-keyingtries\ 3
-.ad
-.LP
-Since this silly connection description specifies neither encryption,
-authentication, nor tunneling, it could only be used to establish
-an ISAKMP SA.
-.HP
-.na
-\ \ \ ipsec whack \-\-name\ secret \-\-host\ 10.0.0.1 \-\-client\ 10.0.1.0/24
-\-\-to \-\-host\ 10.0.0.2 \-\-client\ 10.0.2.0/24
-\-\-encrypt
-.ad
-.LP
-This is something that must be done on both sides. If the other
-side is \fBpluto\fP, the same \fBwhack\fP command could be used on it
-(the command syntax is designed to not distinguish which end is ours).
-.LP
-Now that the connections are specified, \fBpluto\fP is ready to handle
-requests and replies via the public interfaces. We must tell it to discover
-those interfaces and start accepting messages from peers:
-
-\ \ \ ipsec whack \-\-listen
-.LP
-If we don't immediately wish to bring up a secure connection between
-the two clients, we might wish to prevent insecure traffic.
-The routing form asks \fBpluto\fP to cause the packets sent from
-our client to the peer's client to be routed through the ipsec0
-device; if there is no SA, they will be discarded:
-
-\ \ \ ipsec whack \-\-route secret
-.LP
-Finally, we are ready to get \fBpluto\fP to initiate negotiation
-for an IPsec SA (and implicitly, an ISAKMP SA):
-
-\ \ \ ipsec whack \-\-initiate\ \-\-name\ secret
-
-A small log of interesting events will appear on standard output
-(other logging is sent to syslog).
-.LP
-\fBwhack\fP can also be used to terminate \fBpluto\fP cleanly, tearing down
-all SAs that it has negotiated.
-
-\ \ \ ipsec whack \-\-shutdown
-
-Notification of any IPSEC SA deletion, but not ISAKMP SA deletion
-is sent to the peer. Unfortunately, such Notification is not reliable.
-Furthermore, \fBpluto\fP itself ignores Notifications.
-.SS The updown command
-.LP
-Whenever \fBpluto\fP brings a connection up or down, it invokes
-the updown command. This command is specified using the \fB\-\-updown\fP
-option. This allows for customized control over routing and firewall manipulation.
-.LP
-The updown is invoked for five different operations. Each of
-these operations can be for our client subnet or for our host itself.
-.TP
-\fBprepare-host\fP or \fBprepare-client\fP
-is run before bringing up a new connection if no other connection
-with the same clients is up. Generally, this is useful for deleting a
-route that might have been set up before \fBpluto\fP was run or
-perhaps by some agent not known to \fBpluto\fP.
-.TP
-\fBroute-host\fP or \fBroute-client\fP
-is run when bringing up a connection for a new peer client subnet
-(even if \fBprepare-host\fP or \fBprepare-client\fP was run). The
-command should install a suitable route. Routing decisions are based
-only on the destination (peer's client) subnet address, unlike eroutes
-which discriminate based on source too.
-.TP
-\fBunroute-host\fP or \fBunroute-client\fP
-is run when bringing down the last connection for a particular peer
-client subnet. It should undo what the \fBroute-host\fP or \fBroute-client\fP
-did.
-.TP
-\fBup-host\fP or \fBup-client\fP
-is run when bringing up a tunnel eroute with a pair of client subnets
-that does not already have a tunnel eroute.
-This command should install firewall rules as appropriate.
-It is generally a good idea to allow IKE messages (UDP port 500)
-travel between the hosts.
-.TP
-\fBdown-host\fP or \fBdown-client\fP
-is run when bringing down the eroute for a pair of client subnets.
-This command should delete firewall rules as appropriate. Note that
-there may remain some inbound IPsec SAs with these client subnets.
-.LP
-The script is passed a large number of environment variables to specify
-what needs to be done.
-.TP
-\fBPLUTO_VERSION\fP
-indicates what version of this interface is being used. This document
-describes version 1.1. This is upwardly compatible with version 1.0.
-.TP
-\fBPLUTO_VERB\fP
-specifies the name of the operation to be performed
-(\fBprepare-host\fP,r \fBprepare-client\fP,
-\fBup-host\fP, \fBup-client\fP,
-\fBdown-host\fP, or \fBdown-client\fP). If the address family for
-security gateway to security gateway communications is IPv6, then
-a suffix of -v6 is added to the verb.
-.TP
-\fBPLUTO_CONNECTION\fP
-is the name of the connection for which we are routing.
-.TP
-\fBPLUTO_NEXT_HOP\fP
-is the next hop to which packets bound for the peer must be sent.
-.TP
-\fBPLUTO_INTERFACE\fP
-is the name of the ipsec interface to be used.
-.TP
-\fBPLUTO_ME\fP
-is the IP address of our host.
-.TP
-\fBPLUTO_MY_CLIENT\fP
-is the IP address / count of our client subnet.
-If the client is just the host, this will be the host's own IP address / max
-(where max is 32 for IPv4 and 128 for IPv6).
-.TP
-\fBPLUTO_MY_CLIENT_NET\fP
-is the IP address of our client net.
-If the client is just the host, this will be the host's own IP address.
-.TP
-\fBPLUTO_MY_CLIENT_MASK\fP
-is the mask for our client net.
-If the client is just the host, this will be 255.255.255.255.
-.TP
-\fBPLUTO_PEER\fP
-is the IP address of our peer.
-.TP
-\fBPLUTO_PEER_CLIENT\fP
-is the IP address / count of the peer's client subnet.
-If the client is just the peer, this will be the peer's own IP address / max
-(where max is 32 for IPv4 and 128 for IPv6).
-.TP
-\fBPLUTO_PEER_CLIENT_NET\fP
-is the IP address of the peer's client net.
-If the client is just the peer, this will be the peer's own IP address.
-.TP
-\fBPLUTO_PEER_CLIENT_MASK\fP
-is the mask for the peer's client net.
-If the client is just the peer, this will be 255.255.255.255.
-.LP
-All output sent by the script to stderr or stdout is logged. The
-script should return an exit status of 0 if and only if it succeeds.
-.LP
-\fBPluto\fP waits for the script to finish and will not do any other
-processing while it is waiting.
-The script may assume that \fBpluto\fP will not change anything
-while the script runs.
-The script should avoid doing anything that takes much time and it
-should not issue any command that requires processing by \fBpluto\fP.
-Either of these activities could be performed by a background
-subprocess of the script.
-.SS Rekeying
-.LP
-When an SA that was initiated by \fBpluto\fP has only a bit of
-lifetime left,
-\fBpluto\fP will initiate the creation of a new SA. This applies to
-ISAKMP and IPsec SAs.
-The rekeying will be initiated when the SA's remaining lifetime is
-less than the rekeymargin plus a random percentage, between 0 and
-rekeyfuzz, of the rekeymargin.
-.LP
-Similarly, when an SA that was initiated by the peer has only a bit of
-lifetime left, \fBpluto\fP will try to initiate the creation of a
-replacement.
-To give preference to the initiator, this rekeying will only be initiated
-when the SA's remaining lifetime is half of rekeymargin.
-If rekeying is done by the responder, the roles will be reversed: the
-responder for the old SA will be the initiator for the replacement.
-The former initiator might also initiate rekeying, so there may
-be redundant SAs created.
-To avoid these complications, make sure that rekeymargin is generous.
-.LP
-One risk of having the former responder initiate is that perhaps
-none of its proposals is acceptable to the former initiator
-(they have not been used in a successful negotiation).
-To reduce the chances of this happening, and to prevent loss of security,
-the policy settings are taken from the old SA (this is the case even if
-the former initiator is initiating).
-These may be stricter than those of the connection.
-.LP
-\fBpluto\fP will not rekey an SA if that SA is not the most recent of its
-type (IPsec or ISAKMP) for its potential connection.
-This avoids creating redundant SAs.
-.LP
-The random component in the rekeying time (rekeyfuzz) is intended to
-make certain pathological patterns of rekeying unstable. If both
-sides decide to rekey at the same time, twice as many SAs as necessary
-are created. This could become a stable pattern without the
-randomness.
-.LP
-Another more important case occurs when a security gateway has SAs
-with many other security gateways. Each of these connections might
-need to be rekeyed at the same time. This would cause a high peek
-requirement for resources (network bandwidth, CPU time, entropy for
-random numbers). The rekeyfuzz can be used to stagger the rekeying
-times.
-.LP
-Once a new set of SAs has been negotiated, \fBpluto\fP will never send
-traffic on a superseded one. Traffic will be accepted on an old SA
-until it expires.
-.SS Selecting a Connection When Responding: Road Warrior Support
-.LP
-When \fBpluto\fP receives an initial Main Mode message, it needs to
-decide which connection this message is for. It picks based solely on
-the source and destination IP addresses of the message. There might
-be several connections with suitable IP addresses, in which case one
-of them is arbitrarily chosen. (The ISAKMP SA proposal contained in
-the message could be taken into account, but it is not.)
-.LP
-The ISAKMP SA is negotiated before the parties pass further
-identifying information, so all ISAKMP SA characteristics specified in
-the connection description should be the same for every connection
-with the same two host IP addresses. At the moment, the only
-characteristic that might differ is authentication method.
-.LP
-Up to this point,
-all configuring has presumed that the IP addresses
-are known to all parties ahead of time. This will not work
-when either end is mobile (or assigned a dynamic IP address for other
-reasons). We call this situation ``Road Warrior''. It is fairly tricky
-and has some important limitations, most of which are features of
-the IKE protocol.
-.LP
-Only the initiator may be mobile:
-the initiator may have an IP number unknown to the responder. When
-the responder doesn't recognize the IP address on the first Main Mode
-packet, it looks for a connection with itself as one end and \fB%any\fP
-as the other.
-If it cannot find one, it refuses to negotiate. If it
-does find one, it creates a temporary connection that is a duplicate
-except with the \fB%any\fP replaced by the source IP address from the
-packet; if there was no identity specified for the peer, the new IP
-address will be used.
-.LP
-When \fBpluto\fP is using one of these temporary connections and
-needs to find the preshared secret or RSA private key in \fIipsec.secrets\fP,
-and and the connection specified no identity for the peer, \fB%any\fP
-is used as its identity. After all, the real IP address was apparently
-unknown to the configuration, so it is unreasonable to require that
-it be used in this table.
-.LP
-Part way into the Phase 1 (Main Mode) negotiation using one of these
-temporary connection descriptions, \fBpluto\fP will be receive an
-Identity Payload. At this point, \fBpluto\fP checks for a more
-appropriate connection, one with an identity for the peer that matches
-the payload but which would use the same keys so-far used for
-authentication. If it finds one, it will switch to using this better
-connection (or a temporary derived from this, if it has \fB%any\fP
-for the peer's IP address). It may even turn out that no connection
-matches the newly discovered identity, including the current connection;
-if so, \fBpluto\fP terminates negotiation.
-.LP
-Unfortunately, if preshared secret authentication is being used, the
-Identity Payload is encrypted using this secret, so the secret must be
-selected by the responder without knowing this payload. This
-limits there to being at most one preshared secret for all Road Warrior
-systems connecting to a host. RSA Signature authentications does not
-require that the responder know how to select the initiator's public key
-until after the initiator's Identity Payload is decoded (using the
-responder's private key, so that must be preselected).
-.LP
-When \fBpluto\fP is responding to a Quick Mode negotiation via one of these
-temporary connection descriptions, it may well find that the subnets
-specified by the initiator don't match those in the temporary
-connection description. If so, it will look for a connection with
-matching subnets, its own host address, a peer address of \fB%any\fP
-and matching identities.
-If it finds one, a new temporary connection is derived from this one
-and used for the Quick Mode negotiation of IPsec SAs. If it does not
-find one, \fBpluto\fP terminates negotiation.
-.LP
-Be sure to specify an appropriate nexthop for the responder
-to send a message to the initiator: \fBpluto\fP has no way of guessing
-it (if forwarding isn't required, use an explicit \fB%direct\fP as the nexthop
-and the IP address of the initiator will be filled in; the obsolete
-notation \fB0.0.0.0\fP is still accepted).
-.LP
-\fBpluto\fP has no special provision for the initiator side. The current
-(possibly dynamic) IP address and nexthop must be used in defining
-connections. These must be
-properly configured each time the initiator's IP address changes.
-\fBpluto\fP has no mechanism to do this automatically.
-.LP
-Although we call this Road Warrior Support, it could also be used to
-support encrypted connections with anonymous initiators. The
-responder's organization could announce the preshared secret that would be used
-with unrecognized initiators and let anyone connect. Of course the initiator's
-identity would not be authenticated.
-.LP
-If any Road Warrior connections are supported, \fBpluto\fP cannot
-reject an exchange initiated by an unknown host until it has
-determined that the secret is not shared or the signature is invalid.
-This must await the
-third Main Mode message from the initiator. If no Road Warrior
-connection is supported, the first message from an unknown source
-would be rejected. This has implications for ease of debugging
-configurations and for denial of service attacks.
-.LP
-Although a Road Warrior connection must be initiated by the mobile
-side, the other side can and will rekey using the temporary connection
-it has created. If the Road Warrior wishes to be able to disconnect,
-it is probably wise to set \fB\-\-keyingtries\fP to 1 in the
-connection on the non-mobile side to prevent it trying to rekey the
-connection. Unfortunately, there is no mechanism to unroute the
-connection automatically.
-.SS Debugging
-.LP
-\fBpluto\fP accepts several optional arguments, useful mostly for debugging.
-Except for \fB\-\-interface\fP, each should appear at most once.
-.TP
-\fB\-\-interface\fP \fIinterfacename\fP
-specifies that the named real public network interface should be considered.
-The interface name specified should not be \fBipsec\fP\fIN\fP.
-If the option doesn't appear, all interfaces are considered.
-To specify several interfaces, use the option once for each.
-One use of this option is to specify which interface should be used
-when two or more share the same IP address.
-.TP
-\fB\-\-ikeport\fP \fIport-number\fP
-changes the UDP port that \fBpluto\fP will use
-(default, specified by IANA: 500)
-.TP
-\fB\-\-ctlbase\fP \fIpath\fP
-basename for control files.
-\fIpath\fP.ctl is the socket through which \fBwhack\fP communicates with
-\fBpluto\fP.
-\fIpath\fP.pid is the lockfile to prevent multiple \fBpluto\fP instances.
-The default is \fI/var/run/pluto\fP).
-.TP
-\fB\-\-secretsfile\fP \fIfile\fP
-specifies the file for authentication secrets
-(default: \fI/etc/ipsec.secrets\fP).
-This name is subject to ``globbing'' as in \fIsh\fP(1),
-so every file with a matching name is processed.
-Quoting is generally needed to prevent the shell from doing the globbing.
-.TP
-\fB\-\-adns\fP \fIpathname\fP
-.TP
-\fB\-\-lwdnsq\fP \fIpathname\fP
-specifies where to find \fBpluto\fP's helper program for asynchronous DNS lookup.
-\fBpluto\fP can be built to use one of two helper programs: \fB_pluto_adns\fP
-or \fBlwdnsq\fP. You must use the program for which it was built.
-By default, \fBpluto\fP will look for the program in
-\fB$IPSEC_DIR\fP (if that environment variable is defined) or, failing that,
-in the same directory as \fBpluto\fP.
-.TP
-\fB\-\-nofork\fP
-disable ``daemon fork'' (default is to fork). In addition, after the
-lock file and control socket are created, print the line ``Pluto
-initialized'' to standard out.
-.TP
-\fB\-\-noklips\fP
-don't actually implement negotiated IPsec SAs
-.TP
-\fB\-\-uniqueids\fP
-if this option has been selected, whenever a new ISAKMP SA is
-established, any connection with the same Peer ID but a different
-Peer IP address is unoriented (causing all its SAs to be deleted).
-This helps clean up dangling SAs when a connection is lost and
-then regained at another IP address.
-.TP
-\fB\-\-stderrlog\fP
-log goes to standard out {default is to use \fIsyslogd\fP(8))
-.LP
-For example
-.TP
-pluto \-\-secretsfile\ ipsec.secrets \-\-ctlbase\ pluto.base \-\-ikeport\ 8500 \-\-nofork \-\-noklips \-\-stderrlog
-.LP
-lets one test \fBpluto\fP without using the superuser account.
-.LP
-\fBpluto\fP is willing to produce a prodigious amount of debugging
-information. To do so, it must be compiled with \-DDEBUG. There are
-several classes of debugging output, and \fBpluto\fP may be directed to
-produce a selection of them. All lines of
-debugging output are prefixed with ``|\ '' to distinguish them from error
-messages.
-.LP
-When \fBpluto\fP is invoked, it may be given arguments to specify
-which classes to output. The current options are:
-.TP
-\fB\-\-debug-raw\fP
-show the raw bytes of messages
-.TP
-\fB\-\-debug-crypt\fP
-show the encryption and decryption of messages
-.TP
-\fB\-\-debug-parsing\fP
-show the structure of input messages
-.TP
-\fB\-\-debug-emitting\fP
-show the structure of output messages
-.TP
-\fB\-\-debug-control\fP
-show \fBpluto\fP's decision making
-.TP
-\fB\-\-debug-lifecycle\fP
-[this option is temporary] log more detail of lifecycle of SAs
-.TP
-\fB\-\-debug-klips\fP
-show \fBpluto\fP's interaction with \fBKLIPS\fP
-.TP
-\fB\-\-debug-dns\fP
-show \fBpluto\fP's interaction with \fBDNS\fP for KEY and TXT records
-.TP
-\fB\-\-debug-oppo\fP
-show why \fBpluto\fP didn't find a suitable DNS TXT record to authorize opportunistic initiation
-.TP
-\fB\-\-debug-all\fP
-all of the above
-.TP
-\fB\-\-debug-private\fP
-allow debugging output with private keys.
-.TP
-\fB\-\-debug-none\fP
-none of the above
-.LP
-The debug form of the
-\fBwhack\fP command will change the selection in a running
-\fBpluto\fP.
-If a connection name is specified, the flags are added whenever
-\fBpluto\fP has identified that it is dealing with that connection.
-Unfortunately, this is often part way into the operation being observed.
-.LP
-For example, to start a \fBpluto\fP with a display of the structure of input
-and output:
-.IP
-pluto \-\-debug-emitting \-\-debug-parsing
-.LP
-To later change this \fBpluto\fP to only display raw bytes:
-.IP
-whack \-\-debug-raw
-.LP
-For testing, SSH's IKE test page is quite useful:
-.IP
-\fIhttp://isakmp-test.ssh.fi/\fP
-.LP
-Hint: ISAKMP SAs are often kept alive by IKEs even after the IPsec SA
-is established. This allows future IPsec SA's to be negotiated
-directly. If one of the IKEs is restarted, the other may try to use
-the ISAKMP SA but the new IKE won't know about it. This can lead to
-much confusion. \fBpluto\fP is not yet smart enough to get out of such a
-mess.
-.SS Pluto's Behaviour When Things Go Wrong
-.LP
-When \fBpluto\fP doesn't understand or accept a message, it just
-ignores the message. It is not yet capable of communicating the
-problem to the other IKE daemon (in the future it might use
-Notifications to accomplish this in many cases). It does log a diagnostic.
-.LP
-When \fBpluto\fP gets no response from a message, it resends the same
-message (a message will be sent at most three times). This is
-appropriate: UDP is unreliable.
-.LP
-When pluto gets a message that it has already seen, there are many
-cases when it notices and discards it. This too is appropriate for UDP.
-.LP
-Combine these three rules, and you can explain many apparently
-mysterious behaviours. In a \fBpluto\fP log, retrying isn't usually the
-interesting event. The critical thing is either earlier (\fBpluto\fP
-got a message which it didn't like and so ignored, so it was still
-awaiting an acceptable message and got impatient) or on the other
-system (\fBpluto\fP didn't send a reply because it wasn't happy with
-the previous message).
-.SS Notes
-.LP
-If \fBpluto\fP is compiled without \-DKLIPS, it negotiates Security
-Associations but never ask the kernel to put them in place and never
-makes routing changes. This allows \fBpluto\fP to be tested on systems
-without \fBKLIPS\fP, but makes it rather useless.
-.LP
-Each IPsec SA is assigned an SPI, a 32-bit number used to refer to the SA.
-The IKE protocol lets the destination of the SA choose the SPI.
-The range 0 to 0xFF is reserved for IANA.
-\fBPluto\fP also avoids choosing an SPI in the range 0x100 to 0xFFF,
-leaving these SPIs free for manual keying.
-Remember that the peer, if not \fBpluto\fP, may well chose
-SPIs in this range.
-.SS Policies
-.LP
-This catalogue of policies may be of use when trying to configure
-\fBPluto\fP and another IKE implementation to interoperate.
-.LP
-In Phase 1, only Main Mode is supported. We are not sure that
-Aggressive Mode is secure. For one thing, it does not support
-identity protection. It may allow more severe Denial Of Service
-attacks.
-.LP
-No Informational Exchanges are supported. These are optional and
-since their delivery is not assured, they must not matter.
-It is the case that some IKE implementations won't interoperate
-without Informational Exchanges, but we feel they are broken.
-.LP
-No Informational Payloads are supported. These are optional, but
-useful. It is of concern that these payloads are not authenticated in
-Phase 1, nor in those Phase 2 messages authenticated with HASH(3).
-.IP \(bu \w'\(bu\ 'u
-Diffie Hellman Groups MODP 1024 and MODP 1536 (2 and 5)
-are supported.
-Group MODP768 (1) is not supported because it is too weak.
-.IP \(bu
-Host authetication can be done by RSA Signatures or Pre-Shared
-Secrets.
-.IP \(bu
-3DES CBC (Cypher Block Chaining mode) is the only encryption
-supported, both for ISAKMP SAs and IPSEC SAs.
-.IP \(bu
-MD5 and SHA1 hashing are supported for packet authentication in both
-kinds of SAs.
-.IP \(bu
-The ESP, AH, or AH plus ESP are supported. If, and only if, AH and
-ESP are combined, the ESP need not have its own authentication
-component. The selection is controlled by the \-\-encrypt and
-\-\-authenticate flags.
-.IP \(bu
-Each of these may be combined with IPCOMP Deflate compression,
-but only if the potential connection specifies compression and only
-if KLIPS is configured with IPCOMP support.
-.IP \(bu
-The IPSEC SAs may be tunnel or transport mode, where appropriate.
-The \-\-tunnel flag controls this when \fBpluto\fP is initiating.
-.IP \(bu
-When responding to an ISAKMP SA proposal, the maximum acceptable
-lifetime is eight hours. The default is one hour. There is no
-minimum. The \-\-ikelifetime flag controls this when \fBpluto\fP
-is initiating.
-.IP \(bu
-When responding to an IPSEC SA proposal, the maximum acceptable
-lifetime is one day. The default is eight hours. There is no
-minimum. The \-\-ipseclifetime flag controls this when \fBpluto\fP
-is initiating.
-.IP \(bu
-PFS is acceptable, and will be proposed if the \-\-pfs flag was
-specified. The DH group proposed will be the same as negotiated for
-Phase 1.
-.SH SIGNALS
-.LP
-\fBPluto\fP responds to \fBSIGHUP\fP by issuing a suggestion that ``\fBwhack\fP
-\-\-listen'' might have been intended.
-.LP
-\fBPluto\fP exits when it recieves \fBSIGTERM\fP.
-.SH EXIT STATUS
-.LP
-\fBpluto\fP normally forks a daemon process, so the exit status is
-normally a very preliminary result.
-.TP
-0
-means that all is OK so far.
-.TP
-1
-means that something was wrong.
-.TP
-10
-means that the lock file already exists.
-.LP
-If \fBwhack\fP detects a problem, it will return an exit status of 1.
-If it received progress messages from \fBpluto\fP, it returns as status
-the value of the numeric prefix from the last such message
-that was not a message sent to syslog or a comment
-(but the prefix for success is treated as 0).
-Otherwise, the exit status is 0.
-.SH FILES
-\fI/var/run/pluto.pid\fP
-.br
-\fI/var/run/pluto.ctl\fP
-.br
-\fI/etc/ipsec.secrets\fP
-.br
-\fI$IPSEC_LIBDIR/_pluto_adns\fP
-.br
-\fI$IPSEC_EXECDIR/lwdnsq\fP
-.br
-\fI/dev/urandom\fP
-.SH ENVIRONMENT
-\fIIPSEC_LIBDIR\fP
-.br
-\fIIPSEC_EXECDIR\fP
-.br
-\fIIPSECmyid\fP
-.SH SEE ALSO
-.LP
-The rest of the FreeS/WAN distribution, in particular \fIipsec\fP(8).
-.LP
-\fIipsec_auto\fP(8) is designed to make using \fBpluto\fP more pleasant.
-Use it!
-.LP
-.IR ipsec.secrets (5)
-describes the format of the secrets file.
-.LP
-\fIipsec_atoaddr\fP(3), part of the FreeS/WAN distribution, describes the
-forms that IP addresses may take.
-\fIipsec_atosubnet\fP(3), part of the FreeS/WAN distribution, describes the
-forms that subnet specifications.
-.LP
-For more information on IPsec, the mailing list, and the relevant
-documents, see:
-.IP
-.nh
-\fIhttp://www.ietf.cnri.reston.va.us/html.charters/ipsec-charter.html\fP
-.hy
-.LP
-At the time of writing, the most relevant IETF RFCs are:
-.IP
-RFC2409 The Internet Key Exchange (IKE)
-.IP
-RFC2408 Internet Security Association and Key Management Protocol (ISAKMP)
-.IP
-RFC2407 The Internet IP Security Domain of Interpretation for ISAKMP
-.LP
-The FreeS/WAN web site <htp://www.freeswan.org>
-and the mailing lists described there.
-.SH HISTORY
-This code is released under the GPL terms.
-See the accompanying file COPYING-2.0 for more details.
-The GPL does NOT apply to those pieces of code written by others
-which are included in this distribution, except as noted by the
-individual authors.
-.LP
-This software was originally written
-for the FreeS/WAN project
-<http://www.freeswan.org>
-by Angelos D. Keromytis
-(angelos@dsl.cis.upenn.edu), in May/June 1997, in Athens, Greece.
-Thanks go to John Ioannidis for his help.
-.LP
-It is currently (2000)
-being developed and maintained by D. Hugh Redelmeier
-(hugh@mimosa.com), in Canada. The regulations of Greece and Canada
-allow us to make the code freely redistributable.
-.LP
-Kai Martius (admin@imib.med.tu-dresden.de) contributed the initial
-version of the code supporting PFS.
-.LP
-Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> and Peter Onion
-<ponion@srd.bt.co.uk> added the PFKEY2 support.
-.LP
-We gratefully acknowledge that we use parts of Eric Young's \fIlibdes\fP
-package; see \fI../libdes/COPYRIGHT\fP.
-.SH BUGS
-.BR pluto
-is a work-in-progress. It currently has many limitations.
-For example, it ignores notification messages that it receives, and
-it generates only Delete Notifications and those only for IPSEC SAs.
-.LP
-\fBpluto\fP does not support the Commit Flag.
-The Commit Flag is a bad feature of the IKE protocol.
-It isn't protected -- neither encrypted nor authenticated.
-A man in the middle could turn it on, leading to DoS.
-We just ignore it, with a warning.
-This should let us interoperate with
-implementations that insist on it, with minor damage.
-.LP
-\fBpluto\fP does not check that the SA returned by the Responder
-is actually one that was proposed. It only checks that the SA is
-acceptable. The difference is not large, but can show up in attributes
-such as SA lifetime.
-.LP
-There is no good way for a connection to be automatically terminated.
-This is a problem for Road Warrior and Opportunistic connections.
-The \fB\-\-dontrekey\fP option does prevent the SAs from
-being rekeyed on expiry.
-Additonally, if a Road Warrior connection has a client subnet with a fixed IP
-address, a negotiation with that subnet will cause any other
-connection instantiations with that same subnet to be unoriented
-(deleted, in effect).
-See also the \-\-uniqueids option for an extension of this.
-.LP
-When \fBpluto\fP sends a message to a peer that has disappeared,
-\fBpluto\fP receives incomplete information from the kernel, so it
-logs the unsatisfactory message ``some IKE message we sent has been
-rejected with ECONNREFUSED (kernel supplied no details)''. John
-Denker suggests that this command is useful for tracking down the
-source of these problems:
-.br
- tcpdump -i eth0 icmp[0] != 8 and icmp[0] != 0
-.br
-Substitute your public interface for eth0 if it is different.
-.LP
-The word ``authenticate'' is used for two different features. We must
-authenticate each IKE peer to the other. This is an important task of
-Phase 1. Each packet must be authenticated, both in IKE and in IPsec,
-and the method for IPsec is negotiated as an AH SA or part of an ESP SA.
-Unfortunately, the protocol has no mechanism for authenticating the Phase 2
-identities.
-.LP
-Bugs should be reported to the <users@lists.freeswan.org> mailing list.
-Caution: we cannot accept
-actual code from US residents, or even US citizens living outside the
-US, because that would bring FreeS/WAN under US export law. Some
-other countries cause similar problems. In general, we would prefer
-that you send detailed problem reports rather than code: we want
-FreeS/WAN to be unquestionably freely exportable, which means being
-very careful about where the code comes from, and for a small bug fix,
-that is often more time-consuming than just reinventing the fix
-ourselves.
diff --git a/programs/pluto/plutomain.c b/programs/pluto/plutomain.c
deleted file mode 100644
index d7e9d8a2c..000000000
--- a/programs/pluto/plutomain.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/* Pluto main program
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: plutomain.c,v 1.19 2007/01/29 08:27:19 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "id.h"
-#include "ca.h"
-#include "certs.h"
-#include "ac.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "packet.h"
-#include "demux.h" /* needs packet.h */
-#include "server.h"
-#include "kernel.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "rnd.h"
-#include "state.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "ocsp.h"
-#include "crl.h"
-#include "fetch.h"
-#include "xauth.h"
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-
-#ifdef VIRTUAL_IP
-#include "virtual.h"
-#endif
-
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-static void
-usage(const char *mess)
-{
- if (mess != NULL && *mess != '\0')
- fprintf(stderr, "%s\n", mess);
- fprintf(stderr
- , "Usage: pluto"
- " [--help]"
- " [--version]"
- " [--optionsfrom <filename>]"
- " \\\n\t"
- "[--nofork]"
- " [--stderrlog]"
- " [--noklips]"
- " [--nocrsend]"
- " \\\n\t"
- "[--strictcrlpolicy]"
- " [--crlcheckinterval]"
- " [--cachecrls]"
- " [--uniqueids]"
- " \\\n\t"
- "[--interface <ifname>]"
- " [--ikeport <port-number>]"
- " \\\n\t"
- "[--ctlbase <path>]"
- " \\\n\t"
- "[--perpeerlogbase <path>] [--perpeerlog]"
- " \\\n\t"
- "[--secretsfile <secrets-file>]"
- " [--policygroupsdir <policygroups-dir>]"
- " \\\n\t"
- "[--adns <pathname>]"
- "[--pkcs11module <path>]"
- "[--pkcs11keepstate"
-#ifdef DEBUG
- " \\\n\t"
- "[--debug-none]"
- " [--debug-all]"
- " \\\n\t"
- "[--debug-raw]"
- " [--debug-crypt]"
- " [--debug-parsing]"
- " [--debug-emitting]"
- " \\\n\t"
- "[--debug-control]"
- " [--debug-lifecycle]"
- " [--debug-klips]"
- " [--debug-dns]"
- " \\\n\t"
- "[--debug-oppo]"
- " [--debug-controlmore]"
- " [--debug-private]"
-#endif
-#ifdef NAT_TRAVERSAL
- " [ --debug-natt]"
- " \\\n\t"
- "[--nat_traversal] [--keep_alive <delay_sec>]"
- " \\\n\t"
- "[--force_keepalive] [--disable_port_floating]"
-#endif
-#ifdef VIRTUAL_IP
- " \\\n\t"
- "[--virtual_private <network_list>]"
-#endif
- "\n"
- "strongSwan %s\n"
- , ipsec_version_code());
- exit_pluto(mess == NULL? 0 : 1);
-}
-
-
-/* lock file support
- * - provides convenient way for scripts to find Pluto's pid
- * - prevents multiple Plutos competing for the same port
- * - same basename as unix domain control socket
- * NOTE: will not take account of sharing LOCK_DIR with other systems.
- */
-
-static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
-static bool pluto_lock_created = FALSE;
-
-/* create lockfile, or die in the attempt */
-static int
-create_lock(void)
-{
- int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
- , S_IRUSR | S_IRGRP | S_IROTH);
-
- if (fd < 0)
- {
- if (errno == EEXIST)
- {
- fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
- , pluto_lock);
- exit_pluto(10);
- }
- else
- {
- fprintf(stderr
- , "pluto: unable to create lock file \"%s\" (%d %s)\n"
- , pluto_lock, errno, strerror(errno));
- exit_pluto(1);
- }
- }
- pluto_lock_created = TRUE;
- return fd;
-}
-
-static bool
-fill_lock(int lockfd, pid_t pid)
-{
- char buf[30]; /* holds "<pid>\n" */
- int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
- bool ok = len > 0 && write(lockfd, buf, len) == len;
-
- close(lockfd);
- return ok;
-}
-
-static void
-delete_lock(void)
-{
- if (pluto_lock_created)
- {
- delete_ctl_socket();
- unlink(pluto_lock); /* is noting failure useful? */
- }
-}
-
-/* by default pluto sends certificate requests to its peers */
-bool no_cr_send = FALSE;
-
-/* by default the CRL policy is lenient */
-bool strict_crl_policy = FALSE;
-
-/* by default CRLs are cached locally as files */
-bool cache_crls = FALSE;
-
-/* by default pluto does not check crls dynamically */
-long crl_check_interval = 0;
-
-/* path to the PKCS#11 module */
-char *pkcs11_module_path = NULL;
-
-/* by default pluto logs out after every smartcard use */
-bool pkcs11_keep_state = FALSE;
-
-/* by default pluto does not allow pkcs11 proxy access via whack */
-bool pkcs11_proxy = FALSE;
-
-int
-main(int argc, char **argv)
-{
- bool fork_desired = TRUE;
- bool log_to_stderr_desired = FALSE;
-#ifdef NAT_TRAVERSAL
- bool nat_traversal = FALSE;
- bool nat_t_spf = TRUE; /* support port floating */
- unsigned int keep_alive = 0;
- bool force_keepalive = FALSE;
-#endif
-#ifdef VIRTUAL_IP
- char *virtual_private = NULL;
-#endif
- int lockfd;
-
- /* handle arguments */
- for (;;)
- {
-# define DBG_OFFSET 256
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "nofork", no_argument, NULL, 'd' },
- { "stderrlog", no_argument, NULL, 'e' },
- { "noklips", no_argument, NULL, 'n' },
- { "nocrsend", no_argument, NULL, 'c' },
- { "strictcrlpolicy", no_argument, NULL, 'r' },
- { "crlcheckinterval", required_argument, NULL, 'x'},
- { "cachecrls", no_argument, NULL, 'C' },
- { "uniqueids", no_argument, NULL, 'u' },
- { "interface", required_argument, NULL, 'i' },
- { "ikeport", required_argument, NULL, 'p' },
- { "ctlbase", required_argument, NULL, 'b' },
- { "secretsfile", required_argument, NULL, 's' },
- { "foodgroupsdir", required_argument, NULL, 'f' },
- { "perpeerlogbase", required_argument, NULL, 'P' },
- { "perpeerlog", no_argument, NULL, 'l' },
- { "policygroupsdir", required_argument, NULL, 'f' },
-#ifdef USE_LWRES
- { "lwdnsq", required_argument, NULL, 'a' },
-#else /* !USE_LWRES */
- { "adns", required_argument, NULL, 'a' },
-#endif /* !USE_LWRES */
- { "pkcs11module", required_argument, NULL, 'm' },
- { "pkcs11keepstate", no_argument, NULL, 'k' },
- { "pkcs11proxy", no_argument, NULL, 'y' },
-#ifdef NAT_TRAVERSAL
- { "nat_traversal", no_argument, NULL, '1' },
- { "keep_alive", required_argument, NULL, '2' },
- { "force_keepalive", no_argument, NULL, '3' },
- { "disable_port_floating", no_argument, NULL, '4' },
- { "debug-natt", no_argument, NULL, '5' },
-#endif
-#ifdef VIRTUAL_IP
- { "virtual_private", required_argument, NULL, '6' },
-#endif
-#ifdef DEBUG
- { "debug-none", no_argument, NULL, 'N' },
- { "debug-all", no_argument, NULL, 'A' },
-
- { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
- { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
- { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
- { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
- { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
- { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
- { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
- { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
- { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
- { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
- { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
-
- { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
- { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
- { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
- { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
-#endif
- { 0,0,0,0 }
- };
- /* Note: we don't like the way short options get parsed
- * by getopt_long, so we simply pass an empty string as
- * the list. It could be "hvdenp:l:s:" "NARXPECK".
- */
- int c = getopt_long(argc, argv, "", long_opts, NULL);
-
- /* Note: "breaking" from case terminates loop */
- switch (c)
- {
- case EOF: /* end of flags */
- break;
-
- case 0: /* long option already handled */
- continue;
-
- case ':': /* diagnostic already printed by getopt_long */
- case '?': /* diagnostic already printed by getopt_long */
- usage("");
- break; /* not actually reached */
-
- case 'h': /* --help */
- usage(NULL);
- break; /* not actually reached */
-
- case 'v': /* --version */
- {
- const char **sp = ipsec_copyright_notice();
-
- printf("%s%s\n", ipsec_version_string(),
- compile_time_interop_options);
- for (; *sp != NULL; sp++)
- puts(*sp);
- }
- exit_pluto(0);
- break; /* not actually reached */
-
- case '+': /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- case 'd': /* --nofork*/
- fork_desired = FALSE;
- continue;
-
- case 'e': /* --stderrlog */
- log_to_stderr_desired = TRUE;
- continue;
-
- case 'n': /* --noklips */
- no_klips = TRUE;
- continue;
-
- case 'c': /* --nocrsend */
- no_cr_send = TRUE;
- continue;
-
- case 'r': /* --strictcrlpolicy */
- strict_crl_policy = TRUE;
- continue;
-
- case 'x': /* --crlcheckinterval <time>*/
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing interval time");
-
- {
- char *endptr;
- long interval = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || interval <= 0)
- usage("<interval-time> must be a positive number");
- crl_check_interval = interval;
- }
- continue;
-
- case 'C': /* --cachecrls */
- cache_crls = TRUE;
- continue;
-
- case 'u': /* --uniqueids */
- uniqueIDs = TRUE;
- continue;
-
- case 'i': /* --interface <ifname> */
- if (!use_interface(optarg))
- usage("too many --interface specifications");
- continue;
-
- case 'p': /* --port <portnumber> */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing port number");
-
- {
- char *endptr;
- long port = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || port <= 0 || port > 0x10000)
- usage("<port-number> must be a number between 1 and 65535");
- pluto_port = port;
- }
- continue;
-
- case 'b': /* --ctlbase <path> */
- if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
- , "%s%s", optarg, CTL_SUFFIX) == -1)
- usage("<path>" CTL_SUFFIX " too long for sun_path");
- if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
- , "%s%s", optarg, INFO_SUFFIX) == -1)
- usage("<path>" INFO_SUFFIX " too long for sun_path");
- if (snprintf(pluto_lock, sizeof(pluto_lock)
- , "%s%s", optarg, LOCK_SUFFIX) == -1)
- usage("<path>" LOCK_SUFFIX " must fit");
- continue;
-
- case 's': /* --secretsfile <secrets-file> */
- shared_secrets_file = optarg;
- continue;
-
- case 'f': /* --policygroupsdir <policygroups-dir> */
- policygroups_dir = optarg;
- continue;
-
- case 'a': /* --adns <pathname> */
- pluto_adns_option = optarg;
- continue;
-
- case 'm': /* --pkcs11module <pathname> */
- pkcs11_module_path = optarg;
- continue;
-
- case 'k': /* --pkcs11keepstate */
- pkcs11_keep_state = TRUE;
- continue;
-
- case 'y': /* --pkcs11proxy */
- pkcs11_proxy = TRUE;
- continue;
-
-#ifdef DEBUG
- case 'N': /* --debug-none */
- base_debugging = DBG_NONE;
- continue;
-
- case 'A': /* --debug-all */
- base_debugging = DBG_ALL;
- continue;
-#endif
-
- case 'P': /* --perpeerlogbase */
- base_perpeer_logdir = optarg;
- continue;
-
- case 'l':
- log_to_perpeer = TRUE;
- continue;
-
-#ifdef NAT_TRAVERSAL
- case '1': /* --nat_traversal */
- nat_traversal = TRUE;
- continue;
- case '2': /* --keep_alive */
- keep_alive = atoi(optarg);
- continue;
- case '3': /* --force_keepalive */
- force_keepalive = TRUE;
- continue;
- case '4': /* --disable_port_floating */
- nat_t_spf = FALSE;
- continue;
- case '5': /* --debug-nat_t */
- base_debugging |= DBG_NATT;
- continue;
-#endif
-#ifdef VIRTUAL_IP
- case '6': /* --virtual_private */
- virtual_private = optarg;
- continue;
-#endif
-
- default:
-#ifdef DEBUG
- if (c >= DBG_OFFSET)
- {
- base_debugging |= c - DBG_OFFSET;
- continue;
- }
-# undef DBG_OFFSET
-#endif
- bad_case(c);
- }
- break;
- }
- if (optind != argc)
- usage("unexpected argument");
- reset_debugging();
- lockfd = create_lock();
-
- /* select between logging methods */
-
- if (log_to_stderr_desired)
- log_to_syslog = FALSE;
- else
- log_to_stderr = FALSE;
-
- /* set the logging function of pfkey debugging */
-#ifdef DEBUG
- pfkey_debug_func = DBG_log;
-#else
- pfkey_debug_func = NULL;
-#endif
-
- /* create control socket.
- * We must create it before the parent process returns so that
- * there will be no race condition in using it. The easiest
- * place to do this is before the daemon fork.
- */
- {
- err_t ugh = init_ctl_socket();
-
- if (ugh != NULL)
- {
- fprintf(stderr, "pluto: %s", ugh);
- exit_pluto(1);
- }
- }
-
- /* If not suppressed, do daemon fork */
-
- if (fork_desired)
- {
- {
- pid_t pid = fork();
-
- if (pid < 0)
- {
- int e = errno;
-
- fprintf(stderr, "pluto: fork failed (%d %s)\n",
- errno, strerror(e));
- exit_pluto(1);
- }
-
- if (pid != 0)
- {
- /* parent: die, after filling PID into lock file.
- * must not use exit_pluto: lock would be removed!
- */
- exit(fill_lock(lockfd, pid)? 0 : 1);
- }
- }
-
- if (setsid() < 0)
- {
- int e = errno;
-
- fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
- errno, strerror(e));
- exit_pluto(1);
- }
- }
- else
- {
- /* no daemon fork: we have to fill in lock file */
- (void) fill_lock(lockfd, getpid());
- fprintf(stdout, "Pluto initialized\n");
- fflush(stdout);
- }
-
- /* Close everything but ctl_fd and (if needed) stderr.
- * There is some danger that a library that we don't know
- * about is using some fd that we don't know about.
- * I guess we'll soon find out.
- */
- {
- int i;
-
- for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
- {
- if ((!log_to_stderr || i != 2) && i != ctl_fd)
- close(i);
- }
-
- /* make sure that stdin, stdout, stderr are reserved */
- if (open("/dev/null", O_RDONLY) != 0)
- abort();
- if (dup2(0, 1) != 1)
- abort();
- if (!log_to_stderr && dup2(0, 2) != 2)
- abort();
- }
-
- init_constants();
- init_log("pluto");
-
- /* Note: some scripts may look for this exact message -- don't change
- * ipsec barf was one, but it no longer does.
- */
- plog("Starting Pluto (strongSwan Version %s%s)"
- , ipsec_version_code()
- , compile_time_interop_options);
-
-#ifdef NAT_TRAVERSAL
- init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
-#endif
-
-#ifdef VIRTUAL_IP
- init_virtual_ip(virtual_private);
-#endif
- scx_init(pkcs11_module_path); /* load and initialize PKCS #11 module */
- xauth_init(); /* load and initialize XAUTH module */
- init_rnd_pool();
- init_secret();
- init_states();
- init_crypto();
- init_demux();
- init_kernel();
- init_adns();
- init_id();
- init_fetch();
-
- /* loading X.509 CA certificates */
- load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
- /* loading X.509 AA certificates */
- load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
- /* loading X.509 OCSP certificates */
- load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
- /* loading X.509 CRLs */
- load_crls();
- /* loading attribute certificates (experimental) */
- load_acerts();
-
- daily_log_event();
- call_server();
- return -1; /* Shouldn't ever reach this */
-}
-
-/* leave pluto, with status.
- * Once child is launched, parent must not exit this way because
- * the lock would be released.
- *
- * 0 OK
- * 1 general discomfort
- * 10 lock file exists
- */
-void
-exit_pluto(int status)
-{
- reset_globals(); /* needed because we may be called in odd state */
- free_preshared_secrets();
- free_remembered_public_keys();
- delete_every_connection();
- free_crl_fetch(); /* free chain of crl fetch requests */
- free_ocsp_fetch(); /* free chain of ocsp fetch requests */
- free_authcerts(); /* free chain of X.509 authority certificates */
- free_crls(); /* free chain of X.509 CRLs */
- free_acerts(); /* free chain of X.509 attribute certificates */
- free_ca_infos(); /* free chain of X.509 CA information records */
- free_ocsp(); /* free ocsp cache */
- free_ifaces();
- scx_finalize(); /* finalize and unload PKCS #11 module */
- xauth_finalize(); /* finalize and unload XAUTH module */
- stop_adns();
- free_md_pool();
- delete_lock();
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- exit(status);
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/programs/pluto/primegen.c b/programs/pluto/primegen.c
deleted file mode 100644
index 159490345..000000000
--- a/programs/pluto/primegen.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/* primegen.c - prime number generator
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * ***********************************************************************
- * The algorithm used to generate practically save primes is due to
- * Lim and Lee as described in the CRYPTO '97 proceedings (ISBN3540633847)
- * page 260.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <assert.h> */
-/* #include <config.h> */
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif /* !PLUTO */
-
-static int no_of_small_prime_numbers;
-static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
-static int check_prime( MPI prime, MPI val_2 );
-static int is_prime( MPI n, unsigned steps, int *count );
-static void m_out_of_n( char *array, int m, int n );
-
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-/****************
- * Generate a prime number (stored in secure memory)
- */
-MPI
-generate_secret_prime( unsigned nbits )
-{
- MPI prime;
-
- prime = gen_prime( nbits, 1, 2 );
- progress('\n');
- return prime;
-}
-
-MPI
-generate_public_prime( unsigned nbits )
-{
- MPI prime;
-
- prime = gen_prime( nbits, 0, 2 );
- progress('\n');
- return prime;
-}
-
-
-/****************
- * We do not need to use the strongest RNG because we gain no extra
- * security from it - The prime number is public and we could also
- * offer the factors for those who are willing to check that it is
- * indeed a strong prime.
- *
- * mode 0: Standard
- * 1: Make sure that at least one factor is of size qbits.
- */
-MPI
-generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
- MPI g, MPI **ret_factors )
-{
- int n; /* number of factors */
- int m; /* number of primes in pool */
- unsigned fbits; /* length of prime factors */
- MPI *factors; /* current factors */
- MPI *pool; /* pool of primes */
- MPI q; /* first prime factor (variable)*/
- MPI prime; /* prime test value */
- MPI q_factor; /* used for mode 1 */
- byte *perms = NULL;
- int i, j;
- int count1, count2;
- unsigned nprime;
- unsigned req_qbits = qbits; /* the requested q bits size */
- MPI val_2 = mpi_alloc_set_ui( 2 );
-
- /* find number of needed prime factors */
- for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
- ;
- n--;
- if( !n || (mode==1 && n < 2) )
- log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
- if( mode == 1 ) {
- n--;
- fbits = (pbits - 2*req_qbits -1) / n;
- qbits = pbits - req_qbits - n*fbits;
- }
- else {
- fbits = (pbits - req_qbits -1) / n;
- qbits = pbits - n*fbits;
- }
- if( DBG_CIPHER )
- log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
- pbits, req_qbits, qbits, fbits, n );
- prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
- q = gen_prime( qbits, 0, 1 );
- q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
-
- /* allocate an array to hold the factors + 2 for later usage */
-#ifdef PLUTO
- m_alloc_ptrs_clear(factors, n+2);
-#else
- factors = m_alloc_clear( (n+2) * sizeof *factors );
-#endif
-
- /* make a pool of 3n+5 primes (this is an arbitrary value) */
- m = n*3+5;
- if( mode == 1 )
- m += 5; /* need some more for DSA */
- if( m < 25 )
- m = 25;
-#ifdef PLUTO
- m_alloc_ptrs_clear(pool, m);
-#else
- pool = m_alloc_clear( m * sizeof *pool );
-#endif
-
- /* permutate over the pool of primes */
- count1=count2=0;
- do {
- next_try:
- if( !perms ) {
- /* allocate new primes */
- for(i=0; i < m; i++ ) {
- mpi_free(pool[i]);
- pool[i] = NULL;
- }
- /* init m_out_of_n() */
-#ifdef PLUTO
- perms = alloc_bytes( m, "perms" );
-#else
- perms = m_alloc_clear( m );
-#endif
- for(i=0; i < n; i++ ) {
- perms[i] = 1;
- pool[i] = gen_prime( fbits, 0, 1 );
- factors[i] = pool[i];
- }
- }
- else {
- m_out_of_n( perms, n, m );
- for(i=j=0; i < m && j < n ; i++ )
- if( perms[i] ) {
- if( !pool[i] )
- pool[i] = gen_prime( fbits, 0, 1 );
- factors[j++] = pool[i];
- }
- if( i == n ) {
- m_free(perms); perms = NULL;
- progress('!');
- goto next_try; /* allocate new primes */
- }
- }
-
- mpi_set( prime, q );
- mpi_mul_ui( prime, prime, 2 );
- if( mode == 1 )
- mpi_mul( prime, prime, q_factor );
- for(i=0; i < n; i++ )
- mpi_mul( prime, prime, factors[i] );
- mpi_add_ui( prime, prime, 1 );
- nprime = mpi_get_nbits(prime);
- if( nprime < pbits ) {
- if( ++count1 > 20 ) {
- count1 = 0;
- qbits++;
- progress('>');
- q = gen_prime( qbits, 0, 1 );
- goto next_try;
- }
- }
- else
- count1 = 0;
- if( nprime > pbits ) {
- if( ++count2 > 20 ) {
- count2 = 0;
- qbits--;
- progress('<');
- q = gen_prime( qbits, 0, 1 );
- goto next_try;
- }
- }
- else
- count2 = 0;
- } while( !(nprime == pbits && check_prime( prime, val_2 )) );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump( "prime : ", prime );
- log_mpidump( "factor q: ", q );
- if( mode == 1 )
- log_mpidump( "factor q0: ", q_factor );
- for(i=0; i < n; i++ )
- log_mpidump( "factor pi: ", factors[i] );
- log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
- if( mode == 1 )
- fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
- for(i=0; i < n; i++ )
- fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
- progress('\n');
- }
-
- if( ret_factors ) { /* caller wants the factors */
-#ifdef PLUTO
- m_alloc_ptrs_clear(*ret_factors, n+2);
-#else
- *ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
-#endif
- if( mode == 1 ) {
- i = 0;
- (*ret_factors)[i++] = mpi_copy( q_factor );
- for(; i <= n; i++ )
- (*ret_factors)[i] = mpi_copy( factors[i] );
- }
- else {
- for(; i < n; i++ )
- (*ret_factors)[i] = mpi_copy( factors[i] );
- }
- }
-
- if( g ) { /* create a generator (start with 3)*/
- MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
- MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
- MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
-
- if( mode == 1 )
- BUG(); /* not yet implemented */
- factors[n] = q;
- factors[n+1] = mpi_alloc_set_ui(2);
- mpi_sub_ui( pmin1, prime, 1 );
- mpi_set_ui(g,2);
- do {
- mpi_add_ui(g, g, 1);
- if( DBG_CIPHER ) {
-#ifdef PLUTO
- log_mpidump("checking g: ", g);
-#else
- log_debug("checking g: ");
- mpi_print( stderr, g, 1 );
-#endif
- }
- else
- progress('^');
- for(i=0; i < n+2; i++ ) {
- /*fputc('~', stderr);*/
- mpi_fdiv_q(tmp, pmin1, factors[i] );
- /* (no mpi_pow(), but it is okay to use this with mod prime) */
- mpi_powm(b, g, tmp, prime );
- if( !mpi_cmp_ui(b, 1) )
- break;
- }
- if( DBG_CIPHER )
- progress('\n');
- } while( i < n+2 );
- mpi_free(factors[n+1]);
- mpi_free(tmp);
- mpi_free(b);
- mpi_free(pmin1);
- }
- if( !DBG_CIPHER )
- progress('\n');
-
- m_free( factors ); /* (factors are shallow copies) */
- for(i=0; i < m; i++ )
- mpi_free( pool[i] );
- m_free( pool );
- m_free(perms);
- mpi_free(val_2);
- return prime;
-}
-
-
-
-static MPI
-gen_prime( unsigned nbits, int secret, int randomlevel )
-{
- unsigned nlimbs;
- MPI prime, ptest, pminus1, val_2, val_3, result;
- int i;
- unsigned x, step;
- unsigned count1, count2;
- int *mods;
-
- if( 0 && DBG_CIPHER )
- log_debug("generate a prime of %u bits ", nbits );
-
- if( !no_of_small_prime_numbers ) {
- for(i=0; small_prime_numbers[i]; i++ )
- no_of_small_prime_numbers++;
- }
- mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
- /* make nbits fit into MPI implementation */
- nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
- val_2 = mpi_alloc_set_ui( 2 );
- val_3 = mpi_alloc_set_ui( 3);
- prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
- result = mpi_alloc_like( prime );
- pminus1= mpi_alloc_like( prime );
- ptest = mpi_alloc_like( prime );
- count1 = count2 = 0;
- for(;;) { /* try forvever */
- int dotcount=0;
-
- /* generate a random number */
- { char *p = get_random_bits( nbits, randomlevel, secret );
- mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
- m_free(p);
- }
-
- /* set high order bit to 1, set low order bit to 1 */
- mpi_set_highbit( prime, nbits-1 );
- mpi_set_bit( prime, 0 );
-
- /* calculate all remainders */
- for(i=0; (x = small_prime_numbers[i]); i++ )
- mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
-
- /* now try some primes starting with prime */
- for(step=0; step < 20000; step += 2 ) {
- /* check against all the small primes we have in mods */
- count1++;
- for(i=0; (x = small_prime_numbers[i]); i++ ) {
- while( mods[i] + step >= x )
- mods[i] -= x;
- if( !(mods[i] + step) )
- break;
- }
- if( x )
- continue; /* found a multiple of an already known prime */
-
- mpi_add_ui( ptest, prime, step );
-
- /* do a faster Fermat test */
- count2++;
- mpi_sub_ui( pminus1, ptest, 1);
- mpi_powm( result, val_2, pminus1, ptest );
- if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
- /* perform stronger tests */
- if( is_prime(ptest, 5, &count2 ) ) {
- if( !mpi_test_bit( ptest, nbits-1 ) ) {
- progress('\n');
- log_debug("overflow in prime generation\n");
- break; /* step loop, continue with a new prime */
- }
-
- mpi_free(val_2);
- mpi_free(val_3);
- mpi_free(result);
- mpi_free(pminus1);
- mpi_free(prime);
- m_free(mods);
- return ptest;
- }
- }
- if( ++dotcount == 10 ) {
- progress('.');
- dotcount = 0;
- }
- }
- progress(':'); /* restart with a new random value */
- }
-}
-
-/****************
- * Returns: true if this may be a prime
- */
-static int
-check_prime( MPI prime, MPI val_2 )
-{
- int i;
- unsigned x;
- int count=0;
-
- /* check against small primes */
- for(i=0; (x = small_prime_numbers[i]); i++ ) {
- if( mpi_divisible_ui( prime, x ) )
- return 0;
- }
-
- /* a quick fermat test */
- {
- MPI result = mpi_alloc_like( prime );
- MPI pminus1 = mpi_alloc_like( prime );
- mpi_sub_ui( pminus1, prime, 1);
- mpi_powm( result, val_2, pminus1, prime );
- mpi_free( pminus1 );
- if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
- mpi_free( result );
- progress('.');
- return 0;
- }
- mpi_free( result );
- }
-
- /* perform stronger tests */
- if( is_prime(prime, 5, &count ) )
- return 1; /* is probably a prime */
- progress('.');
- return 0;
-}
-
-
-/****************
- * Return true if n is probably a prime
- */
-static int
-is_prime( MPI n, unsigned steps, int *count )
-{
- MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI a2 = mpi_alloc_set_ui( 2 );
- MPI q;
- unsigned i, j, k;
- int rc = 0;
- unsigned nbits = mpi_get_nbits( n );
-
- mpi_sub_ui( nminus1, n, 1 );
-
- /* find q and k, so that n = 1 + 2^k * q */
- q = mpi_copy( nminus1 );
- k = mpi_trailing_zeros( q );
- mpi_tdiv_q_2exp(q, q, k);
-
- for(i=0 ; i < steps; i++ ) {
- ++*count;
- if( !i ) {
- mpi_set_ui( x, 2 );
- }
- else {
- /*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
- { char *p = get_random_bits( nbits, 0, 0 );
- mpi_set_buffer( x, p, (nbits+7)/8, 0 );
- m_free(p);
- }
- /* make sure that the number is smaller than the prime
- * and keep the randomness of the high bit */
- if( mpi_test_bit( x, nbits-2 ) ) {
- mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
- }
- else {
- mpi_set_highbit( x, nbits-2 );
- mpi_clear_bit( x, nbits-2 );
- }
- assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
- }
- mpi_powm( y, x, q, n);
- if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
- for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
- mpi_powm(y, y, a2, n);
- if( !mpi_cmp_ui( y, 1 ) )
- goto leave; /* not a prime */
- }
- if( mpi_cmp( y, nminus1 ) )
- goto leave; /* not a prime */
- }
- progress('+');
- }
- rc = 1; /* may be a prime */
-
- leave:
- mpi_free( x );
- mpi_free( y );
- mpi_free( z );
- mpi_free( nminus1 );
- mpi_free( q );
-
- return rc;
-}
-
-
-static void
-m_out_of_n( char *array, int m, int n )
-{
- int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
-
- if( !m || m >= n )
- return;
-
- if( m == 1 ) { /* special case */
- for(i=0; i < n; i++ )
- if( array[i] ) {
- array[i++] = 0;
- if( i >= n )
- i = 0;
- array[i] = 1;
- return;
- }
- BUG();
- }
-
- for(j=1; j < n; j++ ) {
- if( array[n-1] == array[n-j-1] )
- continue;
- j1 = j;
- break;
- }
-
- if( m & 1 ) { /* m is odd */
- if( array[n-1] ) {
- if( j1 & 1 ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- goto scan;
- }
- k2 = n - j1 - 1;
- if( k2 == 0 ) {
- k1 = i;
- k2 = n - j1;
- }
- else if( array[k2] && array[k2-1] )
- k1 = n;
- else
- k1 = k2 + 1;
- }
- else { /* m is even */
- if( !array[n-1] ) {
- k1 = n - j1;
- k2 = k1 + 1;
- goto leave;
- }
-
- if( !(j1 & 1) ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- scan:
- jp = n - j1 - 1;
- for(i=1; i <= jp; i++ ) {
- i1 = jp + 2 - i;
- if( array[i1-1] ) {
- if( array[i1-2] ) {
- k1 = i1 - 1;
- k2 = n - j1;
- }
- else {
- k1 = i1 - 1;
- k2 = n + 1 - j1;
- }
- goto leave;
- }
- }
- k1 = 1;
- k2 = n + 1 - m;
- }
- leave:
- array[k1-1] = !array[k1-1];
- array[k2-1] = !array[k2-1];
-}
-
diff --git a/programs/pluto/rcv_whack.c b/programs/pluto/rcv_whack.c
deleted file mode 100644
index 99c377765..000000000
--- a/programs/pluto/rcv_whack.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/* whack communicating routines
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rcv_whack.c,v 1.18 2006/05/25 11:33:57 as Exp $
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "id.h"
-#include "ca.h"
-#include "certs.h"
-#include "ac.h"
-#include "smartcard.h"
-#include "connections.h"
-#include "foodgroups.h"
-#include "whack.h" /* needs connections.h */
-#include "packet.h"
-#include "demux.h" /* needs packet.h */
-#include "state.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "kernel.h"
-#include "rcv_whack.h"
-#include "log.h"
-#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "server.h"
-#include "fetch.h"
-#include "ocsp.h"
-#include "crl.h"
-
-#include "kernel_alg.h"
-#include "ike_alg.h"
-/* helper variables and function to decode strings from whack message */
-
-static char *next_str
- , *str_roof;
-
-static bool
-unpack_str(char **p)
-{
- char *end = memchr(next_str, '\0', str_roof - next_str);
-
- if (end == NULL)
- {
- return FALSE; /* fishy: no end found */
- }
- else
- {
- *p = next_str == end? NULL : next_str;
- next_str = end + 1;
- return TRUE;
- }
-}
-
-/* bits loading keys from asynchronous DNS */
-
-enum key_add_attempt {
- ka_TXT,
-#ifdef USE_KEYRR
- ka_KEY,
-#endif
- ka_roof /* largest value + 1 */
-};
-
-struct key_add_common {
- int refCount;
- char *diag[ka_roof];
- int whack_fd;
- bool success;
-};
-
-struct key_add_continuation {
- struct adns_continuation ac; /* common prefix */
- struct key_add_common *common; /* common data */
- enum key_add_attempt lookingfor;
-};
-
-static void
-key_add_ugh(const struct id *keyid, err_t ugh)
-{
- char name[BUF_LEN]; /* longer IDs will be truncated in message */
-
- (void)idtoa(keyid, name, sizeof(name));
- loglog(RC_NOKEY
- , "failure to fetch key for %s from DNS: %s", name, ugh);
-}
-
-/* last one out: turn out the lights */
-static void
-key_add_merge(struct key_add_common *oc, const struct id *keyid)
-{
- if (oc->refCount == 0)
- {
- enum key_add_attempt kaa;
-
- /* if no success, print all diagnostics */
- if (!oc->success)
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- key_add_ugh(keyid, oc->diag[kaa]);
-
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- pfreeany(oc->diag[kaa]);
-
- close(oc->whack_fd);
- pfree(oc);
- }
-}
-
-static void
-key_add_continue(struct adns_continuation *ac, err_t ugh)
-{
- struct key_add_continuation *kc = (void *) ac;
- struct key_add_common *oc = kc->common;
-
- passert(whack_log_fd == NULL_FD);
- whack_log_fd = oc->whack_fd;
-
- if (ugh != NULL)
- {
- oc->diag[kc->lookingfor] = clone_str(ugh, "key add error");
- }
- else
- {
- oc->success = TRUE;
- transfer_to_public_keys(kc->ac.gateways_from_dns
-#ifdef USE_KEYRR
- , &kc->ac.keys_from_dns
-#endif /* USE_KEYRR */
- );
- }
-
- oc->refCount--;
- key_add_merge(oc, &ac->id);
- whack_log_fd = NULL_FD;
-}
-
-static void
-key_add_request(const whack_message_t *msg)
-{
- struct id keyid;
- err_t ugh = atoid(msg->keyid, &keyid, FALSE);
-
- if (ugh != NULL)
- {
- loglog(RC_BADID, "bad --keyid \"%s\": %s", msg->keyid, ugh);
- }
- else
- {
- if (!msg->whack_addkey)
- delete_public_keys(&keyid, msg->pubkey_alg
- , empty_chunk, empty_chunk);
-
- if (msg->keyval.len == 0)
- {
- struct key_add_common *oc
- = alloc_thing(struct key_add_common
- , "key add common things");
- enum key_add_attempt kaa;
-
- /* initialize state shared by queries */
- oc->refCount = 0;
- oc->whack_fd = dup_any(whack_log_fd);
- oc->success = FALSE;
-
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- {
- struct key_add_continuation *kc
- = alloc_thing(struct key_add_continuation
- , "key add continuation");
-
- oc->diag[kaa] = NULL;
- oc->refCount++;
- kc->common = oc;
- kc->lookingfor = kaa;
- switch (kaa)
- {
- case ka_TXT:
- ugh = start_adns_query(&keyid
- , &keyid /* same */
- , T_TXT
- , key_add_continue
- , &kc->ac);
- break;
-#ifdef USE_KEYRR
- case ka_KEY:
- ugh = start_adns_query(&keyid
- , NULL
- , T_KEY
- , key_add_continue
- , &kc->ac);
- break;
-#endif /* USE_KEYRR */
- default:
- bad_case(kaa); /* suppress gcc warning */
- }
- if (ugh != NULL)
- {
- oc->diag[kaa] = clone_str(ugh, "early key add failure");
- oc->refCount--;
- }
- }
-
- /* Done launching queries.
- * Handle total failure case.
- */
- key_add_merge(oc, &keyid);
- }
- else
- {
- ugh = add_public_key(&keyid, DAL_LOCAL, msg->pubkey_alg
- , &msg->keyval, &pubkeys);
- if (ugh != NULL)
- loglog(RC_LOG_SERIOUS, "%s", ugh);
- }
- }
-}
-
-/* Handle a kernel request. Supposedly, there's a message in
- * the kernelsock socket.
- */
-void
-whack_handle(int whackctlfd)
-{
- whack_message_t msg;
- struct sockaddr_un whackaddr;
- int whackaddrlen = sizeof(whackaddr);
- int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
- /* Note: actual value in n should fit in int. To print, cast to int. */
- ssize_t n;
-
- if (whackfd < 0)
- {
- log_errno((e, "accept() failed in whack_handle()"));
- return;
- }
- if (fcntl(whackfd, F_SETFD, FD_CLOEXEC) < 0)
- {
- log_errno((e, "failed to set CLOEXEC in whack_handle()"));
- close(whackfd);
- return;
- }
-
- n = read(whackfd, &msg, sizeof(msg));
-
- if (n == -1)
- {
- log_errno((e, "read() failed in whack_handle()"));
- close(whackfd);
- return;
- }
-
- whack_log_fd = whackfd;
-
- /* sanity check message */
- {
- err_t ugh = NULL;
-
- next_str = msg.string;
- str_roof = (char *)&msg + n;
-
- if ((size_t)n < offsetof(whack_message_t, whack_shutdown) + sizeof(msg.whack_shutdown))
- {
- ugh = builddiag("ignoring runt message from whack: got %d bytes", (int)n);
- }
- else if (msg.magic != WHACK_MAGIC)
- {
- if (msg.magic == WHACK_BASIC_MAGIC)
- {
- /* Only shutdown command. Simpler inter-version compatability. */
- if (msg.whack_shutdown)
- {
- plog("shutting down");
- exit_pluto(0); /* delete lock and leave, with 0 status */
- }
- ugh = ""; /* bail early, but without complaint */
- }
- else
- {
- ugh = builddiag("ignoring message from whack with bad magic %d; should be %d; probably wrong version"
- , msg.magic, WHACK_MAGIC);
- }
- }
- else if (next_str > str_roof)
- {
- ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
- , (int) n, (unsigned) sizeof(msg));
- }
- else if (!unpack_str(&msg.name) /* string 1 */
- || !unpack_str(&msg.left.id) /* string 2 */
- || !unpack_str(&msg.left.cert) /* string 3 */
- || !unpack_str(&msg.left.ca) /* string 4 */
- || !unpack_str(&msg.left.groups) /* string 5 */
- || !unpack_str(&msg.left.updown) /* string 6 */
-#ifdef VIRTUAL_IP
- || !unpack_str(&msg.left.virt)
-#endif
- || !unpack_str(&msg.right.id) /* string 7 */
- || !unpack_str(&msg.right.cert) /* string 8 */
- || !unpack_str(&msg.right.ca) /* string 9 */
- || !unpack_str(&msg.right.groups) /* string 10 */
- || !unpack_str(&msg.right.updown) /* string 11 */
-#ifdef VIRTUAL_IP
- || !unpack_str(&msg.right.virt)
-#endif
- || !unpack_str(&msg.keyid) /* string 12 */
- || !unpack_str(&msg.myid) /* string 13 */
- || !unpack_str(&msg.cacert) /* string 14 */
- || !unpack_str(&msg.ldaphost) /* string 15 */
- || !unpack_str(&msg.ldapbase) /* string 16 */
- || !unpack_str(&msg.crluri) /* string 17 */
- || !unpack_str(&msg.crluri2) /* string 18 */
- || !unpack_str(&msg.ocspuri) /* string 19 */
- || !unpack_str(&msg.ike) /* string 20 */
- || !unpack_str(&msg.esp) /* string 21 */
- || !unpack_str(&msg.sc_data) /* string 22 */
- || str_roof - next_str != (ptrdiff_t)msg.keyval.len) /* check chunk */
- {
- ugh = "message from whack contains bad string";
- }
- else
- {
- msg.keyval.ptr = next_str; /* grab chunk */
- }
-
- if (ugh != NULL)
- {
- if (*ugh != '\0')
- loglog(RC_BADWHACKMESSAGE, "%s", ugh);
- whack_log_fd = NULL_FD;
- close(whackfd);
- return;
- }
- }
-
- if (msg.whack_options)
- {
-#ifdef DEBUG
- if (msg.name == NULL)
- {
- /* we do a two-step so that if either old or new would
- * cause the message to print, it will be printed.
- */
- cur_debugging |= msg.debugging;
- DBG(DBG_CONTROL
- , DBG_log("base debugging = %s"
- , bitnamesof(debug_bit_names, msg.debugging)));
- cur_debugging = base_debugging = msg.debugging;
- }
- else if (!msg.whack_connection)
- {
- struct connection *c = con_by_name(msg.name, TRUE);
-
- if (c != NULL)
- {
- c->extra_debugging = msg.debugging;
- DBG(DBG_CONTROL
- , DBG_log("\"%s\" extra_debugging = %s"
- , c->name
- , bitnamesof(debug_bit_names, c->extra_debugging)));
- }
- }
-#endif
- }
-
- if (msg.whack_myid)
- set_myid(MYID_SPECIFIED, msg.myid);
-
- /* Deleting combined with adding a connection works as replace.
- * To make this more useful, in only this combination,
- * delete will silently ignore the lack of the connection.
- */
- if (msg.whack_delete)
- {
- if (msg.whack_ca)
- find_ca_info_by_name(msg.name, TRUE);
- else
- delete_connections_by_name(msg.name, !msg.whack_connection);
- }
-
- if (msg.whack_deletestate)
- {
- struct state *st = state_with_serialno(msg.whack_deletestateno);
-
- if (st == NULL)
- {
- loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
- , msg.whack_deletestateno);
- }
- else
- {
- delete_state(st);
- }
- }
-
- if (msg.whack_crash)
- delete_states_by_peer(&msg.whack_crash_peer);
-
- if (msg.whack_connection)
- add_connection(&msg);
-
- if (msg.whack_ca && msg.cacert != NULL)
- add_ca_info(&msg);
-
- /* process "listen" before any operation that could require it */
- if (msg.whack_listen)
- {
- close_peerlog(); /* close any open per-peer logs */
- plog("listening for IKE messages");
- listening = TRUE;
- daily_log_reset();
- reset_adns_restart_count();
- set_myFQDN();
- find_ifaces();
- load_preshared_secrets(NULL_FD);
- load_groups();
- }
- if (msg.whack_unlisten)
- {
- plog("no longer listening for IKE messages");
- listening = FALSE;
- }
-
- if (msg.whack_reread & REREAD_SECRETS)
- {
- load_preshared_secrets(whackfd);
- }
-
- if (msg.whack_reread & REREAD_CACERTS)
- {
- load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
- }
-
- if (msg.whack_reread & REREAD_AACERTS)
- {
- load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
- }
-
- if (msg.whack_reread & REREAD_OCSPCERTS)
- {
- load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
- }
-
- if (msg.whack_reread & REREAD_ACERTS)
- {
- load_acerts();
- }
-
- if (msg.whack_reread & REREAD_CRLS)
- {
- load_crls();
- }
-
- if (msg.whack_purgeocsp)
- {
- free_ocsp_fetch();
- free_ocsp_cache();
- }
-
- if (msg.whack_list & LIST_ALGS)
- {
- ike_alg_list();
- kernel_alg_list();
- }
- if (msg.whack_list & LIST_PUBKEYS)
- {
- list_public_keys(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CERTS)
- {
- list_certs(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CACERTS)
- {
- list_authcerts("CA", AUTH_CA, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_AACERTS)
- {
- list_authcerts("AA", AUTH_AA, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_OCSPCERTS)
- {
- list_authcerts("OCSP", AUTH_OCSP, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_ACERTS)
- {
- list_acerts(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_GROUPS)
- {
- list_groups(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CAINFOS)
- {
- list_ca_infos(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CRLS)
- {
- list_crls(msg.whack_utc, strict_crl_policy);
- list_crl_fetch_requests(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_OCSP)
- {
- list_ocsp_cache(msg.whack_utc, strict_crl_policy);
- list_ocsp_fetch_requests(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CARDS)
- {
- scx_list(msg.whack_utc);
- }
-
- if (msg.whack_key)
- {
- /* add a public key */
- key_add_request(&msg);
- }
-
- if (msg.whack_route)
- {
- if (!listening)
- {
- whack_log(RC_DEAF, "need --listen before --route");
- }
- if (msg.name == NULL)
- {
- whack_log(RC_UNKNOWN_NAME
- , "whack --route requires a connection name");
- }
- else
- {
- struct connection *c = con_by_name(msg.name, TRUE);
-
- if (c != NULL)
- {
- set_cur_connection(c);
- if (!oriented(*c))
- whack_log(RC_ORIENT
- , "we have no ipsecN interface for either end of this connection");
- else if (c->policy & POLICY_GROUP)
- route_group(c);
- else if (!trap_connection(c))
- whack_log(RC_ROUTE, "could not route");
- reset_cur_connection();
- }
- }
- }
-
- if (msg.whack_unroute)
- {
- if (msg.name == NULL)
- {
- whack_log(RC_UNKNOWN_NAME
- , "whack --unroute requires a connection name");
- }
- else
- {
- struct connection *c = con_by_name(msg.name, TRUE);
-
- if (c != NULL)
- {
- struct spd_route *sr;
- int fail = 0;
-
- set_cur_connection(c);
-
- for (sr = &c->spd; sr != NULL; sr = sr->next)
- {
- if (sr->routing >= RT_ROUTED_TUNNEL)
- fail++;
- }
- if (fail > 0)
- whack_log(RC_RTBUSY, "cannot unroute: route busy");
- else if (c->policy & POLICY_GROUP)
- unroute_group(c);
- else
- unroute_connection(c);
- reset_cur_connection();
- }
- }
- }
-
- if (msg.whack_initiate)
- {
- if (!listening)
- {
- whack_log(RC_DEAF, "need --listen before --initiate");
- }
- else if (msg.name == NULL)
- {
- whack_log(RC_UNKNOWN_NAME
- , "whack --initiate requires a connection name");
- }
- else
- {
- initiate_connection(msg.name
- , msg.whack_async? NULL_FD : dup_any(whackfd));
- }
- }
-
- if (msg.whack_oppo_initiate)
- {
- if (!listening)
- whack_log(RC_DEAF, "need --listen before opportunistic initiation");
- else
- initiate_opportunistic(&msg.oppo_my_client, &msg.oppo_peer_client, 0
- , FALSE
- , msg.whack_async? NULL_FD : dup_any(whackfd));
- }
-
- if (msg.whack_terminate)
- {
- if (msg.name == NULL)
- {
- whack_log(RC_UNKNOWN_NAME
- , "whack --terminate requires a connection name");
- }
- else
- {
- terminate_connection(msg.name);
- }
- }
-
- if (msg.whack_status)
- show_status(msg.whack_statusall, msg.name);
-
- if (msg.whack_shutdown)
- {
- plog("shutting down");
- exit_pluto(0); /* delete lock and leave, with 0 status */
- }
-
- if (msg.whack_sc_op != SC_OP_NONE)
- {
- if (pkcs11_proxy)
- scx_op_via_whack(msg.sc_data, msg.inbase, msg.outbase
- , msg.whack_sc_op, msg.keyid, whackfd);
- else
- plog("pkcs11 access to smartcard not allowed (set pkcs11proxy=yes)");
- }
-
- whack_log_fd = NULL_FD;
- close(whackfd);
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * c-style: pluto
- * End:
- */
diff --git a/programs/pluto/rcv_whack.h b/programs/pluto/rcv_whack.h
deleted file mode 100644
index f42761c51..000000000
--- a/programs/pluto/rcv_whack.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* whack communicating routines
- * Copyright (C) 1998, 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rcv_whack.h,v 1.1 2004/03/15 20:35:29 as Exp $
- */
-
-extern void whack_handle(int kernelfd);
diff --git a/programs/pluto/rnd.c b/programs/pluto/rnd.c
deleted file mode 100644
index da72cc8ff..000000000
--- a/programs/pluto/rnd.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* randomness machinery
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rnd.c,v 1.3 2005/09/08 16:26:30 as Exp $
- */
-
-/* A true random number generator (we hope)
- *
- * Under LINUX ("linux" predefined), use /dev/urandom.
- * Under OpenBSD ("__OpenBSD__" predefined), use arc4random().
- * Otherwise use our own random number generator based on clock skew.
- * I (ADK) first heard of the idea from John Ioannidis, who heard it
- * from Matt Blaze and/or Jack Lacy.
- * ??? Why is mixing need for linux but not OpenBSD?
- */
-
-/* Pluto's uses of randomness:
- *
- * - Setting up the "secret_of_the_day". This changes every hour! 20
- * bytes a shot. It is used in building responder cookies.
- *
- * - generating initiator cookies (8 bytes, once per Phase 1 initiation).
- *
- * - 32 bytes per DH local secret. Once per Main Mode exchange and once
- * per Quick Mode Exchange with PFS. (Size is our choice, with
- * tradeoffs.)
- *
- * - 16 bytes per nonce we generate. Once per Main Mode exchange and
- * once per Quick Mode exchange. (Again, we choose the size.)
- *
- * - 4 bytes per SPI number that we generate. We choose the SPIs for all
- * inbound SPIs, one to three per IPSEC SA (one for AH (rare, probably)
- * one for ESP (almost always), and one for tunnel (very common)).
- * I don't actually know how the kernel would generate these numbers --
- * currently Pluto generates them; this isn't the way things will be
- * done in the future.
- *
- * - 4 bytes per Message ID we need to generate. One per Quick Mode
- * exchange. Eventually, one per informational exchange.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include "sha1.h"
-#include "constants.h"
-#include "defs.h"
-#include "rnd.h"
-#include "log.h"
-#include "timer.h"
-
-#ifdef linux
-# define USE_DEV_RANDOM 1
-# define RANDOM_PATH "/dev/urandom"
-#else
-# ifdef __OpenBSD__
-# define USE_ARC4RANDOM
-# else
-# define USE_CLOCK_SLEW
-# endif
-#endif
-
-#ifdef USE_ARC4RANDOM
-
-#define get_rnd_byte() (arc4random() % 256)
-
-#else /**** start of large #else ****/
-
-#ifdef USE_DEV_RANDOM
-static int random_fd = NULL_FD;
-#endif
-
-#define RANDOM_POOL_SIZE SHA1_DIGEST_SIZE
-static u_char random_pool[RANDOM_POOL_SIZE];
-
-#ifdef USE_DEV_RANDOM
-
-/* Generate (what we hope is) a true random byte using /dev/urandom */
-static u_char
-generate_rnd_byte(void)
-{
- u_char c;
-
- if (read(random_fd, &c, sizeof(c)) == -1)
- exit_log_errno((e, "read() failed in get_rnd_byte()"));
-
- return c;
-}
-
-#else /* !USE_DEV_RANDOM */
-
-/* Generate (what we hope is) a true random byte using the clock skew trick.
- * Note: this code is not maintained! In particular, LINUX signal(2)
- * semantics changed with glibc2 (and not for the better). It isn't clear
- * that this code will work. We keep the code because someday it might
- * come in handy.
- */
-# error "This code is not maintained. Please define USE_DEV_RANDOM."
-
-static volatile sig_atomic_t i, j, k;
-
-/* timer signal handler */
-static void
-rnd_handler(int ignore_me UNUSED)
-{
- k <<= 1; /* Shift left by 1 */
- j++;
- k |= (i & 0x1); /* Get lsbit of counter */
-
- if (j != 8)
- signal(SIGVTALRM, rnd_handler);
-}
-
-static u_char
-generate_rnd_byte(void)
-{
- struct itimerval tmval, ntmval;
-
-# ifdef NEVER /* ??? */
-# ifdef linux
- int mask = siggetmask();
-
- mask |= SIGVTALRM;
- sigsetmask(mask);
-# endif
-# endif
-
- i = 0;
- j = 0;
-
- ntmval.it_interval.tv_sec = 0;
- ntmval.it_interval.tv_usec = 1;
- ntmval.it_value.tv_sec = 0;
- ntmval.it_value.tv_usec = 1;
- signal(SIGVTALRM, rnd_handler);
- setitimer(ITIMER_VIRTUAL, &ntmval, &tmval);
-
- while (j != 8)
- i++;
-
- setitimer(ITIMER_VIRTUAL, &tmval, &ntmval);
- signal(SIGVTALRM, SIG_IGN);
-
-# ifdef NEVER /* ??? */
-# ifdef linux
- mask ^= SIGVTALRM;
- sigsetmask(mask);
-# endif
-# endif
-
- return k;
-}
-
-#endif /* !USE_DEV_RANDOM */
-
-static void
-mix_pool(void)
-{
- SHA1_CTX ctx;
-
- SHA1Init(&ctx);
- SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE);
- SHA1Final(random_pool, &ctx);
-}
-
-/*
- * Get a single random byte.
- */
-static u_char
-get_rnd_byte(void)
-{
- random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
- random_pool[0] = generate_rnd_byte();
- mix_pool();
- return random_pool[0];
-}
-
-#endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/
-
-void
-get_rnd_bytes(u_char *buffer, int length)
-{
- int i;
-
- for (i = 0; i < length; i++)
- buffer[i] = get_rnd_byte();
-}
-
-/*
- * Initialize the random pool.
- */
-void
-init_rnd_pool(void)
-{
-#ifndef USE_ARC4RANDOM
-# ifdef USE_DEV_RANDOM
- DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
- random_fd = open(RANDOM_PATH, O_RDONLY);
- if (random_fd == -1)
- exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
- fcntl(random_fd, F_SETFD, FD_CLOEXEC);
-# endif
-
- get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
- mix_pool();
-#endif /* !USE_ARC4RANDOM */
-
- /* start of rand(3) on the right foot */
- {
- unsigned int seed;
-
- get_rnd_bytes((void *)&seed, sizeof(seed));
- srand(seed);
- }
-}
-
-u_char secret_of_the_day[SHA1_DIGEST_SIZE];
-
-#ifndef NO_PLUTO
-
-void
-init_secret(void)
-{
- /*
- * Generate the secret value for responder cookies, and
- * schedule an event for refresh.
- */
- get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day));
- event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
-}
-
-#endif /* NO_PLUTO */
diff --git a/programs/pluto/rnd.h b/programs/pluto/rnd.h
deleted file mode 100644
index 0bd168039..000000000
--- a/programs/pluto/rnd.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* randomness machinery
- * Copyright (C) 1998, 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rnd.h,v 1.1 2004/03/15 20:35:29 as Exp $
- */
-
-extern u_char secret_of_the_day[SHA1_DIGEST_SIZE];
-
-extern void get_rnd_bytes(u_char *buffer, int length);
-extern void init_rnd_pool(void);
-extern void init_secret(void);
diff --git a/programs/pluto/routing.txt b/programs/pluto/routing.txt
deleted file mode 100644
index a69b8a542..000000000
--- a/programs/pluto/routing.txt
+++ /dev/null
@@ -1,331 +0,0 @@
-Routing and Erouting in Pluto
-=============================
-
-RCSID $Id: routing.txt,v 1.1 2004/03/15 20:35:29 as Exp $
-
-This is meant as internal documentation for Pluto. As such, it
-presumes some understanding of Pluto's code.
-
-It also describes KLIPS 1 erouting, including details not otherwise
-documented. KLIPS 1 documentation would be better included in KLIPS.
-
-Routing and erouting are complicated enough that the Pluto code needs
-a guide. This document is meant to be that guide.
-
-
-Mechanisms available to Pluto
------------------------------
-
-All outbound packets that are to be processed by KLIPS 1 must be
-routed to an ipsecN network interface. Pluto only uses normal routing
-(as opposed to "Advanced Routing"), so the selection of packets is
-made solely on the basis of the destination address. (Since the
-actual routing commands are in the updown script, they could be
-changed by the administrator, but Pluto needs to understand what is
-going on, and it currently assumes normal routing is used.)
-
-When an outbound packet hits an ipsecN interface, KLIPS figures out
-how to process it by finding an eroute that applies to the source and
-destination addresses. Eroutes are global: they are not specific to a
-particular ipsecN interface (routing needs to get the packets to any
-ipsecN interface; erouting takes it from there, ignoring issues of
-source IP address and nexthop (because nobody knows!)). If multiple
-eroutes apply to the packet, among the ones with the most specific
-source subnet, the one with the most specific destination subset is
-chosen (RGB thinks). If no eroute is discovered, KLIPS acts as if it
-was covered by a DROP eroute (this is the default behaviour; it can be
-changed). At most one eroute can exist for a particular pair of
-client subnets.
-
-There are fundamentally two kinds of eroutes: "shunt" eroutes and ones
-that specify that a packet is to be processed by a group of IPSEC SAs.
-Shunt eroutes specify what is to be done with the packet. Remember
-that these only apply to outbound packets.
-
-- TRAP: notify Pluto of the packet (presumably to attempt to negotiate
- an appropriate group of IPSEC SAs). At the same time, KLIPS
- installs a HOLD shunt (see below) for the specific source and
- destination addresses from the packet and retains the packet
- for later reprocessing (KLIPS does not yet implement retention).
- Beware: if the TRAP's subnets both contained a single IP address
- then installing the HOLD would actually delete the TRAP.
-
-- PASS: let the packet through in the clear
-
-- DROP: discard the packet
-
-- REJECT: discard the packet and notify the sender
-
-- HOLD: (automatically created by KLIPS when a TRAP fires) block
- the packet, but retain it. If there is already a retained
- packet, drop the old one and retain the new. When the HOLD
- shunt is deleted or replaced, the retained packet is reinjected --
- there might now be a tunnel. Note that KLIPS doesn't yet
- implement the retention part, so HOLD is really like a DROP.
-
-One consequence of there being only one eroute for a pair of clients
-is that KLIPS will only use one SA group for output for this pair,
-even though there could be several SA groups that are authorised and
-live. Pluto chooses to make this the youngest such group.
-
-
-
-KLIPS lets through in the clear outbound UDP/500 packets that would
-otherwise be processed if they originate on this host and meet certain
-other conditions. The actual test is
- source == me
- && (no_eroute || dest == eroute.dest || isanyaddr(eroute.dest))
- && port == UDP/500
-The idea is that IKE packets between us and a peer should not be
-sent through an IPSEC tunnel negotiated between us. Furthermore,
-our shunt eroutes should not apply to our IKE packets (shunt eroutes
-will generally have an eroute.dest of 0.0.0.0 or its IPv6 equivalent).
-
-Inbound behaviour is controlled in a quite different way. KLIPS
-processes only those inbound packets of ESP or AH protocol, with a
-destination address for this machine's ipsecN interfaces. The
-processing is as dictated by the SAs involved. Unfortunately, the
-decapsulated packet's source and destination address are not checked
-(part of "inbound policy checking").
-
-To prevent clear packets being accepted, firewall rules must be put in
-place. This has nothing to do with KLIPS, but is nonetheless in
-important part of security. It isn't clear what firewalling makes
-sense when Opportunism is allowed.
-
-
-For routing and firewalling, Pluto invokes the updown script. Pluto
-installs eroutes via extended PF_KEY messages.
-
-
-Current Pluto Behaviour
------------------------
-
-Data Structures:
-
-Routes and most eroutes are associated with connections (struct
-connection, a potential connection description). The enum routing_t
-field "routing" in struct connection records the state of routing and
-erouting for that connection. The values are:
- RT_UNROUTED, /* unrouted */
- RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
- RT_ROUTED_PROSPECTIVE, /* routed, and TRAP shunt installed */
- RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
- RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
- RT_ROUTED_TUNNEL /* routed, and erouted to an IPSEC SA group */
-Notice that the routing and erouting are not independent: erouting
-(except for HOLD) implies that the connection is routed.
-
-Several struct connections may have the same destination subnet. If
-they agree on what the route should be, they can share it -- any of
-them may have routing >= RT_ROUTED_PROSPECTIVE. If they disagree,
-they cannot simultaneously be routed.
-
-invariant: for all struct connections c, d:
- (c.that.client == d.that.client
- && c.routing >= RT_ROUTED_PROSPECTIVE
- && d.routing >= RT_ROUTED_PROSPECTIVE)
- => c.interface == d.interface && c.this.nexthop == d.this.nexthop
-
-There are two kinds of eroutes: shunt eroutes and ones for an IPSEC SA
-Group. Most eroutes are associated with and are represeented in a
-connection. The exception is that some HOLD and PASS shunts do not
-correspond to connections; those are represented in the bare_shunt
-table.
-
-An eroute for an IPSEC SA Group is associated with the state object
-for that Group. The existence of such an eroute is also represented
-by the "so_serial_t eroute_owner" field in the struct connection. The
-value is the serial number of the state object for the Group. The
-special value SOS_NOBODY means that there is no owner associated with
-this connection for the eroute and hence no normal eroute. At most
-one eroute owner may exist for a particular (source subnet,
-destination subnet) pair. A Pluto-managed eroute cannot be associated
-with an RT_UNROUTED connection.
-
-invariant: for all struct connection c:
- c.routing == RT_EROUTED_TUNNEL || c.eroute_owner == SOS_NOBODY
-
-invariant: for all struct connections c, d:
- c.this.client == d.this.client && c.that.client == d.that.client
- && &c != &d
- => c.routing == RT_UNROUTED || d.routing == RT_UNROUTED
-
-If no normal eroute is set for a particular (source subnet,
-destination subnet) pair for which a connection is routed, then a
-shunt eroute would have been installed. This specifies what should
-happen to packets snared by the route.
-
-When Pluto is notified by KLIPS of a packet that has been TRAPped,
-there is no connection with which to associate the HOLD. It is
-temporarily held in the "bare_shunt table". If Opportunism is
-attempted but DNS doesn't provide Security Gateway information, Pluto
-will replace the HOLD with a PASS shunt. Since this PASS isn't
-associated with a connection, it too will reside in the bare_shunt
-table. If the HOLD can be associated with a connection, it will be
-removed from the bare_shunt table and represented in the connection.
-
-There are two contexts for which shunt eroutes are installed by Pluto
-for a particular connection. The first context is with the prospect
-of dealing with packets before any negotiation has been attempted. I
-call this context "prospective". Currently is a TRAP shunt, used to
-catch packets for initiate opportunistic negotiation. In the future,
-it might also be used to implement preordained PASS, DROP, or REJECT
-rules.
-
-The second context is after a failed negotiation. I call this context
-"failure". At this point a different kind of shunt eroute is
-appropriate. Depending on policy, it could be PASS, DROP, or REJECT,
-but it is unlikely to be TRAP. The shunt eroute should have a
-lifetime (this isn't yet implemented). When the lifetime expires, the
-failure shunt eroute should be replaced by the prospective shunt
-eroute.
-
-The kind and duration of a failure shunt eroute should perhaps depend
-on the nature of the failure, at least as imperfectly detected by
-Pluto. We haven't looked at this. In particular, the mapping from
-observations to robust respose isn't obvious.
-
-The shunt eroute policies should be a function of the potential
-connection. The failure shunt eroute can be specified for a
-particular connection with the flags --pass and --drop in a connection
-definition. There are four combinations, and each has a distinct
-meaning. The failure shunt eroute is incompletely implemented and
-cannot be represented in /etc/ipsec.conf.
-
-There is as yet no control over the prospective shunt eroute: it is
-always TRAP as far as Pluto is concerned. This is probably
-reasonable: any other fate suggests that no negotiation will be done,
-and so a connection definition is inappropriate. These should be
-implemented as manual conns. There remains the issue of whether Pluto
-should be aware of them -- currently it is not.
-
-
-Routines:
-
-[in kernel.c]
-
-bool do_command(struct connection *c, const char *verb)
- Run the updown script to perform such tasks as installing a route
- and adjust the firewall.
-
-bool could_route(struct connection *c)
- Check to see whether we could route and eroute the connection.
- <- shunt_eroute_connection (to check if --route can be performed)
- <- install_inbound_ipsec_sa (to see if it will be possible
- to (later) install route and eroute the corresponding outbound SA)
- <- install_ipsec_sa (to see if the outbound SA can be routed and erouted)
-
-bool trap_connection(struct connection *c)
- Install a TRAP shunt eroute for this connection. This implements
- "whack --route", the way an admin can specify that packets for a
- connection should be caught without first bringing it up.
-
-void unroute_connection(struct connection *c)
- Delete any eroute for a connection and unroute it if route isn't shared.
- <- release_connection
- <- whack_handle (for "whack --unroute)
-
-bool eroute_connection(struct connection *c
-, ipsec_spi_t spi, unsigned int proto, unsigned int satype
-, unsigned int op, const char *opname UNUSED)
- Issue PF_KEY commands to KLIPS to add, replace, or delete an eroute.
- The verb is specified by op and described (for logging) by opname.
- <- assign_hold
- <- sag_eroute
- <- shunt_eroute
-
-bool assign_hold(struct connection *c
-, const ip_address *src, const ip_address *dst)
- Take a HOLD from the bare_shunt table and assign it to a connection.
- If the HOLD is broadened (i.e. the connection's source or destination
- subnets contain more than one IP address), this will involve replacing
- the HOLD with a different one.
-
-bool sag_eroute(struct state *st, unsigned op, const char *opname)
- SA Group eroute manipulation. The SA Group concerned is
- identified with a state object.
- <- route_and_eroute several times
-
-bool shunt_eroute(struct connection *c, unsigned int op, const char *opname)
- shunt eroute manipulation. Shunt eroutes are associated with
- connections.
- <- unroute_connection
- <- route_and_eroute
- <- delete_ipsec_sa
-
-bool route_and_eroute(struct connection *c, struct state *st)
- Install a route and then a prospective shunt eroute or an SA group
- eroute. The code assumes that could_route had previously
- given the go-ahead. Any SA group to be erouted must already
- exist.
- <- shunt_eroute_connection
- <- install_ipsec_sa
-
-void scan_proc_shunts(void)
- Every SHUNT_SCAN_INTERVAL scan /proc/net/ipsec_eroute.
- Delete any PASS eroute in the bare_shunt table that hasn't been used
- within the last SHUNT_PATIENCE seconds.
- For any HOLD for which Pluto hasn't received an ACQUIRE (possibly
- lost due to congestion), act as if an ACQUIRE were received.
-
-[in connection.c]
-
-struct connection *route_owner(struct connection *c, struct connection **erop)
- Find the connection to connection c's peer's client with the
- largest value of .routing. All other things being equal,
- preference is given to c. Return NULL if no connection is routed
- at all. If erop is non-null, sets it to a connection sharing both
- our client subnet and peer's client subnet with the largest value
- of .routing.
- The return value is used to find other connections sharing
- a route. The value of *erop is used to find other connections
- sharing an eroute.
- <- could_route (to find any conflicting routes or eroutes)
- <- unroute_connection (to find out if our route is still in use
- after this connection is finished with it)
- <- install_inbound_ipsec_sa (to find other IPSEC SAs for the
- same peer clients; when we find them WE KILL THEM; a
- kludge to deal with road warriors reconnecting)
- <- route_and_eroute (to find all the connections from which the
- route or eroute is being stolen)
-
-Uses:
-
-- setting up route & shunt eroute to TRAP packets for opportunism
- (whack --route). Perhaps also manually designating DROP, REJECT, or
- PASS for certain packets.
-
- whack_handle() responds to --route; calls route_connection()
-
-
-- removing same (whack --unroute)
-
- whack_handle() responds to --unroute; calls unroute_connection()
-
-- installing route & normal eroute for a newly negotiated group of
- outbound IPSEC SAs
-
- + perhaps an (additional) route is not needed: if the negotiation
- was initiated by a TRAPped outgoing packet, then there must
- already have been a route that got the packet to ipsecN. Mind
- you, it could have been the wrong N!
-
- install_ipsec_sa()
-
-- updating a normal eroute when a new group of IPSEC SAs replaces
- an old one due to rekeying.
-
- install_ipsec_sa()
-
-- replacing an old eroute when a negotiation fails. But this is
- tricky. If this was a rekeying, we should just leave the old
- normal eroute be -- it might still work. Otherwise, this was
- an initial negotiation: we should replace the shunt eroute
- with one appropriate for the failure context.
-
-- when a group of IPSEC SAs dies or is killed, and it had the eroute,
- its normal eroute should be replaced by a shunt eroute. If there
- was an attempt to replace the group, the replacement is in the
- failure context; otherwise the replacement is in the prospective
- context.
diff --git a/programs/pluto/rsaref/pkcs11.h b/programs/pluto/rsaref/pkcs11.h
deleted file mode 100644
index 9261e1e4c..000000000
--- a/programs/pluto/rsaref/pkcs11.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* pkcs11.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined. These
- * macros are described below, and typical definitions for them
- * are also given. Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a Cryptoki library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for Cryptoki structures should be set. The Cryptoki
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, this might be done by using the following
- * preprocessor directive before including pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, this might be done by using
- * the following preprocessor directive before including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(1)
- *
- * In a UNIX environment, you're on your own for this. You might
- * not need to do (or be able to do!) anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object. It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, it might be defined by:
- *
- * #define CK_PTR *
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, it might be defined by:
- *
- * #define CK_PTR far *
- *
- * In a typical UNIX environment, it might be defined by:
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable Cryptoki library function definition out of a
- * return type and a function name. It should be used in the
- * following fashion to define the exposed Cryptoki functions in
- * a Cryptoki library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * )
- * {
- * ...
- * }
- *
- * If you're using Microsoft Developer Studio 5.0 to define a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType __declspec(dllexport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to define a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable Cryptoki library function declaration out of a
- * return type and a function name. It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * );
- *
- * If you're using Microsoft Developer Studio 5.0 to declare a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType __declspec(dllimport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to declare a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a Cryptoki API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name. It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a Cryptoki API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // Cryptoki API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * If you're using Microsoft Developer Studio 5.0 to access
- * functions in a Win32 Cryptoki .dll, in might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType __declspec(dllimport) (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to access functions in a Win16 Cryptoki .dll, it might
- * be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType __export _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV. It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * If you're using Microsoft Developer Studio 5.0 to do Win32
- * Cryptoki development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to do Win16 development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should best be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various Cryptoki types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y) x##y
-
-
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- extern CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points. That is, for
- * each Cryptoki function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points. A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's Cryptoki version
- * and then a whole slew of function pointers to the routines in
- * the library. This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
- __PASTE(CK_,name) name;
-
-struct CK_FUNCTION_LIST {
-
- CK_VERSION version; /* Cryptoki version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/programs/pluto/rsaref/pkcs11f.h b/programs/pluto/rsaref/pkcs11f.h
deleted file mode 100644
index dec6315dd..000000000
--- a/programs/pluto/rsaref/pkcs11f.h
+++ /dev/null
@@ -1,912 +0,0 @@
-/* pkcs11f.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This header file contains pretty much everything about all the */
-/* Cryptoki function prototypes. Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-/* General-purpose */
-
-/* C_Initialize initializes the Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
- * cast to CK_C_INITIALIZE_ARGS_PTR
- * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about Cryptoki. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_INFO_PTR pInfo /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
- * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_BBOOL tokenPresent, /* only slots with tokens? */
- CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
- CK_ULONG_PTR pulCount /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the ID of the slot */
- CK_SLOT_INFO_PTR pInfo /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_TOKEN_INFO_PTR pInfo /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of token's slot */
- CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
- CK_ULONG_PTR pulCount /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_MECHANISM_TYPE type, /* type of mechanism */
- CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
- CK_ULONG ulPinLen, /* length in bytes of the PIN */
- CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
- CK_ULONG ulPinLen /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
- CK_ULONG ulOldLen, /* length of the old PIN */
- CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
- CK_ULONG ulNewLen /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the slot's ID */
- CK_FLAGS flags, /* from CK_SESSION_INFO */
- CK_VOID_PTR pApplication, /* passed to callback */
- CK_NOTIFY Notify, /* callback function */
- CK_SESSION_HANDLE_PTR phSession /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_SESSION_INFO_PTR pInfo /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* gets state */
- CK_ULONG_PTR pulOperationStateLen /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* holds state */
- CK_ULONG ulOperationStateLen, /* holds state length */
- CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
- CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_USER_TYPE userType, /* the user type */
- CK_UTF8CHAR_PTR pPin, /* the user's PIN */
- CK_ULONG ulPinLen /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ULONG_PTR pulSize /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
- CK_ULONG ulCount /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
- CK_ULONG ulMaxObjectCount, /* max handles to get */
- CK_ULONG_PTR pulObjectCount /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pData, /* the plaintext data */
- CK_ULONG ulDataLen, /* bytes of plaintext */
- CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext data len */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session handle */
- CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
- CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedData, /* ciphertext */
- CK_ULONG ulEncryptedDataLen, /* ciphertext length */
- CK_BYTE_PTR pData, /* gets plaintext */
- CK_ULONG_PTR pulDataLen /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* encrypted data */
- CK_ULONG ulEncryptedPartLen, /* input length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pLastPart, /* gets plaintext */
- CK_ULONG_PTR pulLastPartLen /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* data to be digested */
- CK_ULONG ulDataLen, /* bytes of data to digest */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* data to be digested */
- CK_ULONG ulPartLen /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hKey /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* the data to sign */
- CK_ULONG ulPartLen /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- * cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* signed data */
- CK_ULONG ulDataLen, /* length of signed data */
- CK_BYTE_PTR pSignature, /* signature */
- CK_ULONG ulSignatureLen /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* signed data */
- CK_ULONG ulPartLen /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen, /* signature length */
- CK_BYTE_PTR pData, /* gets signed data */
- CK_ULONG_PTR pulDataLen /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* key generation mech. */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
- CK_ULONG ulCount, /* # of attrs in template */
- CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session
- * handle */
- CK_MECHANISM_PTR pMechanism, /* key-gen
- * mech. */
- CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
- * for pub.
- * key */
- CK_ULONG ulPublicKeyAttributeCount, /* # pub.
- * attrs. */
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
- * for priv.
- * key */
- CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
- * attrs. */
- CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
- * key
- * handle */
- CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
- * priv. key
- * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
- CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
- CK_OBJECT_HANDLE hKey, /* key to be wrapped */
- CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
- CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
- CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
- CK_BYTE_PTR pWrappedKey, /* the wrapped key */
- CK_ULONG ulWrappedKeyLen, /* wrapped key len */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
- CK_OBJECT_HANDLE hBaseKey, /* base key */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSeed, /* the seed material */
- CK_ULONG ulSeedLen /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR RandomData, /* receives the random data */
- CK_ULONG ulRandomLen /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for Cryptoki Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FLAGS flags, /* blocking/nonblocking flag */
- CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
- CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
-);
-#endif
diff --git a/programs/pluto/rsaref/pkcs11t.h b/programs/pluto/rsaref/pkcs11t.h
deleted file mode 100644
index 3da20b215..000000000
--- a/programs/pluto/rsaref/pkcs11t.h
+++ /dev/null
@@ -1,1685 +0,0 @@
-/* pkcs11t.h include file for PKCS #11. */
-/* $Revision: 1.2 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file. */
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#define CK_TRUE 1
-#define CK_FALSE 0
-
-#ifndef CK_DISABLE_TRUE_FALSE
-#ifndef FALSE
-#define FALSE CK_FALSE
-#endif
-
-#ifndef TRUE
-#define TRUE CK_TRUE
-#endif
-#endif
-
-/* an unsigned 8-bit value */
-typedef unsigned char CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE CK_CHAR;
-
-/* an 8-bit UTF-8 character */
-typedef CK_BYTE CK_UTF8CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE 0
-
-
-typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-typedef CK_CHAR CK_PTR CK_CHAR_PTR;
-typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
-typedef CK_ULONG CK_PTR CK_ULONG_PTR;
-typedef void CK_PTR CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-typedef struct CK_VERSION {
- CK_BYTE major; /* integer portion of version number */
- CK_BYTE minor; /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
- /* manufacturerID and libraryDecription have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags; /* must be zero */
-
- /* libraryDescription and libraryVersion are new for v2.0 */
- CK_UTF8CHAR libraryDescription[32]; /* blank padded */
- CK_VERSION libraryVersion; /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * Cryptoki provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER 0
-
-
-typedef CK_ULONG CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
- /* slotDescription and manufacturerID have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_UTF8CHAR slotDescription[64]; /* blank padded */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags;
-
- /* hardwareVersion and firmwareVersion are new for v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
-#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
-#define CKF_HW_SLOT 0x00000004 /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
- /* label, manufacturerID, and model have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_UTF8CHAR label[32]; /* blank padded */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_UTF8CHAR model[16]; /* blank padded */
- CK_CHAR serialNumber[16]; /* blank padded */
- CK_FLAGS flags; /* see below */
-
- /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
- * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
- * changed from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulMaxSessionCount; /* max open sessions */
- CK_ULONG ulSessionCount; /* sess. now open */
- CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
- CK_ULONG ulRwSessionCount; /* R/W sess. now open */
- CK_ULONG ulMaxPinLen; /* in bytes */
- CK_ULONG ulMinPinLen; /* in bytes */
- CK_ULONG ulTotalPublicMemory; /* in bytes */
- CK_ULONG ulFreePublicMemory; /* in bytes */
- CK_ULONG ulTotalPrivateMemory; /* in bytes */
- CK_ULONG ulFreePrivateMemory; /* in bytes */
-
- /* hardwareVersion, firmwareVersion, and time are new for
- * v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
- CK_CHAR utcTime[16]; /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- * Bit Flag Mask Meaning
- */
-#define CKF_RNG 0x00000001 /* has random #
- * generator */
-#define CKF_WRITE_PROTECTED 0x00000002 /* token is
- * write-
- * protected */
-#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
- * login */
-#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
- * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
- * that the token has some sort of clock. The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN 0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the Cryptoki library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
-
-/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
- * equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
- * the token to be reinitialized. */
-#define CKF_TOKEN_INITIALIZED 0x00000400
-
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. This flag is deprecated in v2.11 and
- onwards. */
-#define CKF_SECONDARY_AUTHENTICATION 0x00000800
-
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
- * since the last successful authentication. */
-#define CKF_USER_PIN_COUNT_LOW 0x00010000
-
-/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect user PIN will it to become locked. */
-#define CKF_USER_PIN_FINAL_TRY 0x00020000
-
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
- * possible. */
-#define CKF_USER_PIN_LOCKED 0x00040000
-
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
-
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
- * the last successful authentication. */
-#define CKF_SO_PIN_COUNT_LOW 0x00100000
-
-/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect SO PIN will it to become locked. */
-#define CKF_SO_PIN_FINAL_TRY 0x00200000
-
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
- * PIN has been locked. SO login to the token is not possible.
- */
-#define CKF_SO_PIN_LOCKED 0x00400000
-
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
- * identifies a session */
-typedef CK_ULONG CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of Cryptoki users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO 0
-/* Normal user */
-#define CKU_USER 1
-/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC 2
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_STATE;
-#define CKS_RO_PUBLIC_SESSION 0
-#define CKS_RO_USER_FUNCTIONS 1
-#define CKS_RW_PUBLIC_SESSION 2
-#define CKS_RW_USER_FUNCTIONS 3
-#define CKS_RW_SO_FUNCTIONS 4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
- CK_SLOT_ID slotID;
- CK_STATE state;
- CK_FLAGS flags; /* see below */
-
- /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulDeviceError; /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- * Bit Flag Mask Meaning
- */
-#define CKF_RW_SESSION 0x00000002 /* session is r/w */
-#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object */
-typedef CK_ULONG CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that Cryptoki recognizes. It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-/* CKO_HW_FEATURE is new for v2.10 */
-/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-/* CKO_MECHANISM is new for v2.20 */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_HW_FEATURE 0x00000005
-#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_MECHANISM 0x00000007
-#define CKO_VENDOR_DEFINED 0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
- * value that identifies the hardware feature type of an object
- * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-typedef CK_ULONG CK_HW_FEATURE_TYPE;
-
-/* The following hardware feature types are defined */
-/* CKH_USER_INTERFACE is new for v2.20 */
-#define CKH_MONOTONIC_COUNTER 0x00000001
-#define CKH_CLOCK 0x00000002
-#define CKH_USER_INTERFACE 0x00000003
-#define CKH_VENDOR_DEFINED 0x80000000
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA 0x00000000
-#define CKK_DSA 0x00000001
-#define CKK_DH 0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-#define CKK_ECDSA 0x00000003
-#define CKK_EC 0x00000003
-#define CKK_X9_42_DH 0x00000004
-#define CKK_KEA 0x00000005
-
-#define CKK_GENERIC_SECRET 0x00000010
-#define CKK_RC2 0x00000011
-#define CKK_RC4 0x00000012
-#define CKK_DES 0x00000013
-#define CKK_DES2 0x00000014
-#define CKK_DES3 0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST 0x00000016
-#define CKK_CAST3 0x00000017
-/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018
-#define CKK_RC5 0x00000019
-#define CKK_IDEA 0x0000001A
-#define CKK_SKIPJACK 0x0000001B
-#define CKK_BATON 0x0000001C
-#define CKK_JUNIPER 0x0000001D
-#define CKK_CDMF 0x0000001E
-#define CKK_AES 0x0000001F
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKK_BLOWFISH 0x00000020
-#define CKK_TWOFISH 0x00000021
-
-#define CKK_VENDOR_DEFINED 0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-/* CKC_X_509_ATTR_CERT is new for v2.10 */
-/* CKC_WTLS is new for v2.20 */
-#define CKC_X_509 0x00000000
-#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS 0x00000002
-#define CKC_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_ATTRIBUTE_TYPE;
-
-/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
- consists of an array of values. */
-#define CKF_ARRAY_ATTRIBUTE 0x40000000
-
-/* The following attribute types are defined: */
-#define CKA_CLASS 0x00000000
-#define CKA_TOKEN 0x00000001
-#define CKA_PRIVATE 0x00000002
-#define CKA_LABEL 0x00000003
-#define CKA_APPLICATION 0x00000010
-#define CKA_VALUE 0x00000011
-
-/* CKA_OBJECT_ID is new for v2.10 */
-#define CKA_OBJECT_ID 0x00000012
-
-#define CKA_CERTIFICATE_TYPE 0x00000080
-#define CKA_ISSUER 0x00000081
-#define CKA_SERIAL_NUMBER 0x00000082
-
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
- * for v2.10 */
-#define CKA_AC_ISSUER 0x00000083
-#define CKA_OWNER 0x00000084
-#define CKA_ATTR_TYPES 0x00000085
-
-/* CKA_TRUSTED is new for v2.11 */
-#define CKA_TRUSTED 0x00000086
-
-/* CKA_CERTIFICATE_CATEGORY ...
- * CKA_CHECK_VALUE are new for v2.20 */
-#define CKA_CERTIFICATE_CATEGORY 0x00000087
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
-#define CKA_URL 0x00000089
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
-#define CKA_CHECK_VALUE 0x00000090
-
-#define CKA_KEY_TYPE 0x00000100
-#define CKA_SUBJECT 0x00000101
-#define CKA_ID 0x00000102
-#define CKA_SENSITIVE 0x00000103
-#define CKA_ENCRYPT 0x00000104
-#define CKA_DECRYPT 0x00000105
-#define CKA_WRAP 0x00000106
-#define CKA_UNWRAP 0x00000107
-#define CKA_SIGN 0x00000108
-#define CKA_SIGN_RECOVER 0x00000109
-#define CKA_VERIFY 0x0000010A
-#define CKA_VERIFY_RECOVER 0x0000010B
-#define CKA_DERIVE 0x0000010C
-#define CKA_START_DATE 0x00000110
-#define CKA_END_DATE 0x00000111
-#define CKA_MODULUS 0x00000120
-#define CKA_MODULUS_BITS 0x00000121
-#define CKA_PUBLIC_EXPONENT 0x00000122
-#define CKA_PRIVATE_EXPONENT 0x00000123
-#define CKA_PRIME_1 0x00000124
-#define CKA_PRIME_2 0x00000125
-#define CKA_EXPONENT_1 0x00000126
-#define CKA_EXPONENT_2 0x00000127
-#define CKA_COEFFICIENT 0x00000128
-#define CKA_PRIME 0x00000130
-#define CKA_SUBPRIME 0x00000131
-#define CKA_BASE 0x00000132
-
-/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-#define CKA_PRIME_BITS 0x00000133
-#define CKA_SUBPRIME_BITS 0x00000134
-#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
-/* (To retain backwards-compatibility) */
-
-#define CKA_VALUE_BITS 0x00000160
-#define CKA_VALUE_LEN 0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
- * and CKA_EC_POINT are new for v2.0 */
-#define CKA_EXTRACTABLE 0x00000162
-#define CKA_LOCAL 0x00000163
-#define CKA_NEVER_EXTRACTABLE 0x00000164
-#define CKA_ALWAYS_SENSITIVE 0x00000165
-
-/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-#define CKA_KEY_GEN_MECHANISM 0x00000166
-
-#define CKA_MODIFIABLE 0x00000170
-
-/* CKA_ECDSA_PARAMS is deprecated in v2.11,
- * CKA_EC_PARAMS is preferred. */
-#define CKA_ECDSA_PARAMS 0x00000180
-#define CKA_EC_PARAMS 0x00000180
-
-#define CKA_EC_POINT 0x00000181
-
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * are new for v2.10. Deprecated in v2.11 and onwards. */
-#define CKA_SECONDARY_AUTH 0x00000200
-#define CKA_AUTH_PIN_FLAGS 0x00000201
-
-/* CKA_ALWAYS_AUTHENTICATE ...
- * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-#define CKA_ALWAYS_AUTHENTICATE 0x00000202
-
-#define CKA_WRAP_WITH_TRUSTED 0x00000210
-#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
-#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
-
-/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
- * are new for v2.10 */
-#define CKA_HW_FEATURE_TYPE 0x00000300
-#define CKA_RESET_ON_INIT 0x00000301
-#define CKA_HAS_RESET 0x00000302
-
-/* The following attributes are new for v2.20 */
-#define CKA_PIXEL_X 0x00000400
-#define CKA_PIXEL_Y 0x00000401
-#define CKA_RESOLUTION 0x00000402
-#define CKA_CHAR_ROWS 0x00000403
-#define CKA_CHAR_COLUMNS 0x00000404
-#define CKA_COLOR 0x00000405
-#define CKA_BITS_PER_PIXEL 0x00000406
-#define CKA_CHAR_SETS 0x00000480
-#define CKA_ENCODING_METHODS 0x00000481
-#define CKA_MIME_TYPES 0x00000482
-#define CKA_MECHANISM_TYPE 0x00000500
-#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
-#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
-#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
-#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
-
-#define CKA_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
- CK_ATTRIBUTE_TYPE type;
- CK_VOID_PTR pValue;
-
- /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulValueLen; /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
- CK_CHAR year[4]; /* the year ("1900" - "9999") */
- CK_CHAR month[2]; /* the month ("01" - "12") */
- CK_CHAR day[2]; /* the day ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
-#define CKM_RSA_PKCS 0x00000001
-#define CKM_RSA_9796 0x00000002
-#define CKM_RSA_X_509 0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0. They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS 0x00000004
-#define CKM_MD5_RSA_PKCS 0x00000005
-#define CKM_SHA1_RSA_PKCS 0x00000006
-
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
- * CKM_RSA_PKCS_OAEP are new for v2.10 */
-#define CKM_RIPEMD128_RSA_PKCS 0x00000007
-#define CKM_RIPEMD160_RSA_PKCS 0x00000008
-#define CKM_RSA_PKCS_OAEP 0x00000009
-
-/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
- * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
-#define CKM_RSA_X9_31 0x0000000B
-#define CKM_SHA1_RSA_X9_31 0x0000000C
-#define CKM_RSA_PKCS_PSS 0x0000000D
-#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
-
-#define CKM_DSA_KEY_PAIR_GEN 0x00000010
-#define CKM_DSA 0x00000011
-#define CKM_DSA_SHA1 0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
-#define CKM_DH_PKCS_DERIVE 0x00000021
-
-/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
- * v2.11 */
-#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
-#define CKM_X9_42_DH_DERIVE 0x00000031
-#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
-#define CKM_X9_42_MQV_DERIVE 0x00000033
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_RSA_PKCS 0x00000040
-#define CKM_SHA384_RSA_PKCS 0x00000041
-#define CKM_SHA512_RSA_PKCS 0x00000042
-#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
-#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
-#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
-
-#define CKM_RC2_KEY_GEN 0x00000100
-#define CKM_RC2_ECB 0x00000101
-#define CKM_RC2_CBC 0x00000102
-#define CKM_RC2_MAC 0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL 0x00000104
-#define CKM_RC2_CBC_PAD 0x00000105
-
-#define CKM_RC4_KEY_GEN 0x00000110
-#define CKM_RC4 0x00000111
-#define CKM_DES_KEY_GEN 0x00000120
-#define CKM_DES_ECB 0x00000121
-#define CKM_DES_CBC 0x00000122
-#define CKM_DES_MAC 0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL 0x00000124
-#define CKM_DES_CBC_PAD 0x00000125
-
-#define CKM_DES2_KEY_GEN 0x00000130
-#define CKM_DES3_KEY_GEN 0x00000131
-#define CKM_DES3_ECB 0x00000132
-#define CKM_DES3_CBC 0x00000133
-#define CKM_DES3_MAC 0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL 0x00000135
-#define CKM_DES3_CBC_PAD 0x00000136
-#define CKM_CDMF_KEY_GEN 0x00000140
-#define CKM_CDMF_ECB 0x00000141
-#define CKM_CDMF_CBC 0x00000142
-#define CKM_CDMF_MAC 0x00000143
-#define CKM_CDMF_MAC_GENERAL 0x00000144
-#define CKM_CDMF_CBC_PAD 0x00000145
-
-/* the following four DES mechanisms are new for v2.20 */
-#define CKM_DES_OFB64 0x00000150
-#define CKM_DES_OFB8 0x00000151
-#define CKM_DES_CFB64 0x00000152
-#define CKM_DES_CFB8 0x00000153
-
-#define CKM_MD2 0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC 0x00000201
-#define CKM_MD2_HMAC_GENERAL 0x00000202
-
-#define CKM_MD5 0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC 0x00000211
-#define CKM_MD5_HMAC_GENERAL 0x00000212
-
-#define CKM_SHA_1 0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
- * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
- * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-#define CKM_RIPEMD128 0x00000230
-#define CKM_RIPEMD128_HMAC 0x00000231
-#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
-#define CKM_RIPEMD160 0x00000240
-#define CKM_RIPEMD160_HMAC 0x00000241
-#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256 0x00000250
-#define CKM_SHA256_HMAC 0x00000251
-#define CKM_SHA256_HMAC_GENERAL 0x00000252
-#define CKM_SHA384 0x00000260
-#define CKM_SHA384_HMAC 0x00000261
-#define CKM_SHA384_HMAC_GENERAL 0x00000262
-#define CKM_SHA512 0x00000270
-#define CKM_SHA512_HMAC 0x00000271
-#define CKM_SHA512_HMAC_GENERAL 0x00000272
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN 0x00000300
-#define CKM_CAST_ECB 0x00000301
-#define CKM_CAST_CBC 0x00000302
-#define CKM_CAST_MAC 0x00000303
-#define CKM_CAST_MAC_GENERAL 0x00000304
-#define CKM_CAST_CBC_PAD 0x00000305
-#define CKM_CAST3_KEY_GEN 0x00000310
-#define CKM_CAST3_ECB 0x00000311
-#define CKM_CAST3_CBC 0x00000312
-#define CKM_CAST3_MAC 0x00000313
-#define CKM_CAST3_MAC_GENERAL 0x00000314
-#define CKM_CAST3_CBC_PAD 0x00000315
-#define CKM_CAST5_KEY_GEN 0x00000320
-#define CKM_CAST128_KEY_GEN 0x00000320
-#define CKM_CAST5_ECB 0x00000321
-#define CKM_CAST128_ECB 0x00000321
-#define CKM_CAST5_CBC 0x00000322
-#define CKM_CAST128_CBC 0x00000322
-#define CKM_CAST5_MAC 0x00000323
-#define CKM_CAST128_MAC 0x00000323
-#define CKM_CAST5_MAC_GENERAL 0x00000324
-#define CKM_CAST128_MAC_GENERAL 0x00000324
-#define CKM_CAST5_CBC_PAD 0x00000325
-#define CKM_CAST128_CBC_PAD 0x00000325
-#define CKM_RC5_KEY_GEN 0x00000330
-#define CKM_RC5_ECB 0x00000331
-#define CKM_RC5_CBC 0x00000332
-#define CKM_RC5_MAC 0x00000333
-#define CKM_RC5_MAC_GENERAL 0x00000334
-#define CKM_RC5_CBC_PAD 0x00000335
-#define CKM_IDEA_KEY_GEN 0x00000340
-#define CKM_IDEA_ECB 0x00000341
-#define CKM_IDEA_CBC 0x00000342
-#define CKM_IDEA_MAC 0x00000343
-#define CKM_IDEA_MAC_GENERAL 0x00000344
-#define CKM_IDEA_CBC_PAD 0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
-#define CKM_XOR_BASE_AND_DATA 0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
-
-/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
- * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
-#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
-#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
-#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
-
-/* CKM_TLS_PRF is new for v2.20 */
-#define CKM_TLS_PRF 0x00000378
-
-#define CKM_SSL3_MD5_MAC 0x00000380
-#define CKM_SSL3_SHA1_MAC 0x00000381
-#define CKM_MD5_KEY_DERIVATION 0x00000390
-#define CKM_MD2_KEY_DERIVATION 0x00000391
-#define CKM_SHA1_KEY_DERIVATION 0x00000392
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_KEY_DERIVATION 0x00000393
-#define CKM_SHA384_KEY_DERIVATION 0x00000394
-#define CKM_SHA512_KEY_DERIVATION 0x00000395
-
-#define CKM_PBE_MD2_DES_CBC 0x000003A0
-#define CKM_PBE_MD5_DES_CBC 0x000003A1
-#define CKM_PBE_MD5_CAST_CBC 0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
-#define CKM_PBE_SHA1_RC4_128 0x000003A6
-#define CKM_PBE_SHA1_RC4_40 0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
-
-/* CKM_PKCS5_PBKD2 is new for v2.10 */
-#define CKM_PKCS5_PBKD2 0x000003B0
-
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
-
-/* WTLS mechanisms are new for v2.20 */
-#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
-#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
-#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
-#define CKM_WTLS_PRF 0x000003D3
-#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
-#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
-
-#define CKM_KEY_WRAP_LYNKS 0x00000400
-#define CKM_KEY_WRAP_SET_OAEP 0x00000401
-
-/* CKM_CMS_SIG is new for v2.20 */
-#define CKM_CMS_SIG 0x00000500
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN 0x00001000
-#define CKM_SKIPJACK_ECB64 0x00001001
-#define CKM_SKIPJACK_CBC64 0x00001002
-#define CKM_SKIPJACK_OFB64 0x00001003
-#define CKM_SKIPJACK_CFB64 0x00001004
-#define CKM_SKIPJACK_CFB32 0x00001005
-#define CKM_SKIPJACK_CFB16 0x00001006
-#define CKM_SKIPJACK_CFB8 0x00001007
-#define CKM_SKIPJACK_WRAP 0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
-#define CKM_SKIPJACK_RELAYX 0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN 0x00001010
-#define CKM_KEA_KEY_DERIVE 0x00001011
-#define CKM_FORTEZZA_TIMESTAMP 0x00001020
-#define CKM_BATON_KEY_GEN 0x00001030
-#define CKM_BATON_ECB128 0x00001031
-#define CKM_BATON_ECB96 0x00001032
-#define CKM_BATON_CBC128 0x00001033
-#define CKM_BATON_COUNTER 0x00001034
-#define CKM_BATON_SHUFFLE 0x00001035
-#define CKM_BATON_WRAP 0x00001036
-
-/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
- * CKM_EC_KEY_PAIR_GEN is preferred */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
-#define CKM_EC_KEY_PAIR_GEN 0x00001040
-
-#define CKM_ECDSA 0x00001041
-#define CKM_ECDSA_SHA1 0x00001042
-
-/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
- * are new for v2.11 */
-#define CKM_ECDH1_DERIVE 0x00001050
-#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
-#define CKM_ECMQV_DERIVE 0x00001052
-
-#define CKM_JUNIPER_KEY_GEN 0x00001060
-#define CKM_JUNIPER_ECB128 0x00001061
-#define CKM_JUNIPER_CBC128 0x00001062
-#define CKM_JUNIPER_COUNTER 0x00001063
-#define CKM_JUNIPER_SHUFFLE 0x00001064
-#define CKM_JUNIPER_WRAP 0x00001065
-#define CKM_FASTHASH 0x00001070
-
-/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
- * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
- * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
- * new for v2.11 */
-#define CKM_AES_KEY_GEN 0x00001080
-#define CKM_AES_ECB 0x00001081
-#define CKM_AES_CBC 0x00001082
-#define CKM_AES_MAC 0x00001083
-#define CKM_AES_MAC_GENERAL 0x00001084
-#define CKM_AES_CBC_PAD 0x00001085
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKM_BLOWFISH_KEY_GEN 0x00001090
-#define CKM_BLOWFISH_CBC 0x00001091
-#define CKM_TWOFISH_KEY_GEN 0x00001092
-#define CKM_TWOFISH_CBC 0x00001093
-
-
-/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
-#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
-#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
-#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
-#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
-#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
-
-#define CKM_DSA_PARAMETER_GEN 0x00002000
-#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
-#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
-
-#define CKM_VENDOR_DEFINED 0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism */
-typedef struct CK_MECHANISM {
- CK_MECHANISM_TYPE mechanism;
- CK_VOID_PTR pParameter;
-
- /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulParameterLen; /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
- CK_ULONG ulMinKeySize;
- CK_ULONG ulMaxKeySize;
- CK_FLAGS flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- * Bit Flag Mask Meaning */
-#define CKF_HW 0x00000001 /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0. They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT 0x00000100
-#define CKF_DECRYPT 0x00000200
-#define CKF_DIGEST 0x00000400
-#define CKF_SIGN 0x00000800
-#define CKF_SIGN_RECOVER 0x00001000
-#define CKF_VERIFY 0x00002000
-#define CKF_VERIFY_RECOVER 0x00004000
-#define CKF_GENERATE 0x00008000
-#define CKF_GENERATE_KEY_PAIR 0x00010000
-#define CKF_WRAP 0x00020000
-#define CKF_UNWRAP 0x00040000
-#define CKF_DERIVE 0x00080000
-
-/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
- * describe a token's EC capabilities not available in mechanism
- * information. */
-#define CKF_EC_F_P 0x00100000
-#define CKF_EC_F_2M 0x00200000
-#define CKF_EC_ECPARAMETERS 0x00400000
-#define CKF_EC_NAMEDCURVE 0x00800000
-#define CKF_EC_UNCOMPRESS 0x01000000
-#define CKF_EC_COMPRESS 0x02000000
-
-#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * Cryptoki function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_RV;
-
-#define CKR_OK 0x00000000
-#define CKR_CANCEL 0x00000001
-#define CKR_HOST_MEMORY 0x00000002
-#define CKR_SLOT_ID_INVALID 0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR 0x00000005
-#define CKR_FUNCTION_FAILED 0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD 0x00000007
-#define CKR_NO_EVENT 0x00000008
-#define CKR_NEED_TO_CREATE_THREADS 0x00000009
-#define CKR_CANT_LOCK 0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
-#define CKR_DATA_INVALID 0x00000020
-#define CKR_DATA_LEN_RANGE 0x00000021
-#define CKR_DEVICE_ERROR 0x00000030
-#define CKR_DEVICE_MEMORY 0x00000031
-#define CKR_DEVICE_REMOVED 0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
-#define CKR_FUNCTION_CANCELED 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
-
-#define CKR_KEY_HANDLE_INVALID 0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE 0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED 0x00000064
-#define CKR_KEY_CHANGED 0x00000065
-#define CKR_KEY_NEEDED 0x00000066
-#define CKR_KEY_INDIGESTIBLE 0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
-#define CKR_KEY_NOT_WRAPPABLE 0x00000069
-#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-
-#define CKR_MECHANISM_INVALID 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID 0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID 0x00000082
-#define CKR_OPERATION_ACTIVE 0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
-#define CKR_PIN_INCORRECT 0x000000A0
-#define CKR_PIN_INVALID 0x000000A1
-#define CKR_PIN_LEN_RANGE 0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED 0x000000A3
-#define CKR_PIN_LOCKED 0x000000A4
-
-#define CKR_SESSION_CLOSED 0x000000B0
-#define CKR_SESSION_COUNT 0x000000B1
-#define CKR_SESSION_HANDLE_INVALID 0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
-#define CKR_SESSION_READ_ONLY 0x000000B5
-#define CKR_SESSION_EXISTS 0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
-
-#define CKR_SIGNATURE_INVALID 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
-#define CKR_TOKEN_NOT_PRESENT 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
-#define CKR_USER_NOT_LOGGED_IN 0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
-#define CKR_USER_TYPE_INVALID 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
-#define CKR_USER_TOO_MANY_TYPES 0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID 0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG 0x00000121
-
-/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
-
-/* These are new to v2.0 */
-#define CKR_BUFFER_TOO_SMALL 0x00000150
-#define CKR_SAVED_STATE_INVALID 0x00000160
-#define CKR_INFORMATION_SENSITIVE 0x00000170
-#define CKR_STATE_UNSAVEABLE 0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
-#define CKR_MUTEX_BAD 0x000001A0
-#define CKR_MUTEX_NOT_LOCKED 0x000001A1
-
-/* This is new to v2.20 */
-#define CKR_FUNCTION_REJECTED 0x00000200
-
-#define CKR_VENDOR_DEFINED 0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_NOTIFICATION event,
- CK_VOID_PTR pApplication /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
- * version and pointers of appropriate types to all the
- * Cryptoki functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
- CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
- CK_CREATEMUTEX CreateMutex;
- CK_DESTROYMUTEX DestroyMutex;
- CK_LOCKMUTEX LockMutex;
- CK_UNLOCKMUTEX UnlockMutex;
- CK_FLAGS flags;
- CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK 0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK 1
-
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
- * scheme. */
-typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-
-typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-
-/* The following MGFs are defined */
-/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
- * are new for v2.20 */
-#define CKG_MGF1_SHA1 0x00000001
-#define CKG_MGF1_SHA256 0x00000002
-#define CKG_MGF1_SHA384 0x00000003
-#define CKG_MGF1_SHA512 0x00000004
-
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
- * of the encoding parameter when formatting a message block
- * for the PKCS #1 OAEP encryption scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-
-typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-
-/* The following encoding parameter sources are defined */
-#define CKZ_DATA_SPECIFIED 0x00000001
-
-/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism. */
-typedef struct CK_RSA_PKCS_OAEP_PARAMS {
- CK_MECHANISM_TYPE hashAlg;
- CK_RSA_PKCS_MGF_TYPE mgf;
- CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
- CK_VOID_PTR pSourceData;
- CK_ULONG ulSourceDataLen;
-} CK_RSA_PKCS_OAEP_PARAMS;
-
-typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
- * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_PSS mechanism(s). */
-typedef struct CK_RSA_PKCS_PSS_PARAMS {
- CK_MECHANISM_TYPE hashAlg;
- CK_RSA_PKCS_MGF_TYPE mgf;
- CK_ULONG sLen;
-} CK_RSA_PKCS_PSS_PARAMS;
-
-typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-
-/* CK_EC_KDF_TYPE is new for v2.11. */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-
-/* The following EC Key Derivation Functions are defined */
-#define CKD_NULL 0x00000001
-#define CKD_SHA1_KDF 0x00000002
-
-/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
- * where each party contributes one key pair.
- */
-typedef struct CK_ECDH1_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
-
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-
-
-/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-typedef struct CK_ECDH2_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
-} CK_ECDH2_DERIVE_PARAMS;
-
-typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_ECMQV_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
- CK_OBJECT_HANDLE publicKey;
-} CK_ECMQV_DERIVE_PARAMS;
-
-typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-
-/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
- * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-
-/* The following X9.42 DH key derivation functions are defined
- (besides CKD_NULL already defined : */
-#define CKD_SHA1_KDF_ASN1 0x00000003
-#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-
-/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
- * contributes one key pair */
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_X9_42_DH1_DERIVE_PARAMS;
-
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-
-/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
- * mechanisms, where each party contributes two key pairs */
-typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
-} CK_X9_42_DH2_DERIVE_PARAMS;
-
-typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
- CK_OBJECT_HANDLE publicKey;
-} CK_X9_42_MQV_DERIVE_PARAMS;
-
-typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
- CK_BBOOL isSender;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pRandomB;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
- /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-
- CK_BYTE iv[8]; /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_BYTE_PTR pIv; /* pointer to IV */
- CK_ULONG ulIvLen; /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms. Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
- CK_BYTE iv[8];
- CK_BYTE_PTR pData;
- CK_ULONG length;
-} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
- CK_BYTE iv[16];
- CK_BYTE_PTR pData;
- CK_ULONG length;
-} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pPassword;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPAndGLen;
- CK_ULONG ulQLen;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pPrimeP;
- CK_BYTE_PTR pBaseG;
- CK_BYTE_PTR pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
- CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
- CK_ULONG ulOldWrappedXLen;
- CK_BYTE_PTR pOldWrappedX;
- CK_ULONG ulOldPasswordLen;
- CK_BYTE_PTR pOldPassword;
- CK_ULONG ulOldPublicDataLen;
- CK_BYTE_PTR pOldPublicData;
- CK_ULONG ulOldRandomLen;
- CK_BYTE_PTR pOldRandomA;
- CK_ULONG ulNewPasswordLen;
- CK_BYTE_PTR pNewPassword;
- CK_ULONG ulNewPublicDataLen;
- CK_BYTE_PTR pNewPublicData;
- CK_ULONG ulNewRandomLen;
- CK_BYTE_PTR pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
- CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
- CK_BYTE_PTR pInitVector;
- CK_UTF8CHAR_PTR pPassword;
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_ULONG ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
- CK_BYTE bBC; /* block contents byte */
- CK_BYTE_PTR pX; /* extra data */
- CK_ULONG ulXLen; /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
- CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hClientMacSecret;
- CK_OBJECT_HANDLE hServerMacSecret;
- CK_OBJECT_HANDLE hClientKey;
- CK_OBJECT_HANDLE hServerKey;
- CK_BYTE_PTR pIVClient;
- CK_BYTE_PTR pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_BBOOL bIsExport;
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-typedef struct CK_TLS_PRF_PARAMS {
- CK_BYTE_PTR pSeed;
- CK_ULONG ulSeedLen;
- CK_BYTE_PTR pLabel;
- CK_ULONG ulLabelLen;
- CK_BYTE_PTR pOutput;
- CK_ULONG_PTR pulOutputLen;
-} CK_TLS_PRF_PARAMS;
-
-typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-
-/* WTLS is new for version 2.20 */
-typedef struct CK_WTLS_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_WTLS_RANDOM_DATA;
-
-typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-
-typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_WTLS_RANDOM_DATA RandomInfo;
- CK_BYTE_PTR pVersion;
-} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-
-typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-typedef struct CK_WTLS_PRF_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_BYTE_PTR pSeed;
- CK_ULONG ulSeedLen;
- CK_BYTE_PTR pLabel;
- CK_ULONG ulLabelLen;
- CK_BYTE_PTR pOutput;
- CK_ULONG_PTR pulOutputLen;
-} CK_WTLS_PRF_PARAMS;
-
-typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hMacSecret;
- CK_OBJECT_HANDLE hKey;
- CK_BYTE_PTR pIV;
-} CK_WTLS_KEY_MAT_OUT;
-
-typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_ULONG ulSequenceNumber;
- CK_BBOOL bIsExport;
- CK_WTLS_RANDOM_DATA RandomInfo;
- CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_WTLS_KEY_MAT_PARAMS;
-
-typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-
-/* CMS is new for version 2.20 */
-typedef struct CK_CMS_SIG_PARAMS {
- CK_OBJECT_HANDLE certificateHandle;
- CK_MECHANISM_PTR pSigningMechanism;
- CK_MECHANISM_PTR pDigestMechanism;
- CK_UTF8CHAR_PTR pContentType;
- CK_BYTE_PTR pRequestedAttributes;
- CK_ULONG ulRequestedAttributesLen;
- CK_BYTE_PTR pRequiredAttributes;
- CK_ULONG ulRequiredAttributesLen;
-} CK_CMS_SIG_PARAMS;
-
-typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
- CK_BYTE_PTR pData;
- CK_ULONG ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
- CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
- * key bits using PKCS #5 PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-
-typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-
-/* The following PRFs are defined in PKCS #5 v2.0. */
-#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
-
-/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
- * PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-
-typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-
-/* The following salt value sources are defined in PKCS #5 v2.0. */
-#define CKZ_SALT_SPECIFIED 0x00000001
-
-/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
- * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-typedef struct CK_PKCS5_PBKD2_PARAMS {
- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
- CK_VOID_PTR pSaltSourceData;
- CK_ULONG ulSaltSourceDataLen;
- CK_ULONG iterations;
- CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
- CK_VOID_PTR pPrfData;
- CK_ULONG ulPrfDataLen;
- CK_UTF8CHAR_PTR pPassword;
- CK_ULONG_PTR ulPasswordLen;
-} CK_PKCS5_PBKD2_PARAMS;
-
-typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-#endif
diff --git a/programs/pluto/rsaref/unix.h b/programs/pluto/rsaref/unix.h
deleted file mode 100644
index 2e7eb6663..000000000
--- a/programs/pluto/rsaref/unix.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-#ifndef UNIX_H
-#define UNIX_H
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
- returnType name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
- returnType name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- returnType (* name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
- returnType (* name)
-
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#endif
diff --git a/programs/pluto/server.c b/programs/pluto/server.c
deleted file mode 100644
index 17b70eba4..000000000
--- a/programs/pluto/server.c
+++ /dev/null
@@ -1,1001 +0,0 @@
-/* get-next-event loop
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: server.c,v 1.10 2007/01/29 08:27:19 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#ifdef SOLARIS
-# include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
-#endif
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "connections.h"
-#include "kernel.h"
-#include "log.h"
-#include "server.h"
-#include "timer.h"
-#include "packet.h"
-#include "demux.h" /* needs packet.h */
-#include "rcv_whack.h"
-#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-#include <pfkeyv2.h>
-#include <pfkey.h>
-#include "kameipsec.h"
-
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-/*
- * Server main loop and socket initialization routines.
- */
-
-static const int on = TRUE; /* by-reference parameter; constant, we hope */
-
-/* control (whack) socket */
-int ctl_fd = NULL_FD; /* file descriptor of control (whack) socket */
-struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
-
-/* info (showpolicy) socket */
-int policy_fd = NULL_FD;
-struct sockaddr_un info_addr= { AF_UNIX, DEFAULT_CTLBASE INFO_SUFFIX };
-
-/* Initialize the control socket.
- * Note: this is called very early, so little infrastructure is available.
- * It is important that the socket is created before the original
- * Pluto process returns.
- */
-err_t
-init_ctl_socket(void)
-{
- err_t failed = NULL;
-
- delete_ctl_socket(); /* preventative medicine */
- ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ctl_fd == -1)
- failed = "create";
- else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
- failed = "fcntl FD+CLOEXEC";
- else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
- failed = "setsockopt";
- else
- {
- /* to keep control socket secure, use umask */
- mode_t ou = umask(~S_IRWXU);
-
- if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
- , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- failed = "bind";
- umask(ou);
- }
-
- /* 5 is a haphazardly chosen limit for the backlog.
- * Rumour has it that this is the max on BSD systems.
- */
- if (failed == NULL && listen(ctl_fd, 5) < 0)
- failed = "listen() on";
-
- return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
- , failed, errno, strerror(errno));
-}
-
-void
-delete_ctl_socket(void)
-{
- /* Is noting failure useful? Not when used as preventative medicine. */
- unlink(ctl_addr.sun_path);
-}
-
-bool listening = FALSE; /* should we pay attention to IKE messages? */
-
-struct iface *interfaces = NULL; /* public interfaces */
-
-/* Initialize the interface sockets. */
-
-static void
-mark_ifaces_dead(void)
-{
- struct iface *p;
-
- for (p = interfaces; p != NULL; p = p->next)
- p->change = IFN_DELETE;
-}
-
-static void
-free_dead_ifaces(void)
-{
- struct iface *p;
- bool some_dead = FALSE
- , some_new = FALSE;
-
- for (p = interfaces; p != NULL; p = p->next)
- {
- if (p->change == IFN_DELETE)
- {
- plog("shutting down interface %s/%s %s"
- , p->vname, p->rname, ip_str(&p->addr));
- some_dead = TRUE;
- }
- else if (p->change == IFN_ADD)
- {
- some_new = TRUE;
- }
- }
-
- if (some_dead)
- {
- struct iface **pp;
-
- release_dead_interfaces();
- for (pp = &interfaces; (p = *pp) != NULL; )
- {
- if (p->change == IFN_DELETE)
- {
- *pp = p->next; /* advance *pp */
- pfree(p->vname);
- pfree(p->rname);
- close(p->fd);
- pfree(p);
- }
- else
- {
- pp = &p->next; /* advance pp */
- }
- }
- }
-
- /* this must be done after the release_dead_interfaces
- * in case some to the newly unoriented connections can
- * become oriented here.
- */
- if (some_dead || some_new)
- check_orientations();
-}
-
-void
-free_ifaces(void)
-{
- mark_ifaces_dead();
- free_dead_ifaces();
-}
-
-struct raw_iface {
- ip_address addr;
- char name[IFNAMSIZ + 20]; /* what would be a safe size? */
- struct raw_iface *next;
-};
-
-/* Called to handle --interface <ifname>
- * Semantics: if specified, only these (real) interfaces are considered.
- */
-static const char *pluto_ifn[10];
-static int pluto_ifn_roof = 0;
-
-bool
-use_interface(const char *rifn)
-{
- if (pluto_ifn_roof >= (int)elemsof(pluto_ifn))
- {
- return FALSE;
- }
- else
- {
- pluto_ifn[pluto_ifn_roof++] = rifn;
- return TRUE;
- }
-}
-
-#ifndef IPSECDEVPREFIX
-# define IPSECDEVPREFIX "ipsec"
-#endif
-
-static struct raw_iface *
-find_raw_ifaces4(void)
-{
- int j; /* index into buf */
- struct ifconf ifconf;
- struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
- struct raw_iface *rifaces = NULL;
- int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
-
- /* get list of interfaces with assigned IPv4 addresses from system */
-
- if (master_sock == -1)
- exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
-
- if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
-
- /* bind the socket */
- {
- ip_address any;
-
- happy(anyaddr(AF_INET, &any));
- setportof(htons(pluto_port), &any);
- if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
- exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
- }
-
- /* Get local interfaces. See netdevice(7). */
- ifconf.ifc_len = sizeof(buf);
- ifconf.ifc_buf = (void *) buf;
- zero(buf);
-
- if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
- exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
- /* Add an entry to rifaces for each interesting interface. */
- for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
- {
- struct raw_iface ri;
- const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
- struct ifreq auxinfo;
-
- /* ignore all but AF_INET interfaces */
- if (rs->sin_family != AF_INET)
- continue; /* not interesting */
-
- /* build a NUL-terminated copy of the rname field */
- memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
- ri.name[IFNAMSIZ] = '\0';
-
- /* ignore if our interface names were specified, and this isn't one */
- if (pluto_ifn_roof != 0)
- {
- int i;
-
- for (i = 0; i != pluto_ifn_roof; i++)
- if (streq(ri.name, pluto_ifn[i]))
- break;
- if (i == pluto_ifn_roof)
- continue; /* not found -- skip */
- }
-
- /* Find out stuff about this interface. See netdevice(7). */
- zero(&auxinfo); /* paranoia */
- memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
- if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
- exit_log_errno((e
- , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
- , ri.name));
- if (!(auxinfo.ifr_flags & IFF_UP))
- continue; /* ignore an interface that isn't UP */
-
- /* ignore unconfigured interfaces */
- if (rs->sin_addr.s_addr == 0)
- continue;
-
- happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
- , AF_INET, &ri.addr));
-
- DBG(DBG_CONTROL, DBG_log("found %s with address %s"
- , ri.name, ip_str(&ri.addr)));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
-
- close(master_sock);
-
- return rifaces;
-}
-
-static struct raw_iface *
-find_raw_ifaces6(void)
-{
-
- /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
- *
- * Documentation of format?
- * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
- * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
- *
- * Sample from Gerhard's laptop:
- * 00000000000000000000000000000001 01 80 10 80 lo
- * 30490009000000000000000000010002 02 40 00 80 ipsec0
- * 30490009000000000000000000010002 07 40 00 80 eth0
- * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
- * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
- *
- * Each line contains:
- * - IPv6 address: 16 bytes, in hex, no punctuation
- * - ifindex: 1 byte, in hex
- * - prefix_len: 1 byte, in hex
- * - scope (e.g. global, link local): 1 byte, in hex
- * - flags: 1 byte, in hex
- * - device name: string, followed by '\n'
- */
- struct raw_iface *rifaces = NULL;
- static const char proc_name[] = "/proc/net/if_inet6";
- FILE *proc_sock = fopen(proc_name, "r");
-
- if (proc_sock == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
- }
- else
- {
- for (;;)
- {
- struct raw_iface ri;
- unsigned short xb[8]; /* IPv6 address as 8 16-bit chunks */
- char sb[8*5]; /* IPv6 address as string-with-colons */
- unsigned int if_idx; /* proc field, not used */
- unsigned int plen; /* proc field, not used */
- unsigned int scope; /* proc field, used to exclude link-local */
- unsigned int dad_status; /* proc field, not used */
- /* ??? I hate and distrust scanf -- DHR */
- int r = fscanf(proc_sock
- , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
- " %02x %02x %02x %02x %20s\n"
- , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
- , &if_idx, &plen, &scope, &dad_status, ri.name);
-
- /* ??? we should diagnose any problems */
- if (r != 13)
- break;
-
- /* ignore addresses with link local scope.
- * From linux-2.4.9-13/include/net/ipv6.h:
- * IPV6_ADDR_LINKLOCAL 0x0020U
- * IPV6_ADDR_SCOPE_MASK 0x00f0U
- */
- if ((scope & 0x00f0U) == 0x0020U)
- continue;
-
- snprintf(sb, sizeof(sb)
- , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
- , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
-
- happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
-
- if (!isunspecaddr(&ri.addr))
- {
- DBG(DBG_CONTROL
- , DBG_log("found %s with address %s"
- , ri.name, sb));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
- }
- fclose(proc_sock);
- }
-
- return rifaces;
-}
-
-#if 1
-static int
-create_socket(struct raw_iface *ifp, const char *v_name, int port)
-{
- int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
- int fcntl_flags;
-
- if (fd < 0)
- {
- log_errno((e, "socket() in process_raw_ifaces()"));
- return -1;
- }
-
-#if 1
- /* Set socket Nonblocking */
- if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
- if (!(fcntl_flags & O_NONBLOCK)) {
- fcntl_flags |= O_NONBLOCK;
- fcntl(fd, F_SETFL, fcntl_flags);
- }
- }
-#endif
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- {
- log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- /* To improve error reporting. See ip(7). */
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- if (setsockopt(fd, SOL_IP, IP_RECVERR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-#endif
-
- /* With IPv6, there is no fragmentation after
- * it leaves our interface. PMTU discovery
- * is mandatory but doesn't work well with IKE (why?).
- * So we must set the IPV6_USE_MIN_MTU option.
- * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
- */
-#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
- if (addrtypeof(&ifp->addr) == AF_INET6
- && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-#endif
-
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- struct sadb_x_policy policy;
- int level, opt;
-
- policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- policy.sadb_x_policy_reserved = 0;
- policy.sadb_x_policy_id = 0;
- policy.sadb_x_policy_reserved2 = 0;
-
- if (addrtypeof(&ifp->addr) == AF_INET6)
- {
- level = IPPROTO_IPV6;
- opt = IPV6_IPSEC_POLICY;
- }
- else
- {
- level = IPPROTO_IP;
- opt = IP_IPSEC_POLICY;
- }
-
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
- {
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
-
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
- {
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
- }
-#endif
-
- setportof(htons(port), &ifp->addr);
- if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
- {
- log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
- , ifp->name, v_name
- , ip_str(&ifp->addr), (unsigned) port));
- close(fd);
- return -1;
- }
- setportof(htons(pluto_port), &ifp->addr);
- return fd;
-}
-#endif
-
-static void
-process_raw_ifaces(struct raw_iface *rifaces)
-{
- struct raw_iface *ifp;
-
- /* Find all virtual/real interface pairs.
- * For each real interface...
- */
- for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
- {
- struct raw_iface *v = NULL; /* matching ipsecX interface */
- struct raw_iface fake_v;
- bool after = FALSE; /* has vfp passed ifp on the list? */
- bool bad = FALSE;
- struct raw_iface *vfp;
-
- /* ignore if virtual (ipsec*) interface */
- if (strncmp(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
- continue;
-
- for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
- {
- if (vfp == ifp)
- {
- after = TRUE;
- }
- else if (sameaddr(&ifp->addr, &vfp->addr))
- {
- /* Different entries with matching IP addresses.
- * Many interesting cases.
- */
- if (strncmp(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
- {
- if (v != NULL && !streq(v->name, vfp->name))
- {
- loglog(RC_LOG_SERIOUS
- , "ipsec interfaces %s and %s share same address %s"
- , v->name, vfp->name, ip_str(&ifp->addr));
- bad = TRUE;
- }
- else
- {
- v = vfp; /* current winner */
- }
- }
- else
- {
- /* ugh: a second real interface with the same IP address
- * "after" allows us to avoid double reporting.
- */
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- if (after)
- {
- bad = TRUE;
- break;
- }
- continue;
- }
-#endif
- if (after)
- {
- loglog(RC_LOG_SERIOUS
- , "IP interfaces %s and %s share address %s!"
- , ifp->name, vfp->name, ip_str(&ifp->addr));
- }
- bad = TRUE;
- }
- }
- }
-
- if (bad)
- continue;
-
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- v = ifp;
- goto add_entry;
- }
-#endif
-
- /* what if we didn't find a virtual interface? */
- if (v == NULL)
- {
- if (no_klips)
- {
- /* kludge for testing: invent a virtual device */
- static const char fvp[] = "virtual";
- fake_v = *ifp;
- passert(sizeof(fake_v.name) > sizeof(fvp));
- strcpy(fake_v.name, fvp);
- addrtot(&ifp->addr, 0, fake_v.name + sizeof(fvp) - 1
- , sizeof(fake_v.name) - (sizeof(fvp) - 1));
- v = &fake_v;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
- , ifp->name, ip_str(&ifp->addr)));
- continue;
- }
- }
-
- /* We've got all we need; see if this is a new thing:
- * search old interfaces list.
- */
-#if defined(linux) && defined(KERNEL26_SUPPORT)
-add_entry:
-#endif
- {
- struct iface **p = &interfaces;
-
- for (;;)
- {
- struct iface *q = *p;
-
- /* search is over if at end of list */
- if (q == NULL)
- {
- /* matches nothing -- create a new entry */
- int fd = create_socket(ifp, v->name, pluto_port);
-
- if (fd < 0)
- break;
-
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_support_non_ike
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
- }
-#endif
-
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- interfaces = q;
- plog("adding interface %s/%s %s:%d"
- , q->vname, q->rname, ip_str(&q->addr), pluto_port);
-#ifdef NAT_TRAVERSAL
- if (nat_traversal_support_port_floating
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
- if (fd < 0)
- break;
- nat_traversal_espinudp_socket(fd,
- ESPINUDP_WITH_NON_ESP);
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- q->ike_float = TRUE;
- interfaces = q;
- plog("adding interface %s/%s %s:%d",
- q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
- }
-#endif
- break;
- }
-
- /* search over if matching old entry found */
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr))
- {
- /* matches -- rejuvinate old entry */
- q->change = IFN_KEEP;
-#ifdef NAT_TRAVERSAL
- /* look for other interfaces to keep (due to NAT-T) */
- for (q = q->next ; q ; q = q->next) {
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr)) {
- q->change = IFN_KEEP;
- }
- }
-#endif
- break;
- }
-
- /* try again */
- p = &q->next;
- } /* for (;;) */
- }
- }
-
- /* delete the raw interfaces list */
- while (rifaces != NULL)
- {
- struct raw_iface *t = rifaces;
-
- rifaces = t->next;
- pfree(t);
- }
-}
-
-void
-find_ifaces(void)
-{
- mark_ifaces_dead();
- process_raw_ifaces(find_raw_ifaces4());
- process_raw_ifaces(find_raw_ifaces6());
-
- free_dead_ifaces(); /* ditch remaining old entries */
-
- if (interfaces == NULL)
- loglog(RC_LOG_SERIOUS, "no public interfaces found");
-}
-
-void
-show_ifaces_status(void)
-{
- struct iface *p;
-
- for (p = interfaces; p != NULL; p = p->next)
- whack_log(RC_COMMENT, "interface %s/%s %s:%d"
- , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
-}
-
-void
-show_debug_status(void)
-{
-#ifdef DEBUG
- whack_log(RC_COMMENT, "debug %s"
- , bitnamesof(debug_bit_names, cur_debugging));
-#endif
-}
-
-static volatile sig_atomic_t sighupflag = FALSE;
-
-static void
-huphandler(int sig UNUSED)
-{
- sighupflag = TRUE;
-}
-
-static volatile sig_atomic_t sigtermflag = FALSE;
-
-static void
-termhandler(int sig UNUSED)
-{
- sigtermflag = TRUE;
-}
-
-/* call_server listens for incoming ISAKMP packets and Whack messages,
- * and handles timer events.
- */
-void
-call_server(void)
-{
- struct iface *ifp;
-
- /* catch SIGHUP and SIGTERM */
- {
- int r;
- struct sigaction act;
-
- act.sa_handler = &huphandler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
- r = sigaction(SIGHUP, &act, NULL);
- passert(r == 0);
-
- act.sa_handler = &termhandler;
- r = sigaction(SIGTERM, &act, NULL);
- passert(r == 0);
- }
-
- for (;;)
- {
- fd_set readfds;
- fd_set writefds;
- int ndes;
-
- /* wait for next interesting thing */
-
- for (;;)
- {
- long next_time = next_event(); /* time to any pending timer event */
- int maxfd = ctl_fd;
-
- if (sigtermflag)
- exit_pluto(0);
-
- if (sighupflag)
- {
- /* Ignorant folks think poking any daemon with SIGHUP
- * is polite. We catch it and tell them otherwise.
- * There is one use: unsticking a hung recvfrom.
- * This sticking happens sometimes -- kernel bug?
- */
- sighupflag = FALSE;
- plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
- }
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_SET(ctl_fd, &readfds);
-
- /* the only write file-descriptor of interest */
- if (adns_qfd != NULL_FD && unsent_ADNS_queries)
- {
- if (maxfd < adns_qfd)
- maxfd = adns_qfd;
- FD_SET(adns_qfd, &writefds);
- }
-
- if (adns_afd != NULL_FD)
- {
- if (maxfd < adns_afd)
- maxfd = adns_afd;
- FD_SET(adns_afd, &readfds);
- }
-
-#ifdef KLIPS
- if (!no_klips)
- {
- int fd = *kernel_ops->async_fdp;
-
- if (kernel_ops->process_queue)
- kernel_ops->process_queue();
- if (maxfd < fd)
- maxfd = fd;
- passert(!FD_ISSET(fd, &readfds));
- FD_SET(fd, &readfds);
- }
-#endif
-
- if (listening)
- {
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (maxfd < ifp->fd)
- maxfd = ifp->fd;
- passert(!FD_ISSET(ifp->fd, &readfds));
- FD_SET(ifp->fd, &readfds);
- }
- }
-
- if (next_time == -1)
- {
- /* select without timer */
-
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
- }
- else if (next_time == 0)
- {
- /* timer without select: there is a timer event pending,
- * and it should fire now so don't bother to do the select.
- */
- ndes = 0; /* signify timer expiration */
- }
- else
- {
- /* select with timer */
-
- struct timeval tm;
-
- tm.tv_sec = next_time;
- tm.tv_usec = 0;
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
- }
-
- if (ndes != -1)
- break; /* success */
-
- if (errno != EINTR)
- exit_log_errno((e, "select() failed in call_server()"));
-
- /* retry if terminated by signal */
- }
-
- /* figure out what is interesting */
-
- if (ndes == 0)
- {
- /* timer event */
-
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*time to handle event"));
-
- handle_timer_event();
- passert(GLOBALS_ARE_RESET());
- }
- else
- {
- /* at least one file descriptor is ready */
-
- if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
- {
- passert(ndes > 0);
- send_unsent_ADNS_queries();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received adns message"));
- handle_adns_answer();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
-#ifdef KLIPS
- if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received kernel message"));
- kernel_ops->process_msg();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-#endif
-
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (FD_ISSET(ifp->fd, &readfds))
- {
- /* comm_handle will print DBG_CONTROL intro,
- * with more info than we have here.
- */
-
- passert(ndes > 0);
- comm_handle(ifp);
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
- }
-
- if (FD_ISSET(ctl_fd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received whack message"));
- whack_handle(ctl_fd);
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- passert(ndes == 0);
- }
- }
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 4
- * End Variables:
- */
diff --git a/programs/pluto/server.h b/programs/pluto/server.h
deleted file mode 100644
index aa14d5aaa..000000000
--- a/programs/pluto/server.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* get-next-event loop
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: server.h,v 1.2 2004/03/22 21:53:20 as Exp $
- */
-
-extern int ctl_fd; /* file descriptor of control (whack) socket */
-extern struct sockaddr_un ctl_addr; /* address of control (whack) socket */
-
-extern int info_fd; /* file descriptor of control (info) socket */
-extern struct sockaddr_un info_addr; /* address of control (info) socket */
-
-extern err_t init_ctl_socket(void);
-extern void delete_ctl_socket(void);
-
-extern bool listening; /* should we pay attention to IKE messages? */
-
-
-/* interface: a terminal point for IKE traffic, IPsec transport mode
- * and IPsec tunnels.
- * Essentially:
- * - an IP device (eg. eth1), and
- * - its partner, an ipsec device (eg. ipsec0), and
- * - their shared IP address (eg. 10.7.3.2)
- * Note: the port for IKE is always implicitly UDP/pluto_port.
- */
-struct iface {
- char *vname; /* virtual (ipsec) device name */
- char *rname; /* real device name */
- ip_address addr; /* interface IP address */
- int fd; /* file descriptor of socket for IKE UDP messages */
- struct iface *next;
-#ifdef NAT_TRAVERSAL
- bool ike_float;
-#endif
- enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
-};
-
-extern struct iface *interfaces; /* public interfaces */
-
-extern bool use_interface(const char *rifn);
-extern void find_ifaces(void);
-extern void show_ifaces_status(void);
-extern void free_ifaces(void);
-extern void show_debug_status(void);
-extern void call_server(void);
-
-/* in rcv_info.c */
-extern err_t init_info_socket(void);
-extern void delete_info_socket(void);
diff --git a/programs/pluto/sha1.c b/programs/pluto/sha1.c
deleted file mode 100644
index bbf062876..000000000
--- a/programs/pluto/sha1.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-
-Test Vectors (from FIPS PUB 180-1)
-"abc"
- A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
- 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-#define SHA1HANDSOFF
-
-#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
-#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
-
-#include "sha1.h"
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF))
-#elif BYTE_ORDER == BIG_ENDIAN
-#define blk0(i) block->l[i]
-#else
-#error "Endianness not defined!"
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
-{
-u_int32_t a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- u_int32_t l[16];
-} CHAR64LONG16;
-#ifdef SHA1HANDSOFF
-CHAR64LONG16 block[1]; /* use array to appear as a pointer */
- memcpy(block, buffer, 64);
-#else
- /* The following had better never be used because it causes the
- * pointer-to-const buffer to be cast into a pointer to non-const.
- * And the result is written through. I threw a "const" in, hoping
- * this will cause a diagnostic.
- */
-CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
-#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
-#ifdef SHA1HANDSOFF
- memset(block, '\0', sizeof(block));
-#endif
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(SHA1_CTX* context)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
-{
-u_int32_t i;
-u_int32_t j;
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1]++;
- context->count[1] += (len>>29);
- j = (j >> 3) & 63;
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-unsigned i;
-unsigned char finalcount[8];
-unsigned char c;
-
-#if 0 /* untested "improvement" by DHR */
- /* Convert context->count to a sequence of bytes
- * in finalcount. Second element first, but
- * big-endian order within element.
- * But we do it all backwards.
- */
- unsigned char *fcp = &finalcount[8];
-
- for (i = 0; i < 2; i++)
- {
- u_int32_t t = context->count[i];
- int j;
-
- for (j = 0; j < 4; t >>= 8, j++)
- *--fcp = (unsigned char) t
- }
-#else
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
-#endif
- c = 0200;
- SHA1Update(context, &c, 1);
- while ((context->count[0] & 504) != 448) {
- c = 0000;
- SHA1Update(context, &c, 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- /* Wipe variables */
- memset(context, '\0', sizeof(*context));
- memset(&finalcount, '\0', sizeof(finalcount));
-}
diff --git a/programs/pluto/sha1.h b/programs/pluto/sha1.h
deleted file mode 100644
index 64b3d2f5d..000000000
--- a/programs/pluto/sha1.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-*/
-
-typedef struct {
- u_int32_t state[5];
- u_int32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
-void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
diff --git a/programs/pluto/smallprime.c b/programs/pluto/smallprime.c
deleted file mode 100644
index 87497d096..000000000
--- a/programs/pluto/smallprime.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* smallprime.c - List of small primes
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "gcryptfix.h"
-#else
-/* #include <config.h> */
-/* #include <stdio.h> */
-/* #include <stdlib.h> */
-/* #include "util.h" */
-/* #include "types.h" */
-#endif
-
-/* Note: 2 is not included because it can be tested more easily
- * by looking at bit 0. The last entry in this list is marked by a zero
- */
-ushort
-small_prime_numbers[] = {
- 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
- 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
- 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
- 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
- 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
- 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
- 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
- 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
- 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
- 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
- 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
- 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
- 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
- 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
- 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
- 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
- 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
- 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
- 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
- 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
- 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
- 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
- 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
- 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
- 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
- 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
- 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
- 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
- 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
- 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
- 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
- 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
- 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
- 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
- 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
- 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
- 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
- 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
- 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
- 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
- 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
- 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
- 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
- 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
- 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
- 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
- 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
- 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
- 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
- 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
- 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
- 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
- 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
- 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
- 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
- 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
- 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
- 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
- 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
- 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
- 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
- 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
- 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
- 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
- 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
- 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
- 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
- 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
- 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
- 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
- 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
- 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
- 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
- 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
- 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
- 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
- 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
- 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
- 4957, 4967, 4969, 4973, 4987, 4993, 4999,
- 0
-};
-
-
diff --git a/programs/pluto/smartcard.c b/programs/pluto/smartcard.c
deleted file mode 100644
index f1994f1cf..000000000
--- a/programs/pluto/smartcard.c
+++ /dev/null
@@ -1,1956 +0,0 @@
-/* Support of smartcards and cryptotokens
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2004 David Buechi, Michael Meier
- * Zuercher Hochschule Winterthur, Switzerland
- *
- * Copyright (C) 2005 Michael Joosten
- *
- * Copyright (C) 2005 Andreas Steffen
- * Hochschule für Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: smartcard.c,v 1.41 2006/01/04 21:03:52 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <dlfcn.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-
-#ifdef SMARTCARD
-#include "rsaref/unix.h"
-#include "rsaref/pkcs11.h"
-#endif
-
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-#include "x509.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "smartcard.h"
-#include "whack.h"
-#include "fetch.h"
-
-#define DEFAULT_BASE 16
-
-/* chained list of smartcard records */
-static smartcard_t *smartcards = NULL;
-
-/* number of generated sc objects */
-static int sc_number = 0;
-
-const smartcard_t empty_sc = {
- NULL , /* next */
- 0 , /* last_load */
- { CERT_NONE, {NULL} }, /* last_cert */
- 0 , /* count */
- 0 , /* number */
- 999999 , /* slot */
- NULL , /* id */
- NULL , /* label */
- { NULL, 0 } , /* pin */
- FALSE , /* pinpad */
- FALSE , /* valid */
- FALSE , /* session_opened */
- FALSE , /* logged_in */
- TRUE , /* any_slot */
- 0L , /* session */
-};
-
-#ifdef SMARTCARD /* compile with smartcard support */
-
-#define SCX_MAGIC 0xd00bed00
-
-struct scx_pkcs11_module {
- u_int _magic;
- void *handle;
-};
-
-typedef struct scx_pkcs11_module scx_pkcs11_module_t;
-
-/* PKCS #11 cryptoki context */
-static bool scx_initialized = FALSE;
-static scx_pkcs11_module_t *pkcs11_module = NULL_PTR;
-static CK_FUNCTION_LIST_PTR pkcs11_functions = NULL_PTR;
-
-/* crytoki v2.11 - return values of PKCS #11 functions*/
-
-static const char *const pkcs11_return_name[] = {
- "CKR_OK",
- "CKR_CANCEL",
- "CKR_HOST_MEMORY",
- "CKR_SLOT_ID_INVALID",
- "CKR_FLAGS_INVALID",
- "CKR_GENERAL_ERROR",
- "CKR_FUNCTION_FAILED",
- "CKR_ARGUMENTS_BAD",
- "CKR_NO_EVENT",
- "CKR_NEED_TO_CREATE_THREADS",
- "CKR_CANT_LOCK"
- };
-
-static const char *const pkcs11_return_name_10[] = {
- "CKR_ATTRIBUTE_READ_ONLY",
- "CKR_ATTRIBUTE_SENSITIVE",
- "CKR_ATTRIBUTE_TYPE_INVALID",
- "CKR_ATTRIBUTE_VALUE_INVALID"
- };
-
-static const char *const pkcs11_return_name_20[] = {
- "CKR_DATA_INVALID",
- "CKR_DATA_LEN_RANGE"
- };
-
-static const char *const pkcs11_return_name_30[] = {
- "CKR_DEVICE_ERROR",
- "CKR_DEVICE_MEMORY",
- "CKR_DEVICE_REMOVED"
- };
-
-static const char *const pkcs11_return_name_40[] = {
- "CKR_ENCRYPTED_DATA_INVALID",
- "CKR_ENCRYPTED_DATA_LEN_RANGE"
- };
-
-static const char *const pkcs11_return_name_50[] = {
- "CKR_FUNCTION_CANCELED",
- "CKR_FUNCTION_NOT_PARALLEL",
- "CKR_0x52_UNDEFINED",
- "CKR_0x53_UNDEFINED",
- "CKR_FUNCTION_NOT_SUPPORTED"
- };
-
-static const char *const pkcs11_return_name_60[] = {
- "CKR_KEY_HANDLE_INVALID",
- "CKR_KEY_SENSITIVE",
- "CKR_KEY_SIZE_RANGE",
- "CKR_KEY_TYPE_INCONSISTENT",
- "CKR_KEY_NOT_NEEDED",
- "CKR_KEY_CHANGED",
- "CKR_KEY_NEEDED",
- "CKR_KEY_INDIGESTIBLE",
- "CKR_KEY_FUNCTION_NOT_PERMITTED",
- "CKR_KEY_NOT_WRAPPABLE",
- "CKR_KEY_UNEXTRACTABLE"
- };
-
-static const char *const pkcs11_return_name_70[] = {
- "CKR_MECHANISM_INVALID",
- "CKR_MECHANISM_PARAM_INVALID"
- };
-
-static const char *const pkcs11_return_name_80[] = {
- "CKR_OBJECT_HANDLE_INVALID"
- };
-
-static const char *const pkcs11_return_name_90[] = {
- "CKR_OPERATION_ACTIVE",
- "CKR_OPERATION_NOT_INITIALIZED"
- };
-
-static const char *const pkcs11_return_name_A0[] = {
- "CKR_PIN_INCORRECT",
- "CKR_PIN_INVALID",
- "CKR_PIN_LEN_RANGE",
- "CKR_PIN_EXPIRED",
- "CKR_PIN_LOCKED"
- };
-
-static const char *const pkcs11_return_name_B0[] = {
- "CKR_SESSION_CLOSED",
- "CKR_SESSION_COUNT",
- "CKR_0xB2_UNDEFINED",
- "CKR_SESSION_HANDLE_INVALID",
- "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
- "CKR_SESSION_READ_ONLY",
- "CKR_SESSION_EXISTS",
- "CKR_SESSION_READ_ONLY_EXISTS",
- "CKR_SESSION_READ_WRITE_SO_EXISTS"
- };
-
-static const char *const pkcs11_return_name_C0[] = {
- "CKR_SIGNATURE_INVALID",
- "CKR_SIGNATURE_LEN_RANGE"
- };
-
-static const char *const pkcs11_return_name_D0[] = {
- "CKR_TEMPLATE_INCOMPLETE",
- "CKR_TEMPLATE_INCONSISTENT"
- };
-
-static const char *const pkcs11_return_name_E0[] = {
- "CKR_TOKEN_NOT_PRESENT",
- "CKR_TOKEN_NOT_RECOGNIZED",
- "CKR_TOKEN_WRITE_PROTECTED"
- };
-
-static const char *const pkcs11_return_name_F0[] = {
- "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
- "CKR_UNWRAPPING_KEY_SIZE_RANGE",
- "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"
- };
-
-static const char *const pkcs11_return_name_100[] = {
- "CKR_USER_ALREADY_LOGGED_IN",
- "CKR_USER_NOT_LOGGED_IN",
- "CKR_USER_PIN_NOT_INITIALIZED",
- "CKR_USER_TYPE_INVALID",
- "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
- "CKR_USER_TOO_MANY_TYPES"
- };
-
-static const char *const pkcs11_return_name_110[] = {
- "CKR_WRAPPED_KEY_INVALID",
- "CKR_0x111_UNDEFINED",
- "CKR_WRAPPED_KEY_LEN_RANGE",
- "CKR_WRAPPING_KEY_HANDLE_INVALID",
- "CKR_WRAPPING_KEY_SIZE_RANGE",
- "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"
- };
-
-static const char *const pkcs11_return_name_120[] = {
- "CKR_RANDOM_SEED_NOT_SUPPORTED",
- "CKR_RANDOM_NO_RNG"
- };
-
-static const char *const pkcs11_return_name_130[] = {
- "CKR_DOMAIN_PARAMS_INVALID"
- };
-
-static const char *const pkcs11_return_name_150[] = {
- "CKR_BUFFER_TOO_SMALL"
- };
-
-static const char *const pkcs11_return_name_160[] = {
- "CKR_SAVED_STATE_INVALID"
- };
-
-static const char *const pkcs11_return_name_170[] = {
- "CKR_INFORMATION_SENSITIVE"
- };
-
-static const char *const pkcs11_return_name_180[] = {
- "CKR_STATE_UNSAVEABLE"
- };
-
-static const char *const pkcs11_return_name_190[] = {
- "CKR_CRYPTOKI_NOT_INITIALIZED",
- "CKR_CRYPTOKI_ALREADY_INITIALIZED"
- };
-
-static const char *const pkcs11_return_name_1A0[] = {
- "CKR_MUTEX_BAD",
- "CKR_MUTEX_NOT_LOCKED"
- };
-
-static const char *const pkcs11_return_name_200[] = {
- "CKR_FUNCTION_REJECTED"
- };
-
-static const char *const pkcs11_return_name_vendor[] = {
- "CKR_VENDOR_DEFINED"
- };
-
-static enum_names pkcs11_return_names_vendor =
- { CKR_VENDOR_DEFINED, CKR_VENDOR_DEFINED
- , pkcs11_return_name_vendor, NULL };
-
-static enum_names pkcs11_return_names_200 =
- { CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED
- , pkcs11_return_name_200, &pkcs11_return_names_vendor };
-
-static enum_names pkcs11_return_names_1A0 =
- { CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED
- , pkcs11_return_name_1A0, &pkcs11_return_names_200 };
-
-static enum_names pkcs11_return_names_190 =
- { CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED
- , pkcs11_return_name_190, &pkcs11_return_names_1A0 };
-
-static enum_names pkcs11_return_names_180 =
- { CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE
- , pkcs11_return_name_180, &pkcs11_return_names_190 };
-
-static enum_names pkcs11_return_names_170 =
- { CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE
- , pkcs11_return_name_170, &pkcs11_return_names_180 };
-
-static enum_names pkcs11_return_names_160 =
- { CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID
- , pkcs11_return_name_160, &pkcs11_return_names_170 };
-
-static enum_names pkcs11_return_names_150 =
- { CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL
- , pkcs11_return_name_150, &pkcs11_return_names_160 };
-
-static enum_names pkcs11_return_names_130 =
- { CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID
- , pkcs11_return_name_130, &pkcs11_return_names_150 };
-
-static enum_names pkcs11_return_names_120 =
- { CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG
- , pkcs11_return_name_120, &pkcs11_return_names_130 };
-
-static enum_names pkcs11_return_names_110 =
- { CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT
- , pkcs11_return_name_110, &pkcs11_return_names_120 };
-
-static enum_names pkcs11_return_names_100 =
- { CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES
- , pkcs11_return_name_100, &pkcs11_return_names_110 };
-
-static enum_names pkcs11_return_names_F0 =
- { CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
- , pkcs11_return_name_F0, &pkcs11_return_names_100 };
-
-static enum_names pkcs11_return_names_E0 =
- { CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED
- , pkcs11_return_name_E0, &pkcs11_return_names_F0 };
-
-static enum_names pkcs11_return_names_D0 =
- { CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT
- , pkcs11_return_name_D0,&pkcs11_return_names_E0 };
-
-static enum_names pkcs11_return_names_C0 =
- { CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE
- , pkcs11_return_name_C0, &pkcs11_return_names_D0 };
-
-static enum_names pkcs11_return_names_B0 =
- { CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS
- , pkcs11_return_name_B0, &pkcs11_return_names_C0 };
-
-static enum_names pkcs11_return_names_A0 =
- { CKR_PIN_INCORRECT, CKR_PIN_LOCKED
- , pkcs11_return_name_A0, &pkcs11_return_names_B0 };
-
-static enum_names pkcs11_return_names_90 =
- { CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED
- , pkcs11_return_name_90, &pkcs11_return_names_A0 };
-
-static enum_names pkcs11_return_names_80 =
- { CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID
- , pkcs11_return_name_80, &pkcs11_return_names_90 };
-
-static enum_names pkcs11_return_names_70 =
- { CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID
- , pkcs11_return_name_70, &pkcs11_return_names_80 };
-
-static enum_names pkcs11_return_names_60 =
- { CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE
- , pkcs11_return_name_60, &pkcs11_return_names_70 };
-
-static enum_names pkcs11_return_names_50 =
- { CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED
- , pkcs11_return_name_50, &pkcs11_return_names_60 };
-
-static enum_names pkcs11_return_names_40 =
- { CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE
- , pkcs11_return_name_40, &pkcs11_return_names_50 };
-
-static enum_names pkcs11_return_names_30 =
- { CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED
- , pkcs11_return_name_30, &pkcs11_return_names_40 };
-
-static enum_names pkcs11_return_names_20 =
- { CKR_DATA_INVALID, CKR_DATA_LEN_RANGE
- , pkcs11_return_name_20, &pkcs11_return_names_30 };
-
-static enum_names pkcs11_return_names_10 =
- { CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID
- , pkcs11_return_name_10, &pkcs11_return_names_20};
-
-static enum_names pkcs11_return_names =
- { CKR_OK, CKR_CANT_LOCK
- , pkcs11_return_name, &pkcs11_return_names_10};
-
-/*
- * Unload a PKCS#11 module.
- * The calling application is responsible for cleaning up
- * and calling C_Finalize()
- */
-static CK_RV
-scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
-{
- if (!mod || mod->_magic != SCX_MAGIC)
- return CKR_ARGUMENTS_BAD;
-
- if (dlclose(mod->handle) < 0)
- return CKR_FUNCTION_FAILED;
-
- memset(mod, 0, sizeof(*mod));
- pfree(mod);
- return CKR_OK;
-}
-
-static scx_pkcs11_module_t*
-scx_load_pkcs11_module(const char *name, CK_FUNCTION_LIST_PTR_PTR funcs)
-{
- CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
- scx_pkcs11_module_t *mod;
- void *handle;
- int rv;
-
- if (name == NULL || *name == '\0')
- return NULL;
-
- /* Try to load PKCS#11 library module*/
- handle = dlopen(name, RTLD_NOW);
- if (handle == NULL)
- return NULL;
-
- mod = alloc_thing(scx_pkcs11_module_t, "scx_pkcs11_module");
- mod->_magic = SCX_MAGIC;
- mod->handle = handle;
-
- /* Get the list of function pointers */
- c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
- dlsym(mod->handle, "C_GetFunctionList");
- if (!c_get_function_list)
- goto failed;
-
- rv = c_get_function_list(funcs);
- if (rv == CKR_OK)
- return mod;
-
-failed: scx_unload_pkcs11_module(mod);
- return NULL;
-}
-
-/*
- * retrieve a certificate object
- */
-static bool
-scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
-, smartcard_t *sc, cert_t *cert)
-{
- size_t hex_len, label_len;
- u_char *hex_id = NULL;
- chunk_t blob;
- x509cert_t *x509cert;
-
- CK_ATTRIBUTE attr[] = {
- { CKA_ID, NULL_PTR, 0L },
- { CKA_LABEL, NULL_PTR, 0L },
- { CKA_VALUE, NULL_PTR, 0L }
- };
-
- /* initialize the return argument */
- *cert = empty_cert;
-
- /* get the length of the attributes first */
- CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the attribute sizes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- pfreeany(sc->label);
-
- hex_id = alloc_bytes(attr[0].ulValueLen, "hex id");
- hex_len = attr[0].ulValueLen;
- sc->label = alloc_bytes(attr[1].ulValueLen + 1, "sc label");
- label_len = attr[1].ulValueLen;
- blob.ptr = alloc_bytes(attr[2].ulValueLen, "x509cert blob");
- blob.len = attr[2].ulValueLen;
-
- attr[0].pValue = hex_id;
- attr[1].pValue = sc->label;
- attr[2].pValue = blob.ptr;
-
- /* now get the attributes */
- rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfree(hex_id);
- pfreeany(sc->label);
- pfree(blob.ptr);
- return FALSE;
- }
-
- pfreeany(sc->id);
-
- /* convert id from hex to ASCII */
- sc->id = alloc_bytes(2*hex_len + 1, " sc id");
- datatot(hex_id, hex_len, 16, sc->id, 2*hex_len + 1);
- pfree(hex_id);
-
- /* safeguard in case the label is not null terminated */
- sc->label[label_len] = '\0';
-
- /* parse the retrieved cert */
- x509cert = alloc_thing(x509cert_t, "x509cert");
- *x509cert = empty_x509cert;
- x509cert->smartcard = TRUE;
-
- if (!parse_x509cert(blob, 0, x509cert))
- {
- plog("failed to load cert from smartcard, error in X.509 certificate");
- free_x509cert(x509cert);
- return FALSE;
- }
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return TRUE;
-}
-
-/*
- * search a given slot for PKCS#11 certificate objects
- */
-static void
-scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
-{
- CK_RV rv;
- CK_OBJECT_CLASS class = CKO_CERTIFICATE;
- CK_ATTRIBUTE attr[] = {{ CKA_CLASS, &class, sizeof(class) }};
-
- rv = pkcs11_functions->C_FindObjectsInit(session, attr, 1);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return;
- }
-
- for (;;)
- {
- CK_OBJECT_HANDLE object;
- CK_ULONG obj_count = 0;
- err_t ugh;
- time_t valid_until;
- smartcard_t *sc;
- x509cert_t *cert;
-
- rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjects: %s"
- , enum_show(&pkcs11_return_names, rv));
- break;
- }
-
- /* no objects left */
- if (obj_count == 0)
- break;
-
- /* create and initialize a new smartcard object */
- sc = alloc_thing(smartcard_t, "smartcard");
- *sc = empty_sc;
- sc->any_slot = FALSE;
- sc->slot = slot;
-
- if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
- {
- scx_free(sc);
- continue;
- }
- DBG(DBG_CONTROL,
- DBG_log("found cert in %s with id: %s, label: '%s'"
- , scx_print_slot(sc, ""), sc->id, sc->label)
- )
-
- /* check validity of certificate */
- cert = sc->last_cert.u.x509;
- valid_until = cert->notAfter;
- ugh = check_validity(cert, &valid_until);
- if (ugh != NULL)
- {
- plog(" %s", ugh);
- free_x509cert(cert);
- scx_free(sc);
- continue;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log(" certificate is valid")
- )
- }
-
- sc = scx_add(sc);
-
- /* put end entity and ca certificates into different chains */
- if (cert->isCA)
- add_authcert(cert, AUTH_CA);
- else
- {
- add_x509_public_key(cert, valid_until, DAL_LOCAL);
- sc->last_cert.u.x509 = add_x509cert(cert);
- }
-
- share_cert(sc->last_cert);
- time(&sc->last_load);
- }
-
- rv = pkcs11_functions->C_FindObjectsFinal(session);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsFinal: %s"
- , enum_show(&pkcs11_return_names, rv));
- }
-}
-
-/*
- * search all slots for PKCS#11 certificate objects
- */
-static void
-scx_find_all_cert_objects(void)
-{
- CK_RV rv;
- CK_SLOT_ID_PTR slots = NULL_PTR;
- CK_ULONG slot_count = 0;
- CK_ULONG i;
-
- if (!scx_initialized)
- {
- plog("pkcs11 module not initialized");
- return;
- }
-
- /* read size, always returns CKR_OK ! */
- rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
-
- /* allocate memory for the slots */
- slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
-
- rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
- pfreeany(slots);
- return;
- }
-
- /* look in every slot for certificate objects */
- for (i = 0; i < slot_count; i++)
- {
- CK_SLOT_ID slot = slots[i];
- CK_SLOT_INFO info;
- CK_SESSION_HANDLE session;
-
- rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
-
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotInfo: %s"
- , enum_show(&pkcs11_return_names, rv));
- continue;
- }
-
- if (!(info.flags & CKF_TOKEN_PRESENT))
- {
- plog("no token present in slot %lu", slot);
- continue;
- }
-
- rv = pkcs11_functions->C_OpenSession(slot
- , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
- if (rv != CKR_OK)
- {
- plog("failed to open a session on slot %lu: %s"
- , slot, enum_show(&pkcs11_return_names, rv));
- continue;
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
- )
- scx_find_cert_objects(slot, session);
-
- rv = pkcs11_functions->C_CloseSession(session);
- if (rv != CKR_OK)
- {
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
- }
- }
- pfreeany(slots);
-}
-#endif
-
-/*
- * load and initialize PKCS#11 cryptoki module
- */
-void
-scx_init(const char* module)
-{
-#ifdef SMARTCARD
- CK_RV rv;
-
- if (scx_initialized)
- {
- plog("weird - pkcs11 module seems already to be initialized");
- return;
- }
-
- if (module == NULL)
-#ifdef PKCS11_DEFAULT_LIB
- module = PKCS11_DEFAULT_LIB;
-#else
- {
- plog("no pkcs11 module defined");
- return;
- }
-#endif
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module '%s' loading...", module)
- )
- pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
- if (pkcs11_module == NULL)
- {
- plog("failed to load pkcs11 module '%s'", module);
- return;
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module initializing...")
- )
- rv = pkcs11_functions->C_Initialize(NULL);
- if (rv != CKR_OK)
- {
- plog("failed to initialize pkcs11 module: %s"
- , enum_show(&pkcs11_return_names, rv));
- return;
- }
-
- scx_initialized = TRUE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module loaded and initialized")
- )
-
- scx_find_all_cert_objects();
-#endif
-}
-
-/*
- * finalize and unload PKCS#11 cryptoki module
- */
-void
-scx_finalize(void)
-{
-#ifdef SMARTCARD
- while (smartcards != NULL)
- {
- scx_release(smartcards);
- }
-
- if (pkcs11_functions != NULL_PTR)
- {
- pkcs11_functions->C_Finalize(NULL_PTR);
- pkcs11_functions = NULL_PTR;
- }
-
- if (pkcs11_module != NULL)
- {
- scx_unload_pkcs11_module(pkcs11_module);
- pkcs11_module = NULL;
- }
-
- scx_initialized = FALSE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module finalized and unloaded")
- )
-#endif
-}
-
-/*
- * does a filename contain the token %smartcard?
- */
-bool
-scx_on_smartcard(const char *filename)
-{
- return strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0;
-}
-
-#ifdef SMARTCARD
-/*
- * find a specific object on the smartcard
- */
-static bool
-scx_pkcs11_find_object( CK_SESSION_HANDLE session,
- CK_OBJECT_HANDLE_PTR object,
- CK_OBJECT_CLASS class,
- const char* id)
-{
- size_t len;
- char buf[BUF_LEN];
- CK_RV rv;
- CK_ULONG obj_count = 0;
- CK_ULONG attr_count = 1;
-
- CK_ATTRIBUTE attr[] = {
- { CKA_CLASS, &class, sizeof(class) },
- { CKA_ID, &buf, 0L }
- };
-
- if (id != NULL)
- {
- ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
- attr[1].ulValueLen = len;
- attr_count = 2;
- }
-
- /* get info for certificate with id */
- rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjects: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- rv = pkcs11_functions->C_FindObjectsFinal(session);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsFinal: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- return (obj_count != 0);
-}
-
-/*
- * check if a given certificate object id is found in a slot
- */
-static bool
-scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
-{
- CK_SESSION_HANDLE session;
- CK_OBJECT_HANDLE object;
- CK_SLOT_INFO info;
-
- CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
-
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotInfo: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- if (!(info.flags & CKF_TOKEN_PRESENT))
- {
- plog("no token present in slot %lu", slot);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_OpenSession(slot
- , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
- if (rv != CKR_OK)
- {
- plog("failed to open a session on slot %lu: %s"
- , slot, enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
- )
-
- /* check if there is a certificate on the card in the specified slot */
- if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
- {
- sc->slot = slot;
- sc->any_slot = FALSE;
- sc->session = session;
- sc->session_opened = TRUE;
- return TRUE;
- }
-
- rv = pkcs11_functions->C_CloseSession(session);
- if (rv != CKR_OK)
- {
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
- }
- return FALSE;
-}
-#endif
-
-/*
- * Connect to the smart card in the reader and select the correct slot
- */
-bool
-scx_establish_context(smartcard_t *sc)
-{
-#ifdef SMARTCARD
- bool id_found = FALSE;
-
- if (!scx_initialized)
- {
- plog("pkcs11 module not initialized");
- return FALSE;
- }
-
- if (sc->session_opened)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld already open", sc->session)
- )
- return TRUE;
- }
-
- if (!sc->any_slot)
- id_found = scx_find_cert_id_in_slot(sc, sc->slot);
-
- if (!id_found)
- {
- CK_RV rv;
- CK_SLOT_ID slot;
- CK_SLOT_ID_PTR slots = NULL_PTR;
- CK_ULONG slot_count = 0;
- CK_ULONG i;
-
- /* read size, always returns CKR_OK ! */
- rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
-
- /* allocate memory for the slots */
- slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
-
- rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotList: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfreeany(slots);
- return FALSE;
- }
-
- /* look in every slot for a certificate with a given object ID */
- for (i = 0; i < slot_count; i++)
- {
- slot = slots[i];
- id_found = scx_find_cert_id_in_slot(sc, slot);
- if (id_found)
- break;
- }
- pfreeany(slots)
- }
-
- if (id_found)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
- DBG_log("pkcs11 session #%ld opened", sc->session)
- )
- }
- else
- {
- plog(" no certificate with id %s found on smartcard", sc->id);
- }
- return id_found;
-#else
- plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
- return FALSE;
-#endif
-}
-
-/*
- * log in to a session
- */
-bool
-scx_login(smartcard_t *sc)
-{
-#ifdef SMARTCARD
- CK_RV rv;
-
- if (sc->logged_in)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld login already done", sc->session)
- )
- return TRUE;
- }
-
- if (sc->pin.ptr == NULL)
- {
- plog("unable to log in without PIN!");
- return FALSE;
- }
-
- if (!sc->session_opened)
- {
- plog("session not opened");
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Login(sc->session, CKU_USER
- , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
- {
- plog("unable to login: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld login successful", sc->session)
- )
- sc->logged_in = TRUE;
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-#ifdef SMARTCARD
-/*
- * logout from a session
- */
-static void
-scx_logout(smartcard_t *sc)
-{
- CK_RV rv;
-
- rv = pkcs11_functions->C_Logout(sc->session);
- if (rv != CKR_OK)
- plog("error in C_Logout: %s"
- , enum_show(&pkcs11_return_names, rv));
- else
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld logout", sc->session)
- )
- sc->logged_in = FALSE;
-}
-#endif
-
-
-/*
- * Release context and disconnect from card
- */
-void
-scx_release_context(smartcard_t *sc)
-{
-#ifdef SMARTCARD
- CK_RV rv;
-
- if (!scx_initialized)
- return;
-
- if (sc->session_opened)
- {
- if (sc->logged_in)
- scx_logout(sc);
-
- sc->session_opened = FALSE;
-
- rv = pkcs11_functions->C_CloseSession(sc->session);
- if (rv != CKR_OK)
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
- else
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld closed", sc->session)
- )
- }
-#endif
-}
-
-/*
- * Load host certificate from smartcard
- */
-bool
-scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
-, bool *cached)
-{
-#ifdef SMARTCARD /* compile with smartcard support */
- CK_OBJECT_HANDLE object;
-
- const char *number_slot_id = filename + strlen(SCX_TOKEN);
-
- smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
-
- /* return the smartcard object */
- *scp = sc;
-
- /* is there a cached smartcard certificate? */
- *cached = sc->last_cert.type != CERT_NONE
- && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
-
- if (*cached)
- {
- *cert = sc->last_cert;
- plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
- , sc->number
- , scx_print_slot(sc, "")
- , sc->id
- , sc->label);
- return TRUE;
- }
-
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- /* find the certificate object */
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- /* retrieve the certificate object */
- if (!scx_find_cert_object(sc->session, object, sc, cert))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!pkcs11_keep_state)
- scx_release_context(sc);
-
- plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
- , sc->number
- , scx_print_slot(sc, "")
- , sc->id
- , sc->label);
-
- return TRUE;
-#else
- plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
- return FALSE;
-#endif
-}
-
-/*
- * parse slot number and key id
- * the following syntax is allowed
- * number slot id
- * %smartcard 1 - -
- * %smartcard#2 2 - -
- * %smartcard0 - 0 -
- * %smartcard:45 - - 45
- * %smartcard0:45 - 0 45
- */
-smartcard_t*
-scx_parse_number_slot_id(const char *number_slot_id)
-{
- int len = strlen(number_slot_id);
- smartcard_t *sc = alloc_thing(smartcard_t, "smartcard");
-
- /* assign default values */
- *sc = empty_sc;
-
- if (len == 0) /* default: use certificate #1 */
- {
- sc->number = 1;
- }
- else if (*number_slot_id == '#') /* #number scheme */
- {
- err_t ugh;
- unsigned long ul;
-
- ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
- if (ugh == NULL)
- sc->number = (int)ul;
- else
- plog("error parsing smartcard number: %s", ugh);
- }
- else /* slot:id scheme */
- {
- int slot_len = len;
- char *p = strchr(number_slot_id, ':');
-
- if (p != NULL)
- {
- int id_len = len - (p + 1 - number_slot_id);
- slot_len -= (1 + id_len);
-
- if (id_len > 0) /* we have an id */
- sc->id = p + 1;
- }
- if (slot_len > 0) /* we have a slot */
- {
- err_t ugh = NULL;
- unsigned long ul;
-
- ugh = atoul(number_slot_id, slot_len, 10, &ul);
- if (ugh == NULL)
- {
- sc->slot = ul;
- sc->any_slot = FALSE;
- }
- else
- plog("error parsing smartcard slot number: %s", ugh);
- }
- }
- /* unshare the id string */
- sc->id = clone_str(sc->id, "key id");
- return sc;
-}
-
-/*
- * Verify pin on card
- */
-bool
-scx_verify_pin(smartcard_t *sc)
-{
-#ifdef SMARTCARD
- CK_RV rv;
-
- if (!sc->pinpad)
- sc->valid = FALSE;
-
- if (sc->pin.ptr == NULL)
- {
- plog("unable to verify without PIN");
- return FALSE;
- }
-
- /* establish context */
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
- (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
- if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
- {
- sc->valid = TRUE;
- sc->logged_in = TRUE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log((rv == CKR_OK)
- ? "PIN code correct"
- : "already logged in, no PIN entry required");
- DBG_log("pkcs11 session #%ld login successful", sc->session)
- )
- }
- else
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("PIN code incorrect")
- )
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
-#else
- sc->valid = FALSE;
-#endif
- return sc->valid;
-}
-
-/*
- * Sign hash on smartcard
- */
-bool
-scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t outlen)
-{
-#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG siglen = (CK_ULONG)outlen;
- CK_BBOOL sign_flag, decrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
- { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
- };
-
- if (!sc->logged_in)
- return FALSE;
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
- if (rv != CKR_OK)
- {
- plog("couldn't read the private key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("RSA key flags: sign = %s, decrypt = %s"
- , (sign_flag)? "true":"false"
- , (decrypt_flag)? "true":"false")
- )
-
- if (sign_flag)
- {
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
- if (rv != CKR_OK)
- {
- plog("error in C_SignInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
- , out, &siglen);
- if (rv != CKR_OK)
- {
- plog("error in C_Sign: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- }
- else if (decrypt_flag)
- {
- CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
- size_t padlen;
- u_char *p = out ;
-
- /* PKCS#1 v1.5 8.1 encryption-block formatting */
- *p++ = 0x00;
- *p++ = 0x01; /* BT (block type) 01 */
- padlen = outlen - 3 - inlen;
- memset(p, 0xFF, padlen);
- p += padlen;
- *p++ = 0x00;
- memcpy(p, in, inlen);
-
- rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
- if (rv != CKR_OK)
- {
- plog("error in C_DecryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
- , out, &siglen);
- if (rv != CKR_OK)
- {
- plog("error in C_Decrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- }
- else
- {
- plog("private key has neither sign nor decrypt flag set");
- return FALSE;
- }
-
- if (siglen > (CK_ULONG)outlen)
- {
- plog("signature length (%lu) larger than allocated buffer (%d)"
- , siglen, (int)outlen);
- return FALSE;
- }
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-/*
- * encrypt data block with an RSA public key
- */
-bool
-scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t *outlen)
-{
-#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG len = (CK_ULONG)(*outlen);
- CK_BBOOL encrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_MODULUS, NULL_PTR, 0L },
- { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
- { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
- };
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
- {
- plog("unable to find public key with id '%s'", sc->id);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the public key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!encrypt_flag)
- {
- plog("public key cannot be used for encryption");
- scx_release_context(sc);
- return FALSE;
- }
-
- /* there must be enough space left for the PKCS#1 v1.5 padding */
- if (inlen > attr[0].ulValueLen - 11)
- {
- plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
- , (int)inlen, attr[0].ulValueLen - 11);
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
-
- if (rv != CKR_OK)
- {
- if (rv == CKR_FUNCTION_NOT_SUPPORTED)
- {
- RSA_public_key_t rsa;
- chunk_t plain_text = {in, inlen};
- chunk_t cipher_text;
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA encryption in software")
- )
- attr[0].pValue = alloc_bytes(attr[0].ulValueLen, "modulus");
- attr[1].pValue = alloc_bytes(attr[1].ulValueLen, "exponent");
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
- if (rv != CKR_OK)
- {
- plog("couldn't read modulus and public exponent: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfree(attr[0].pValue);
- pfree(attr[1].pValue);
- scx_release_context(sc);
- return FALSE;
- }
- rsa.k = attr[0].ulValueLen;
- n_to_mpz(&rsa.n, attr[0].pValue, attr[0].ulValueLen);
- n_to_mpz(&rsa.e, attr[1].pValue, attr[1].ulValueLen);
- pfree(attr[0].pValue);
- pfree(attr[1].pValue);
-
- cipher_text = RSA_encrypt(&rsa, plain_text);
- free_RSA_public_content(&rsa);
- if (cipher_text.ptr == NULL)
- {
- plog("smartcard input data length is too large");
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- return FALSE;
- }
-
- memcpy(out, cipher_text.ptr, cipher_text.len);
- *outlen = cipher_text.len;
- freeanychunk(cipher_text);
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- return TRUE;
- }
- else
- {
- plog("error in C_EncryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA encryption on smartcard")
- )
- rv = pkcs11_functions->C_Encrypt(sc->session, in, inlen
- , out, &len);
- if (rv != CKR_OK)
- {
- plog("error in C_Encrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
-
- *outlen = (size_t)len;
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-/*
- * decrypt a data block with an RSA private key
- */
-bool
-scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
-, u_char *out, size_t *outlen)
-{
-#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG len = (CK_ULONG)(*outlen);
- CK_BBOOL decrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
- };
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- if (!scx_establish_context(sc) || !scx_login(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
- if (rv != CKR_OK)
- {
- plog("couldn't read the private key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- if (!decrypt_flag)
- {
- plog("private key cannot be used for decryption");
- scx_release_context(sc);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA decryption on smartcard")
- )
- rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
- if (rv != CKR_OK)
- {
- plog("error in C_DecryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Decrypt(sc->session, in, inlen
- , out, &len);
- if (rv != CKR_OK)
- {
- plog("error in C_Decrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
-
- *outlen = (size_t)len;
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-/* receive an encrypted data block via whack,
- * decrypt it using a private RSA key and
- * return the decrypted data block via whack
- */
-bool
-scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
-, const char* keyid, int whackfd)
-{
- char inbuf[RSA_MAX_OCTETS];
- char outbuf[2*RSA_MAX_OCTETS + 1];
- size_t outlen = sizeof(inbuf);
- size_t inlen;
- smartcard_t *sc,*sc_new;
-
- const char *number_slot_id = "";
-
- err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
-
- /* no prefix - use default base */
- if (ugh != NULL && inbase == 0)
- ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
-
- if (ugh != NULL)
- {
- plog("format error in smartcard input data: %s", ugh);
- return FALSE;
- }
-
- if (keyid != NULL)
- {
- number_slot_id = (strncmp(keyid, SCX_TOKEN, strlen(SCX_TOKEN)) == 0)
- ? keyid + strlen(SCX_TOKEN) : keyid;
- }
-
- sc_new = scx_parse_number_slot_id(number_slot_id);
- sc = scx_add(sc_new);
- if (sc == sc_new)
- scx_share(sc);
-
- DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
- DBG_dump("smartcard input data:\n", inbuf, inlen)
- )
-
- if (op == SC_OP_DECRYPT)
- {
- if (!sc->valid && whackfd != NULL_FD)
- scx_get_pin(sc, whackfd);
-
- if (!sc->valid)
- {
- loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
- )
-
- switch (op)
- {
- case SC_OP_ENCRYPT:
- if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
- return FALSE;
- break;
- case SC_OP_DECRYPT:
- if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
- return FALSE;
- break;
- default:
- break;
- }
-
- DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
- DBG_dump("smartcard output data:\n", inbuf, outlen)
- )
-
- if (outbase == 0) /* use default base */
- outbase = DEFAULT_BASE;
-
- if (outbase == 256) /* ascii plain text */
- whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
- else
- {
- outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
- if (outlen == 0)
- {
- plog("error in output format conversion");
- return FALSE;
- }
- whack_log(RC_COMMENT, "%s", outbuf);
- }
- return TRUE;
-}
-
- /*
- * get length of RSA key in bytes
- */
-size_t
-scx_get_keylength(smartcard_t *sc)
-{
-#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
-
- if (!sc->logged_in)
- return FALSE;
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
-
- /* get the length of the private key */
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
- , (CK_ATTRIBUTE_PTR)&attr, 1);
- if (rv != CKR_OK)
- {
- plog("failed to get key length: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- return attr[0].ulValueLen; /*Return key length in bytes */
-#else
- return 0;
-#endif
-}
-
-/*
- * prompt for pin and verify it
- */
-bool
-scx_get_pin(smartcard_t *sc, int whackfd)
-{
-#ifdef SMARTCARD
- char pin[BUF_LEN];
- int i, n;
-
- whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
- , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
-
- for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
- {
- if (i > 0)
- whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
-
- n = read(whackfd, pin, BUF_LEN);
-
- if (n == -1)
- {
- whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
- return FALSE;
- }
-
- if (strlen(pin) == 0)
- {
- whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
- return FALSE;
- }
-
- sc->pin.ptr = pin;
- sc->pin.len = strlen(pin);
-
- /* verify the pin */
- if (scx_verify_pin(sc))
- {
- clonetochunk(sc->pin, pin, strlen(pin), "pin");
- break;
- }
-
- /* wrong pin - we try another round */
- sc->pin = empty_chunk;
- }
-
- if (sc->valid)
- whack_log(RC_SUCCESS, "valid PIN");
- else
- whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
-#else
- sc->valid = FALSE;
- whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
-#endif
- return sc->valid;
-}
-
-
-/*
- * free the pin code
- */
-void
-scx_free_pin(chunk_t *pin)
-{
- if (pin->ptr != NULL)
- {
- /* clear pin field in memory */
- memset(pin->ptr, '\0', pin->len);
- pfree(pin->ptr);
- *pin = empty_chunk;
- }
-}
-
-/*
- * frees a smartcard record
- */
-void
-scx_free(smartcard_t *sc)
-{
- if (sc != NULL)
- {
- scx_release_context(sc);
- pfreeany(sc->id);
- pfreeany(sc->label);
- scx_free_pin(&sc->pin);
- pfree(sc);
- }
-}
-
-/* release of a smartcard record decreases the count by one
- " the record is freed when the counter reaches zero
- */
-void
-scx_release(smartcard_t *sc)
-{
- if (sc != NULL && --sc->count == 0)
- {
- smartcard_t **pp = &smartcards;
- while (*pp != sc)
- pp = &(*pp)->next;
- *pp = sc->next;
- release_cert(sc->last_cert);
- scx_free(sc);
- }
-}
-
-/*
- * compare two smartcard records by comparing their slots and ids
- */
-static bool
-scx_same(smartcard_t *a, smartcard_t *b)
-{
- if (a->number && b->number)
- {
- /* same number */
- return a->number == b->number;
- }
- else
- {
- /* same id and/or same slot */
- return (!a->id || (b->id && streq(a->id, b->id)))
- && (a->any_slot || b->any_slot || a->slot == b->slot);
- }
-}
-
-/* for each link pointing to the smartcard record
- " increase the count by one
- */
-void
-scx_share(smartcard_t *sc)
-{
- if (sc != NULL)
- sc->count++;
-}
-
-/*
- * adds a smartcard record to the chained list
- */
-smartcard_t*
-scx_add(smartcard_t *smartcard)
-{
- smartcard_t *sc = smartcards;
- smartcard_t **psc = &smartcards;
-
- while (sc != NULL)
- {
- if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
- {
- scx_free(smartcard);
- return sc;
- }
- psc = &sc->next;
- sc = sc->next;
- }
-
- /* insert new smartcard record at the end of the chain */
- *psc = smartcard;
- smartcard->number = ++sc_number;
- smartcard->count = 1;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" smartcard #%d added", sc_number)
- )
- return smartcard;
-}
-
-/*
- * get the smartcard that belongs to an X.509 certificate
- */
-smartcard_t*
-scx_get(x509cert_t *cert)
-{
- smartcard_t *sc = smartcards;
-
- while (sc != NULL)
- {
- if (sc->last_cert.u.x509 == cert)
- return sc;
- sc = sc->next;
- }
- return NULL;
-}
-
-/*
- * prints either the slot number or 'any slot'
- */
-char *
-scx_print_slot(smartcard_t *sc, const char *whitespace)
-{
- char *buf = temporary_cyclic_buffer();
-
- if (sc->any_slot)
- snprintf(buf, BUF_LEN, "any slot");
- else
- snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
- return buf;
-}
-
-/*
- * list all smartcard info records in a chained list
- */
-void
-scx_list(bool utc)
-{
- smartcard_t *sc = smartcards;
-
- if (sc != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Smartcard Objects:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (sc != NULL)
- {
- whack_log(RC_COMMENT, "%s, #%d, count: %d"
- , timetoa(&sc->last_load, utc)
- , sc->number
- , sc->count);
- whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
- , scx_print_slot(sc, " ")
- , sc->session_opened? "opened" : "closed"
- , sc->logged_in? "in" : "out"
- , sc->pinpad? "pin pad"
- : ((sc->pin.ptr == NULL)? "no pin"
- : sc->valid? "valid pin" : "invalid pin"));
- if (sc->id != NULL)
- whack_log(RC_COMMENT, " id: %s", sc->id);
- if (sc->label != NULL)
- whack_log(RC_COMMENT, " label: '%s'", sc->label);
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
- {
- char buf[BUF_LEN];
-
- dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
- whack_log(RC_COMMENT, " subject: '%s'", buf);
- }
- sc = sc->next;
- }
-}
diff --git a/programs/pluto/smartcard.h b/programs/pluto/smartcard.h
deleted file mode 100644
index c004ca7dd..000000000
--- a/programs/pluto/smartcard.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Support of smartcards and cryptotokens
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2004 David Buechi, Michael Meier
- * Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: smartcard.h,v 1.14 2005/11/06 22:55:41 as Exp $
- */
-
-#ifndef _SMARTCARD_H
-#define _SMARTCARD_H
-
-#include "certs.h"
-
-#define SCX_TOKEN "%smartcard"
-#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
-#define SCX_MAX_PIN_TRIALS 3
-
-/* smartcard operations */
-
-typedef enum {
- SC_OP_NONE = 0,
- SC_OP_ENCRYPT = 1,
- SC_OP_DECRYPT = 2,
- SC_OP_SIGN = 3,
-} sc_op_t;
-
-/* smartcard record */
-
-typedef struct smartcard smartcard_t;
-
-struct smartcard {
- smartcard_t *next;
- time_t last_load;
- cert_t last_cert;
- int count;
- int number;
- unsigned long slot;
- char *id;
- char *label;
- chunk_t pin;
- bool pinpad;
- bool valid;
- bool session_opened;
- bool logged_in;
- bool any_slot;
- long session;
-};
-
-extern const smartcard_t empty_sc;
-
-/* keep a PKCS#11 login during the lifetime of pluto
- * flag set in plutomain.c and used in ipsec_doi.c and ocsp.c
- */
-extern bool pkcs11_keep_state;
-
-/* allow other applications access to pluto's PKCS#11 interface
- * via whack. Could be used e.g. for disk encryption
- */
-extern bool pkcs11_proxy;
-
-extern smartcard_t* scx_parse_number_slot_id(const char *number_slot_id);
-extern void scx_init(const char *module);
-extern void scx_finalize(void);
-extern bool scx_establish_context(smartcard_t *sc);
-extern bool scx_login(smartcard_t *sc);
-extern bool scx_on_smartcard(const char *filename);
-extern bool scx_load_cert(const char *filename, smartcard_t **scp
- , cert_t *cert, bool *cached);
-extern bool scx_verify_pin(smartcard_t *sc);
-extern void scx_share(smartcard_t *sc);
-extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t outlen);
-extern bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t *outlen);
-extern bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t *outlen);
-extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
- , sc_op_t op, const char *keyid, int whackfd);
-extern bool scx_get_pin(smartcard_t *sc, int whackfd);
-extern size_t scx_get_keylength(smartcard_t *sc);
-extern smartcard_t* scx_add(smartcard_t *sc);
-extern smartcard_t* scx_get(x509cert_t *cert);
-extern void scx_release(smartcard_t *sc);
-extern void scx_release_context(smartcard_t *sc);
-extern void scx_free_pin(chunk_t *pin);
-extern void scx_free(smartcard_t *sc);
-extern void scx_list(bool utc);
-extern char *scx_print_slot(smartcard_t *sc, const char *whitespace);
-
-#endif /* _SMARTCARD_H */
diff --git a/programs/pluto/spdb.c b/programs/pluto/spdb.c
deleted file mode 100644
index ab976511e..000000000
--- a/programs/pluto/spdb.c
+++ /dev/null
@@ -1,2329 +0,0 @@
-/* Security Policy Data Base (such as it is)
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: spdb.c,v 1.10 2007/01/10 00:36:19 as Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "id.h"
-#include "connections.h"
-#include "state.h"
-#include "packet.h"
-#include "keys.h"
-#include "kernel.h"
-#include "log.h"
-#include "spdb.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-
-#include "alg_info.h"
-#include "kernel_alg.h"
-#include "ike_alg.h"
-#include "db_ops.h"
-#define AD(x) x, elemsof(x) /* Array Description */
-#define AD_NULL NULL, 0
-
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-/**************** Oakely (main mode) SA database ****************/
-
-/* array of proposals to be conjoined (can only be one for Oakley) */
-
-static struct db_prop oakley_pc[] =
- { { PROTO_ISAKMP, AD_NULL } };
-
-/* array of proposal conjuncts (can only be one) */
-
-static struct db_prop_conj oakley_props[] = { { AD(oakley_pc) } };
-
-/* the sadb entry */
-struct db_sa oakley_sadb = { AD(oakley_props) };
-
-/**************** IPsec (quick mode) SA database ****************/
-
-/* arrays of attributes for transforms */
-
-static struct db_attr espsha1_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
- };
-
-static struct db_attr ah_HMAC_SHA1_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
- };
-
-/* arrays of transforms, each in in preference order */
-
-static struct db_trans espa_trans[] = {
- { ESP_3DES, AD(espsha1_attr) },
- };
-
-static struct db_trans esp_trans[] = {
- { ESP_3DES, AD_NULL },
- };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_trans espnull_trans[] = {
- { ESP_NULL, AD(espsha1_attr) },
- };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_trans ah_trans[] = {
- { AH_SHA, AD(ah_HMAC_SHA1_attr) },
- };
-
-static struct db_trans ipcomp_trans[] = {
- { IPCOMP_DEFLATE, AD_NULL },
- };
-
-/* arrays of proposals to be conjoined */
-
-static struct db_prop ah_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_prop espnull_pc[] = {
- { PROTO_IPSEC_ESP, AD(espnull_trans) },
- };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_prop esp_pc[] = {
- { PROTO_IPSEC_ESP, AD(espa_trans) },
- };
-
-static struct db_prop ah_esp_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPSEC_ESP, AD(esp_trans) },
- };
-
-static struct db_prop compress_pc[] = {
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
-
-static struct db_prop ah_compress_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
-
-#ifdef SUPPORT_ESP_NULL
-static struct db_prop espnull_compress_pc[] = {
- { PROTO_IPSEC_ESP, AD(espnull_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
-#endif /* SUPPORT_ESP_NULL */
-
-static struct db_prop esp_compress_pc[] = {
- { PROTO_IPSEC_ESP, AD(espa_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
-
-static struct db_prop ah_esp_compress_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPSEC_ESP, AD(esp_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
-
-/* arrays of proposal alternatives (each element is a conjunction) */
-
-static struct db_prop_conj ah_props[] = {
- { AD(ah_pc) },
-#ifdef SUPPORT_ESP_NULL
- { AD(espnull_pc) }
-#endif
- };
-
-static struct db_prop_conj esp_props[] =
- { { AD(esp_pc) } };
-
-static struct db_prop_conj ah_esp_props[] =
- { { AD(ah_esp_pc) } };
-
-static struct db_prop_conj compress_props[] = {
- { AD(compress_pc) },
- };
-
-static struct db_prop_conj ah_compress_props[] = {
- { AD(ah_compress_pc) },
-#ifdef SUPPORT_ESP_NULL
- { AD(espnull_compress_pc) }
-#endif
- };
-
-static struct db_prop_conj esp_compress_props[] =
- { { AD(esp_compress_pc) } };
-
-static struct db_prop_conj ah_esp_compress_props[] =
- { { AD(ah_esp_compress_pc) } };
-
-/* The IPsec sadb is subscripted by a bitset (subset of policy)
- * with members from { POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS }
- * shifted right by POLICY_IPSEC_SHIFT.
- */
-struct db_sa ipsec_sadb[1 << 3] = {
- { AD_NULL }, /* none */
- { AD(esp_props) }, /* POLICY_ENCRYPT */
- { AD(ah_props) }, /* POLICY_AUTHENTICATE */
- { AD(ah_esp_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE */
- { AD(compress_props) }, /* POLICY_COMPRESS */
- { AD(esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_COMPRESS */
- { AD(ah_compress_props) }, /* POLICY_AUTHENTICATE+POLICY_COMPRESS */
- { AD(ah_esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE+POLICY_COMPRESS */
- };
-
-#undef AD
-#undef AD_NULL
-
-/* output an attribute (within an SA) */
-static bool
-out_attr(int type
-, unsigned long val
-, struct_desc *attr_desc
-, enum_names **attr_val_descs USED_BY_DEBUG
-, pb_stream *pbs)
-{
- struct isakmp_attribute attr;
-
- if (val >> 16 == 0)
- {
- /* short value: use TV form */
- attr.isaat_af_type = type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = val;
- if (!out_struct(&attr, attr_desc, pbs, NULL))
- return FALSE;
- }
- else
- {
- /* This is a real fudge! Since we rarely use long attributes
- * and since this is the only place where we can cause an
- * ISAKMP message length to be other than a multiple of 4 octets,
- * we force the length of the value to be a multiple of 4 octets.
- * Furthermore, we only handle values up to 4 octets in length.
- * Voila: a fixed format!
- */
- pb_stream val_pbs;
- u_int32_t nval = htonl(val);
-
- attr.isaat_af_type = type | ISAKMP_ATTR_AF_TLV;
- if (!out_struct(&attr, attr_desc, pbs, &val_pbs)
- || !out_raw(&nval, sizeof(nval), &val_pbs, "long attribute value"))
- return FALSE;
- close_output_pbs(&val_pbs);
- }
- DBG(DBG_EMITTING,
- enum_names *d = attr_val_descs[type];
-
- if (d != NULL)
- DBG_log(" [%lu is %s]"
- , val, enum_show(d, val)));
- return TRUE;
-}
-#define return_on(var, val) do { var=val;goto return_out; } while(0);
-/* Output an SA, as described by a db_sa.
- * This has the side-effect of allocating SPIs for us.
- */
-bool
-out_sa(pb_stream *outs
-, struct db_sa *sadb
-, struct state *st
-, bool oakley_mode
-, u_int8_t np)
-{
- pb_stream sa_pbs;
- int pcn;
- bool ret = FALSE;
- bool ah_spi_generated = FALSE
- , esp_spi_generated = FALSE
- , ipcomp_cpi_generated = FALSE;
-#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
- struct db_context *db_ctx = NULL;
-#endif
-
- /* SA header out */
- {
- struct isakmp_sa sa;
-
- sa.isasa_np = np;
- st->st_doi = sa.isasa_doi = ISAKMP_DOI_IPSEC; /* all we know */
- if (!out_struct(&sa, &isakmp_sa_desc, outs, &sa_pbs))
- return_on(ret, FALSE);
- }
-
- /* within SA: situation out */
- st->st_situation = SIT_IDENTITY_ONLY;
- if (!out_struct(&st->st_situation, &ipsec_sit_desc, &sa_pbs, NULL))
- return_on(ret, FALSE);
-
- /* within SA: Proposal Payloads
- *
- * Multiple Proposals with the same number are simultaneous
- * (conjuncts) and must deal with different protocols (AH or ESP).
- * Proposals with different numbers are alternatives (disjuncts),
- * in preference order.
- * Proposal numbers must be monotonic.
- * See RFC 2408 "ISAKMP" 4.2
- */
-
- for (pcn = 0; pcn != sadb->prop_conj_cnt; pcn++)
- {
- struct db_prop_conj *pc = &sadb->prop_conjs[pcn];
- int pn;
-
- for (pn = 0; pn != pc->prop_cnt; pn++)
- {
- struct db_prop *p = &pc->props[pn];
- pb_stream proposal_pbs;
- struct isakmp_proposal proposal;
- struct_desc *trans_desc;
- struct_desc *attr_desc;
- enum_names **attr_val_descs;
- int tn;
- bool tunnel_mode;
-
- tunnel_mode = (pn == pc->prop_cnt-1)
- && (st->st_policy & POLICY_TUNNEL);
-
- /* Proposal header */
- proposal.isap_np = pcn == sadb->prop_conj_cnt-1 && pn == pc->prop_cnt-1
- ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_P;
- proposal.isap_proposal = pcn;
- proposal.isap_protoid = p->protoid;
- proposal.isap_spisize = oakley_mode ? 0
- : p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE
- : IPSEC_DOI_SPI_SIZE;
-
- /* In quick mode ONLY, create proposal for runtime kernel algos.
- * Replace ESP proposals with runtime created one
- */
- if (!oakley_mode && p->protoid == PROTO_IPSEC_ESP)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- if (st->st_connection->alg_info_esp)
- {
- static char buf[256]="";
-
- alg_info_snprint(buf, sizeof (buf),
- (struct alg_info *)st->st_connection->alg_info_esp);
- DBG_log(buf);
- }
- )
- db_ctx = kernel_alg_db_new(st->st_connection->alg_info_esp, st->st_policy);
- p = db_prop_get(db_ctx);
-
- if (!p || p->trans_cnt == 0)
- {
- loglog(RC_LOG_SERIOUS,
- "empty IPSEC SA proposal to send "
- "(no kernel algorithms for esp selection)");
- return_on(ret, FALSE);
- }
- }
-
- if (oakley_mode && p->protoid == PROTO_ISAKMP)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- if (st->st_connection->alg_info_ike)
- {
- static char buf[256]="";
-
- alg_info_snprint(buf, sizeof (buf),
- (struct alg_info *)st->st_connection->alg_info_ike);
- DBG_log(buf);
- }
- )
- db_ctx = ike_alg_db_new(st->st_connection->alg_info_ike, st->st_policy);
- p = db_prop_get(db_ctx);
-
- if (!p || p->trans_cnt == 0)
- {
- loglog(RC_LOG_SERIOUS,
- "empty ISAKMP SA proposal to send "
- "(no algorithms for ike selection?)");
- return_on(ret, FALSE);
- }
- }
-
- proposal.isap_notrans = p->trans_cnt;
- if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs))
- return_on(ret, FALSE);
-
- /* Per-protocols stuff:
- * Set trans_desc.
- * Set attr_desc.
- * Set attr_val_descs.
- * If not oakley_mode, emit SPI.
- * We allocate SPIs on demand.
- * All ESPs in an SA will share a single SPI.
- * All AHs in an SAwill share a single SPI.
- * AHs' SPI will be distinct from ESPs'.
- * This latter is needed because KLIPS doesn't
- * use the protocol when looking up a (dest, protocol, spi).
- * ??? If multiple ESPs are composed, how should their SPIs
- * be allocated?
- */
- {
- ipsec_spi_t *spi_ptr = NULL;
- int proto = 0;
- bool *spi_generated = NULL;
-
- switch (p->protoid)
- {
- case PROTO_ISAKMP:
- passert(oakley_mode);
- trans_desc = &isakmp_isakmp_transform_desc;
- attr_desc = &isakmp_oakley_attribute_desc;
- attr_val_descs = oakley_attr_val_descs;
- /* no SPI needed */
- break;
- case PROTO_IPSEC_AH:
- passert(!oakley_mode);
- trans_desc = &isakmp_ah_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
- spi_ptr = &st->st_ah.our_spi;
- spi_generated = &ah_spi_generated;
- proto = IPPROTO_AH;
- break;
- case PROTO_IPSEC_ESP:
- passert(!oakley_mode);
- trans_desc = &isakmp_esp_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
- spi_ptr = &st->st_esp.our_spi;
- spi_generated = &esp_spi_generated;
- proto = IPPROTO_ESP;
- break;
- case PROTO_IPCOMP:
- passert(!oakley_mode);
- trans_desc = &isakmp_ipcomp_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
-
- /* a CPI isn't quite the same as an SPI
- * so we use specialized code to emit it.
- */
- if (!ipcomp_cpi_generated)
- {
- st->st_ipcomp.our_spi = get_my_cpi(
- &st->st_connection->spd, tunnel_mode);
- if (st->st_ipcomp.our_spi == 0)
- return_on(ret, FALSE); /* problem generating CPI */
-
- ipcomp_cpi_generated = TRUE;
- }
- /* CPI is stored in network low order end of an
- * ipsec_spi_t. So we start a couple of bytes in.
- */
- if (!out_raw((u_char *)&st->st_ipcomp.our_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE
- , &proposal_pbs, "CPI"))
- return_on(ret, FALSE);
- break;
- default:
- bad_case(p->protoid);
- }
- if (spi_ptr != NULL)
- {
- if (!*spi_generated)
- {
- *spi_ptr = get_ipsec_spi(0
- , proto
- , &st->st_connection->spd
- , tunnel_mode);
- if (*spi_ptr == 0)
- return FALSE;
- *spi_generated = TRUE;
- }
- if (!out_raw((u_char *)spi_ptr, IPSEC_DOI_SPI_SIZE
- , &proposal_pbs, "SPI"))
- return_on(ret, FALSE);
- }
- }
-
- /* within proposal: Transform Payloads */
- for (tn = 0; tn != p->trans_cnt; tn++)
- {
- struct db_trans *t = &p->trans[tn];
- pb_stream trans_pbs;
- struct isakmp_transform trans;
- int an;
-
- trans.isat_np = (tn == p->trans_cnt - 1)
- ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_T;
- trans.isat_transnum = tn;
- trans.isat_transid = t->transid;
- if (!out_struct(&trans, trans_desc, &proposal_pbs, &trans_pbs))
- return_on(ret, FALSE);
-
- /* Within tranform: Attributes. */
-
- /* For Phase 2 / Quick Mode, GROUP_DESCRIPTION is
- * automatically generated because it must be the same
- * in every transform. Except IPCOMP.
- */
- if (p->protoid != PROTO_IPCOMP
- && st->st_pfs_group != NULL)
- {
- passert(!oakley_mode);
- passert(st->st_pfs_group != &unset_group);
- out_attr(GROUP_DESCRIPTION, st->st_pfs_group->group
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
-
- /* automatically generate duration
- * and, for Phase 2 / Quick Mode, encapsulation.
- */
- if (oakley_mode)
- {
- out_attr(OAKLEY_LIFE_TYPE, OAKLEY_LIFE_SECONDS
- , attr_desc, attr_val_descs
- , &trans_pbs);
- out_attr(OAKLEY_LIFE_DURATION
- , st->st_connection->sa_ike_life_seconds
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
- else
- {
- /* RFC 2407 (IPSEC DOI) 4.5 specifies that
- * the default is "unspecified (host-dependent)".
- * This makes little sense, so we always specify it.
- *
- * Unlike other IPSEC transforms, IPCOMP defaults
- * to Transport Mode, so we can exploit the default
- * (draft-shacham-ippcp-rfc2393bis-05.txt 4.1).
- */
- if (p->protoid != PROTO_IPCOMP
- || st->st_policy & POLICY_TUNNEL)
- {
-#ifdef NAT_TRAVERSAL
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- if ((st->nat_traversal & NAT_T_DETECTED)
- && !(st->st_policy & POLICY_TUNNEL))
- {
- /* Inform user that we will not respect policy and only
- * propose Tunnel Mode
- */
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "Transport Mode not allowed due to security concerns -- "
- "using Tunnel mode");
- }
-#endif
-#endif
- out_attr(ENCAPSULATION_MODE
-#ifdef NAT_TRAVERSAL
-#ifdef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- , NAT_T_ENCAPSULATION_MODE(st,st->st_policy)
-#else
- /* If NAT-T is detected, use UDP_TUNNEL as long as Transport
- * Mode has security concerns.
- *
- * User has been informed of that
- */
- , NAT_T_ENCAPSULATION_MODE(st,POLICY_TUNNEL)
-#endif
-#else /* ! NAT_TRAVERSAL */
- , st->st_policy & POLICY_TUNNEL
- ? ENCAPSULATION_MODE_TUNNEL : ENCAPSULATION_MODE_TRANSPORT
-#endif
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
- out_attr(SA_LIFE_TYPE, SA_LIFE_TYPE_SECONDS
- , attr_desc, attr_val_descs
- , &trans_pbs);
- out_attr(SA_LIFE_DURATION
- , st->st_connection->sa_ipsec_life_seconds
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
-
- /* spit out attributes from table */
- for (an = 0; an != t->attr_cnt; an++)
- {
- struct db_attr *a = &t->attrs[an];
-
- out_attr(a->type, a->val
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
-
- close_output_pbs(&trans_pbs);
- }
- close_output_pbs(&proposal_pbs);
- }
- /* end of a conjunction of proposals */
- }
- close_output_pbs(&sa_pbs);
- ret = TRUE;
-
-return_out:
-
-#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
- if (db_ctx)
- db_destroy(db_ctx);
-#endif
- return ret;
-}
-
-/* Handle long form of duration attribute.
- * The code is can only handle values that can fit in unsigned long.
- * "Clamping" is probably an acceptable way to impose this limitation.
- */
-static u_int32_t
-decode_long_duration(pb_stream *pbs)
-{
- u_int32_t val = 0;
-
- /* ignore leading zeros */
- while (pbs_left(pbs) != 0 && *pbs->cur == '\0')
- pbs->cur++;
-
- if (pbs_left(pbs) > sizeof(val))
- {
- /* "clamp" too large value to max representable value */
- val -= 1; /* portable way to get to maximum value */
- DBG(DBG_PARSING, DBG_log(" too large duration clamped to: %lu"
- , (unsigned long)val));
- }
- else
- {
- /* decode number */
- while (pbs_left(pbs) != 0)
- val = (val << BITS_PER_BYTE) | *pbs->cur++;
- DBG(DBG_PARSING, DBG_log(" long duration: %lu", (unsigned long)val));
- }
- return val;
-}
-
-/* Preparse the body of an ISAKMP SA Payload and
- * return body of ISAKMP Proposal Payload
- *
- * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
- * Error response is rudimentary.
- */
-notification_t
-preparse_isakmp_sa_body(const struct isakmp_sa *sa
- , pb_stream *sa_pbs
- , u_int32_t *ipsecdoisit
- , pb_stream *proposal_pbs
- , struct isakmp_proposal *proposal)
-{
- /* DOI */
- if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
- {
- loglog(RC_LOG_SERIOUS, "Unknown/unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
- /* XXX Could send notification back */
- return DOI_NOT_SUPPORTED;
- }
-
- /* Situation */
- if (!in_struct(ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
- return SITUATION_NOT_SUPPORTED;
-
- if (*ipsecdoisit != SIT_IDENTITY_ONLY)
- {
- loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
- , bitnamesof(sit_bit_names, *ipsecdoisit));
- /* XXX Could send notification back */
- return SITUATION_NOT_SUPPORTED;
- }
-
- /* The rules for ISAKMP SAs are scattered.
- * RFC 2409 "IKE" section 5 says that there
- * can only be one SA, and it can have only one proposal in it.
- * There may well be multiple transforms.
- */
- if (!in_struct(proposal, &isakmp_proposal_desc, sa_pbs, proposal_pbs))
- return PAYLOAD_MALFORMED;
-
- if (proposal->isap_np != ISAKMP_NEXT_NONE)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload must be alone in Oakley SA; found %s following Proposal"
- , enum_show(&payload_names, proposal->isap_np));
- return PAYLOAD_MALFORMED;
- }
-
- if (proposal->isap_protoid != PROTO_ISAKMP)
- {
- loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) found in Oakley Proposal"
- , enum_show(&protocol_names, proposal->isap_protoid));
- return INVALID_PROTOCOL_ID;
- }
-
- /* Just what should we accept for the SPI field?
- * The RFC is sort of contradictory. We will ignore the SPI
- * as long as it is of the proper size.
- *
- * From RFC2408 2.4 Identifying Security Associations:
- * During phase 1 negotiations, the initiator and responder cookies
- * determine the ISAKMP SA. Therefore, the SPI field in the Proposal
- * payload is redundant and MAY be set to 0 or it MAY contain the
- * transmitting entity's cookie.
- *
- * From RFC2408 3.5 Proposal Payload:
- * o SPI Size (1 octet) - Length in octets of the SPI as defined by
- * the Protocol-Id. In the case of ISAKMP, the Initiator and
- * Responder cookie pair from the ISAKMP Header is the ISAKMP SPI,
- * therefore, the SPI Size is irrelevant and MAY be from zero (0) to
- * sixteen (16). If the SPI Size is non-zero, the content of the
- * SPI field MUST be ignored. If the SPI Size is not a multiple of
- * 4 octets it will have some impact on the SPI field and the
- * alignment of all payloads in the message. The Domain of
- * Interpretation (DOI) will dictate the SPI Size for other
- * protocols.
- */
- if (proposal->isap_spisize == 0)
- {
- /* empty (0) SPI -- fine */
- }
- else if (proposal->isap_spisize <= MAX_ISAKMP_SPI_SIZE)
- {
- u_char junk_spi[MAX_ISAKMP_SPI_SIZE];
-
- if (!in_raw(junk_spi, proposal->isap_spisize, proposal_pbs, "Oakley SPI"))
- return PAYLOAD_MALFORMED;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "invalid SPI size (%u) in Oakley Proposal"
- , (unsigned)proposal->isap_spisize);
- return INVALID_SPI;
- }
- return NOTHING_WRONG;
-}
-
-static struct {
- u_int8_t *start;
- u_int8_t *cur;
- u_int8_t *roof;
-} backup;
-
-/*
- * backup the pointer into a pb_stream
- */
-void
-backup_pbs(pb_stream *pbs)
-{
- backup.start = pbs->start;
- backup.cur = pbs->cur;
- backup.roof = pbs->roof;
-}
-
-/*
- * restore the pointer into a pb_stream
- */
-void
-restore_pbs(pb_stream *pbs)
-{
- pbs->start = backup.start;
- pbs->cur = backup.cur;
- pbs->roof = backup.roof;
-}
-
-/*
- * Parse an ISAKMP Proposal Payload for RSA and PSK authentication policies
- */
-notification_t
-parse_isakmp_policy(pb_stream *proposal_pbs
- , u_int notrans
- , lset_t *policy)
-{
- int last_transnum = -1;
-
- *policy = LEMPTY;
-
- while (notrans--)
- {
- pb_stream trans_pbs;
- u_char *attr_start;
- size_t attr_len;
- struct isakmp_transform trans;
-
- if (!in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs))
- return BAD_PROPOSAL_SYNTAX;
-
- if (trans.isat_transnum <= last_transnum)
- {
- /* picky, picky, picky */
- loglog(RC_LOG_SERIOUS, "Transform Numbers are not monotonically increasing"
- " in Oakley Proposal");
- return BAD_PROPOSAL_SYNTAX;
- }
- last_transnum = trans.isat_transnum;
-
- if (trans.isat_transid != KEY_IKE)
- {
- loglog(RC_LOG_SERIOUS, "expected KEY_IKE but found %s in Oakley Transform"
- , enum_show(&isakmp_transformid_names, trans.isat_transid));
- return INVALID_TRANSFORM_ID;
- }
-
- attr_start = trans_pbs.cur;
- attr_len = pbs_left(&trans_pbs);
-
- /* preprocess authentication attributes only */
- while (pbs_left(&trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
-
- if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
- return BAD_PROPOSAL_SYNTAX;
-
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
- switch (a.isaat_af_type)
- {
- case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
- switch (a.isaat_lv)
- {
- case OAKLEY_PRESHARED_KEY:
- *policy |= POLICY_PSK;
- break;
- case OAKLEY_RSA_SIG:
- *policy |= POLICY_RSASIG;
- break;
- case XAUTHInitPreShared:
- *policy |= POLICY_XAUTH_SERVER;
- /* fall through */
- case XAUTHRespPreShared:
- *policy |= POLICY_XAUTH_PSK;
- break;
- case XAUTHInitRSA:
- *policy |= POLICY_XAUTH_SERVER;
- /* fall through */
- case XAUTHRespRSA:
- *policy |= POLICY_XAUTH_RSASIG;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- }
- DBG(DBG_CONTROL|DBG_PARSING,
- DBG_log("preparse_isakmp_policy: peer requests %s authentication"
- , prettypolicy(*policy))
- )
- return NOTHING_WRONG;
-}
-
-/*
- * check that we can find a preshared secret
- */
-static err_t
-find_preshared_key(struct state* st)
-{
- err_t ugh = NULL;
- struct connection *c = st->st_connection;
-
- if (get_preshared_secret(c) == NULL)
- {
- char my_id[BUF_LEN], his_id[BUF_LEN];
-
- idtoa(&c->spd.this.id, my_id, sizeof(my_id));
- if (his_id_was_instantiated(c))
- strcpy(his_id, "%any");
- else
- idtoa(&c->spd.that.id, his_id, sizeof(his_id));
- ugh = builddiag("Can't authenticate: no preshared key found for `%s' and `%s'"
- , my_id, his_id);
- }
- return ugh;
-}
-
-/* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
- * Various shortcuts are taken. In particular, the policy, such as
- * it is, is hardwired.
- *
- * If r_sa is non-NULL, the body of an SA representing the selected
- * proposal is emitted.
- *
- * This routine is used by main_inI1_outR1() and main_inR1_outI2().
- */
-notification_t
-parse_isakmp_sa_body(u_int32_t ipsecdoisit
- , pb_stream *proposal_pbs
- , struct isakmp_proposal *proposal
- , pb_stream *r_sa_pbs
- , struct state *st
- , bool initiator)
-{
- struct connection *c = st->st_connection;
- unsigned no_trans_left;
-
- /* for each transform payload... */
- no_trans_left = proposal->isap_notrans;
-
- for (;;)
- {
- pb_stream trans_pbs;
- u_char *attr_start;
- size_t attr_len;
- struct isakmp_transform trans;
- lset_t seen_attrs = 0;
- lset_t seen_durations = 0;
- u_int16_t life_type = 0;
- struct oakley_trans_attrs ta;
- err_t ugh = NULL; /* set to diagnostic when problem detected */
-
- /* initialize only optional field in ta */
- ta.life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT; /* When this SA expires (seconds) */
-
- if (no_trans_left == 0)
- {
- loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs);
- attr_start = trans_pbs.cur;
- attr_len = pbs_left(&trans_pbs);
-
- /* process all the attributes that make up the transform */
-
- while (pbs_left(&trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
- u_int32_t val; /* room for larger values */
-
- if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
- return BAD_PROPOSAL_SYNTAX;
-
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
- if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
- {
- loglog(RC_LOG_SERIOUS, "repeated %s attribute in Oakley Transform %u"
- , enum_show(&oakley_attr_names, a.isaat_af_type)
- , trans.isat_transnum);
- return BAD_PROPOSAL_SYNTAX;
- }
-
- seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
-
- val = a.isaat_lv;
-
- DBG(DBG_PARSING,
- {
- enum_names *vdesc = oakley_attr_val_descs
- [a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
-
- if (vdesc != NULL)
- {
- const char *nm = enum_name(vdesc, val);
-
- if (nm != NULL)
- DBG_log(" [%u is %s]", (unsigned)val, nm);
- }
- });
-
- switch (a.isaat_af_type)
- {
- case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV:
- if (ike_alg_enc_present(val))
- {
- ta.encrypt = val;
- ta.encrypter = ike_alg_get_encrypter(val);
- ta.enckeylen = ta.encrypter->keydeflen;
- }
- else
- {
- ugh = builddiag("%s is not supported"
- , enum_show(&oakley_enc_names, val));
- }
- break;
-
- case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV:
- if (ike_alg_hash_present(val))
- {
- ta.hash = val;
- ta.hasher = ike_alg_get_hasher(val);
- }
- else
- {
- ugh = builddiag("%s is not supported"
- , enum_show(&oakley_hash_names, val));
- }
- break;
-
- case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
- {
- /* check that authentication method is acceptable */
- lset_t iap = st->st_policy & POLICY_ID_AUTH_MASK;
-
- /* is the initiator the XAUTH client? */
- bool xauth_init = initiator && (st->st_policy & POLICY_XAUTH_SERVER) == LEMPTY
- || !initiator && (st->st_policy & POLICY_XAUTH_SERVER) != LEMPTY;
-
- switch (val)
- {
- case OAKLEY_PRESHARED_KEY:
- if ((iap & POLICY_PSK) == LEMPTY)
- {
- ugh = "policy does not allow OAKLEY_PRESHARED_KEY authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = OAKLEY_PRESHARED_KEY;
- }
- break;
- case XAUTHInitPreShared:
- if ((iap & POLICY_XAUTH_PSK) == LEMPTY || !xauth_init)
- {
- ugh = "policy does not allow XAUTHInitPreShared authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = XAUTHInitPreShared;
- }
- break;
- case XAUTHRespPreShared:
- if ((iap & POLICY_XAUTH_PSK) == LEMPTY || xauth_init)
- {
- ugh = "policy does not allow XAUTHRespPreShared authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = XAUTHRespPreShared;
- }
- break;
- case OAKLEY_RSA_SIG:
- /* Accept if policy specifies RSASIG or is default */
- if ((iap & POLICY_RSASIG) == LEMPTY)
- {
- ugh = "policy does not allow OAKLEY_RSA_SIG authentication";
- }
- else
- {
- ta.auth = OAKLEY_RSA_SIG;
- }
- break;
- case XAUTHInitRSA:
- if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || !xauth_init)
- {
- ugh = "policy does not allow XAUTHInitRSA authentication";
- }
- else
- {
- ta.auth = XAUTHInitRSA;
- }
- break;
- case XAUTHRespRSA:
- if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || xauth_init)
- {
- ugh = "policy does not allow XAUTHRespRSA authentication";
- }
- else
- {
- ta.auth = XAUTHRespRSA;
- }
- break;
- default:
- ugh = builddiag("Pluto does not support %s authentication"
- , enum_show(&oakley_auth_names, val));
- break;
- }
- }
- break;
-
- case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
- ta.group = lookup_group(val);
- if (ta.group == NULL)
- {
- ugh = "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported";
- }
- break;
-
- case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
- switch (val)
- {
- case OAKLEY_LIFE_SECONDS:
- case OAKLEY_LIFE_KILOBYTES:
- if (LHAS(seen_durations, val))
- {
- loglog(RC_LOG_SERIOUS
- , "attribute OAKLEY_LIFE_TYPE value %s repeated"
- , enum_show(&oakley_lifetime_names, val));
- return BAD_PROPOSAL_SYNTAX;
- }
- seen_durations |= LELEM(val);
- life_type = val;
- break;
- default:
- ugh = builddiag("unknown value %s"
- , enum_show(&oakley_lifetime_names, val));
- break;
- }
- break;
-
- case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- val = decode_long_duration(&attr_pbs);
- /* fall through */
- case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
- if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE))
- {
- ugh = "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute";
- break;
- }
- seen_attrs &= ~(LELEM(OAKLEY_LIFE_DURATION) | LELEM(OAKLEY_LIFE_TYPE));
-
- switch (life_type)
- {
- case OAKLEY_LIFE_SECONDS:
- if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)
- {
-#ifdef CISCO_QUIRKS
- plog("peer requested %lu seconds"
- " which exceeds our limit %d seconds"
- , (long) val
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
- plog("lifetime reduced to %d seconds "
- "(todo: IPSEC_RESPONDER_LIFETIME notification)"
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
- val = OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM;
-#else
- ugh = builddiag("peer requested %lu seconds"
- " which exceeds our limit %d seconds"
- , (long) val
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
-#endif
- }
- ta.life_seconds = val;
- break;
- case OAKLEY_LIFE_KILOBYTES:
- ta.life_kilobytes = val;
- break;
- default:
- bad_case(life_type);
- }
- break;
-
- case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:
- if ((seen_attrs & LELEM(OAKLEY_ENCRYPTION_ALGORITHM)) == 0)
- {
- ugh = "OAKLEY_KEY_LENGTH attribute not preceded by "
- "OAKLEY_ENCRYPTION_ALGORITHM attribute";
- break;
- }
- if (ta.encrypter == NULL)
- {
- ugh = "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM";
- break;
- }
- /*
- * check if this keylen is compatible with specified algorithm
- */
- if (val
- && (val < ta.encrypter->keyminlen || val > ta.encrypter->keymaxlen))
- {
- ugh = "peer proposed key length not valid for "
- "encryption algorithm specified";
- }
- ta.enckeylen = val;
- break;
-#if 0 /* not yet supported */
- case OAKLEY_GROUP_TYPE | ISAKMP_ATTR_AF_TV:
- case OAKLEY_PRF | ISAKMP_ATTR_AF_TV:
- case OAKLEY_FIELD_SIZE | ISAKMP_ATTR_AF_TV:
-
- case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:
-#endif
- default:
- ugh = "unsupported OAKLEY attribute";
- break;
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s. Attribute %s"
- , ugh, enum_show(&oakley_attr_names, a.isaat_af_type));
- break;
- }
- }
-
- /*
- * ML: at last check for allowed transforms in alg_info_ike
- * (ALG_INFO_F_STRICT flag)
- */
- if (ugh == NULL)
- {
- if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,
- ta.group ? ta.group->group : -1, c->alg_info_ike))
- {
- ugh = "OAKLEY proposal refused";
- }
- }
-
- if (ugh == NULL)
- {
- /* a little more checking is in order */
- {
- lset_t missing
- = ~seen_attrs
- & (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)
- | LELEM(OAKLEY_HASH_ALGORITHM)
- | LELEM(OAKLEY_AUTHENTICATION_METHOD)
- | LELEM(OAKLEY_GROUP_DESCRIPTION));
-
- if (missing)
- {
- loglog(RC_LOG_SERIOUS, "missing mandatory attribute(s) %s in Oakley Transform %u"
- , bitnamesof(oakley_attr_bit_names, missing)
- , trans.isat_transnum);
- return BAD_PROPOSAL_SYNTAX;
- }
- }
- /* We must have liked this transform.
- * Lets finish early and leave.
- */
-
- DBG(DBG_PARSING | DBG_CRYPT
- , DBG_log("Oakley Transform %u accepted", trans.isat_transnum));
-
- if (r_sa_pbs != NULL)
- {
- struct isakmp_proposal r_proposal = *proposal;
- pb_stream r_proposal_pbs;
- struct isakmp_transform r_trans = trans;
- pb_stream r_trans_pbs;
-
- /* Situation */
- if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
- impossible();
-
- /* Proposal */
-#ifdef EMIT_ISAKMP_SPI
- r_proposal.isap_spisize = COOKIE_SIZE;
-#else
- r_proposal.isap_spisize = 0;
-#endif
- r_proposal.isap_notrans = 1;
- if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
- impossible();
-
- /* SPI */
-#ifdef EMIT_ISAKMP_SPI
- if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI"))
- impossible();
- r_proposal.isap_spisize = COOKIE_SIZE;
-#else
- /* none (0) */
-#endif
-
- /* Transform */
- r_trans.isat_np = ISAKMP_NEXT_NONE;
- if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs))
- impossible();
-
- if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes"))
- impossible();
- close_output_pbs(&r_trans_pbs);
- close_output_pbs(&r_proposal_pbs);
- close_output_pbs(r_sa_pbs);
- }
-
- /* copy over the results */
- st->st_oakley = ta;
- return NOTHING_WRONG;
- }
-
- /* on to next transform */
- no_trans_left--;
-
- if (trans.isat_np == ISAKMP_NEXT_NONE)
- {
- if (no_trans_left != 0)
- {
- loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
- return BAD_PROPOSAL_SYNTAX;
- }
- break;
- }
- if (trans.isat_np != ISAKMP_NEXT_T)
- {
- loglog(RC_LOG_SERIOUS, "unexpected %s payload in Oakley Proposal"
- , enum_show(&payload_names, proposal->isap_np));
- return BAD_PROPOSAL_SYNTAX;
- }
- }
- loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform");
- return NO_PROPOSAL_CHOSEN;
-}
-
-/* Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode).
- *
- * The main routine is parse_ipsec_sa_body; other functions defined
- * between here and there are just helpers.
- *
- * Various shortcuts are taken. In particular, the policy, such as
- * it is, is hardwired.
- *
- * If r_sa is non-NULL, the body of an SA representing the selected
- * proposal is emitted into it.
- *
- * If "selection" is true, the SA is supposed to represent the
- * single tranform that the peer has accepted.
- * ??? We only check that it is acceptable, not that it is one that we offered!
- *
- * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
- * Error response is rudimentary.
- *
- * Since all ISAKMP groups in all SA Payloads must match, st->st_pfs_group
- * holds this across multiple payloads.
- * &unset_group signifies not yet "set"; NULL signifies NONE.
- *
- * This routine is used by quick_inI1_outR1() and quick_inR1_outI2().
- */
-
-static const struct ipsec_trans_attrs null_ipsec_trans_attrs = {
- 0, /* transid (NULL, for now) */
- 0, /* spi */
- SA_LIFE_DURATION_DEFAULT, /* life_seconds */
- SA_LIFE_DURATION_K_DEFAULT, /* life_kilobytes */
- ENCAPSULATION_MODE_UNSPECIFIED, /* encapsulation */
- AUTH_ALGORITHM_NONE, /* auth */
- 0, /* key_len */
- 0, /* key_rounds */
-};
-
-static bool
-parse_ipsec_transform(struct isakmp_transform *trans
-, struct ipsec_trans_attrs *attrs
-, pb_stream *prop_pbs
-, pb_stream *trans_pbs
-, struct_desc *trans_desc
-, int previous_transnum /* or -1 if none */
-, bool selection
-, bool is_last
-, bool is_ipcomp
-, struct state *st) /* current state object */
-{
- lset_t seen_attrs = 0;
- lset_t seen_durations = 0;
- u_int16_t life_type = 0;
- const struct oakley_group_desc *pfs_group = NULL;
-
- if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
- return FALSE;
-
- if (trans->isat_transnum <= previous_transnum)
- {
- loglog(RC_LOG_SERIOUS, "Transform Numbers in Proposal are not monotonically increasing");
- return FALSE;
- }
-
- switch (trans->isat_np)
- {
- case ISAKMP_NEXT_T:
- if (is_last)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload has more Transforms than specified");
- return FALSE;
- }
- break;
- case ISAKMP_NEXT_NONE:
- if (!is_last)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload has fewer Transforms than specified");
- return FALSE;
- }
- break;
- default:
- loglog(RC_LOG_SERIOUS, "expecting Transform Payload, but found %s in Proposal"
- , enum_show(&payload_names, trans->isat_np));
- return FALSE;
- }
-
- *attrs = null_ipsec_trans_attrs;
- attrs->transid = trans->isat_transid;
-
- while (pbs_left(trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
- enum_names *vdesc;
- u_int32_t val; /* room for larger value */
- bool ipcomp_inappropriate = is_ipcomp; /* will get reset if OK */
-
- if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs, &attr_pbs))
- return FALSE;
-
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
- if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
- {
- loglog(RC_LOG_SERIOUS, "repeated %s attribute in IPsec Transform %u"
- , enum_show(&ipsec_attr_names, a.isaat_af_type)
- , trans->isat_transnum);
- return FALSE;
- }
-
- seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
-
- val = a.isaat_lv;
-
- vdesc = ipsec_attr_val_descs[a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
- if (vdesc != NULL)
- {
- if (enum_name(vdesc, val) == NULL)
- {
- loglog(RC_LOG_SERIOUS, "invalid value %u for attribute %s in IPsec Transform"
- , (unsigned)val, enum_show(&ipsec_attr_names, a.isaat_af_type));
- return FALSE;
- }
- DBG(DBG_PARSING
- , if ((a.isaat_af_type & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- DBG_log(" [%u is %s]"
- , (unsigned)val, enum_show(vdesc, val)));
- }
-
- switch (a.isaat_af_type)
- {
- case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
- if (LHAS(seen_durations, val))
- {
- loglog(RC_LOG_SERIOUS, "attribute SA_LIFE_TYPE value %s repeated in message"
- , enum_show(&sa_lifetime_names, val));
- return FALSE;
- }
- seen_durations |= LELEM(val);
- life_type = val;
- break;
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- val = decode_long_duration(&attr_pbs);
- /* fall through */
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
- if (!LHAS(seen_attrs, SA_LIFE_DURATION))
- {
- loglog(RC_LOG_SERIOUS, "SA_LIFE_DURATION IPsec attribute not preceded by SA_LIFE_TYPE attribute");
- return FALSE;
- }
- seen_attrs &= ~(LELEM(SA_LIFE_DURATION) | LELEM(SA_LIFE_TYPE));
-
- switch (life_type)
- {
- case SA_LIFE_TYPE_SECONDS:
- /* silently limit duration to our maximum */
- attrs->life_seconds = val <= SA_LIFE_DURATION_MAXIMUM
- ? val : SA_LIFE_DURATION_MAXIMUM;
- break;
- case SA_LIFE_TYPE_KBYTES:
- attrs->life_kilobytes = val;
- break;
- default:
- bad_case(life_type);
- }
- break;
- case GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
- if (is_ipcomp)
- {
- /* Accept reluctantly. Should not happen, according to
- * draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
- */
- ipcomp_inappropriate = FALSE;
- loglog(RC_COMMENT
- , "IPCA (IPcomp SA) contains GROUP_DESCRIPTION."
- " Ignoring inapproprate attribute.");
- }
- pfs_group = lookup_group(val);
- if (pfs_group == NULL)
- {
- loglog(RC_LOG_SERIOUS, "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported for PFS");
- return FALSE;
- }
- break;
- case ENCAPSULATION_MODE | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
-#ifdef NAT_TRAVERSAL
- switch (val)
- {
- case ENCAPSULATION_MODE_TUNNEL:
- case ENCAPSULATION_MODE_TRANSPORT:
- if (st->nat_traversal & NAT_T_DETECTED)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is not detected"
- , enum_name(&enc_mode_names, val));
- /*
- * Accept it anyway because SSH-Sentinel does not
- * use UDP_TUNNEL or UDP_TRANSPORT for the diagnostic.
- *
- * remove when SSH-Sentinel is fixed
- */
-#ifdef I_DONT_CARE_OF_SSH_SENTINEL
- return FALSE;
-#endif
- }
- attrs->encapsulation = val;
- break;
- case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS:
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- loglog(RC_LOG_SERIOUS
- , "NAT-Traversal: Transport mode disabled due to security concerns");
- return FALSE;
-#endif
- case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS:
- if (st->nat_traversal & NAT_T_WITH_RFC_VALUES)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used with old IETF drafts"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- else if (st->nat_traversal & NAT_T_DETECTED)
- {
- attrs->encapsulation = val
- - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS
- + ENCAPSULATION_MODE_TUNNEL;
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is detected"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- break;
- case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC:
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- loglog(RC_LOG_SERIOUS
- , "NAT-Traversal: Transport mode disabled due "
- "to security concerns");
- return FALSE;
-#endif
- case ENCAPSULATION_MODE_UDP_TUNNEL_RFC:
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->nat_traversal & NAT_T_WITH_RFC_VALUES))
- {
- attrs->encapsulation = val
- - ENCAPSULATION_MODE_UDP_TUNNEL_RFC
- + ENCAPSULATION_MODE_TUNNEL;
- }
- else if (st->nat_traversal & NAT_T_DETECTED)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used with NAT-T RFC"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is detected"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- break;
- default:
- loglog(RC_LOG_SERIOUS
- , "unknown ENCAPSULATION_MODE %d in IPSec SA", val);
- return FALSE;
- }
-#else
- attrs->encapsulation = val;
-#endif
- break;
- case AUTH_ALGORITHM | ISAKMP_ATTR_AF_TV:
- attrs->auth = val;
- break;
- case KEY_LENGTH | ISAKMP_ATTR_AF_TV:
- attrs->key_len = val;
- break;
- case KEY_ROUNDS | ISAKMP_ATTR_AF_TV:
- attrs->key_rounds = val;
- break;
-#if 0 /* not yet implemented */
- case COMPRESS_DICT_SIZE | ISAKMP_ATTR_AF_TV:
- break;
- case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TV:
- break;
-
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- break;
- case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TLV:
- break;
-#endif
- default:
- loglog(RC_LOG_SERIOUS, "unsupported IPsec attribute %s"
- , enum_show(&ipsec_attr_names, a.isaat_af_type));
- return FALSE;
- }
- if (ipcomp_inappropriate)
- {
- loglog(RC_LOG_SERIOUS, "IPsec attribute %s inappropriate for IPCOMP"
- , enum_show(&ipsec_attr_names, a.isaat_af_type));
- return FALSE;
- }
- }
-
- /* Although an IPCOMP SA (IPCA) ought not to have a pfs_group,
- * if it does, demand that it be consistent.
- * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
- */
- if (!is_ipcomp || pfs_group != NULL)
- {
- if (st->st_pfs_group == &unset_group)
- st->st_pfs_group = pfs_group;
-
- if (st->st_pfs_group != pfs_group)
- {
- loglog(RC_LOG_SERIOUS, "GROUP_DESCRIPTION inconsistent with that of %s in IPsec SA"
- , selection? "the Proposal" : "a previous Transform");
- return FALSE;
- }
- }
-
- if (LHAS(seen_attrs, SA_LIFE_DURATION))
- {
- loglog(RC_LOG_SERIOUS, "SA_LIFE_TYPE IPsec attribute not followed by SA_LIFE_DURATION attribute in message");
- return FALSE;
- }
-
- if (!LHAS(seen_attrs, ENCAPSULATION_MODE))
- {
- if (is_ipcomp)
- {
- /* draft-shacham-ippcp-rfc2393bis-05.txt 4.1:
- * "If the Encapsulation Mode is unspecified,
- * the default value of Transport Mode is assumed."
- * This contradicts/overrides the DOI (quuoted below).
- */
- attrs->encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
- else
- {
- /* ??? Technically, RFC 2407 (IPSEC DOI) 4.5 specifies that
- * the default is "unspecified (host-dependent)".
- * This makes little sense, so we demand that it be specified.
- */
- loglog(RC_LOG_SERIOUS, "IPsec Transform must specify ENCAPSULATION_MODE");
- return FALSE;
- }
- }
-
- /* ??? should check for key_len and/or key_rounds if required */
-
- return TRUE;
-}
-
-static void
-echo_proposal(
- struct isakmp_proposal r_proposal, /* proposal to emit */
- struct isakmp_transform r_trans, /* winning transformation within it */
- u_int8_t np, /* Next Payload for proposal */
- pb_stream *r_sa_pbs, /* SA PBS into which to emit */
- struct ipsec_proto_info *pi, /* info about this protocol instance */
- struct_desc *trans_desc, /* descriptor for this transformation */
- pb_stream *trans_pbs, /* PBS for incoming transform */
- struct spd_route *sr, /* host details for the association */
- bool tunnel_mode) /* true for inner most tunnel SA */
-{
- pb_stream r_proposal_pbs;
- pb_stream r_trans_pbs;
-
- /* Proposal */
- r_proposal.isap_np = np;
- r_proposal.isap_notrans = 1;
- if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
- impossible();
-
- /* allocate and emit our CPI/SPI */
- if (r_proposal.isap_protoid == PROTO_IPCOMP)
- {
- /* CPI is stored in network low order end of an
- * ipsec_spi_t. So we start a couple of bytes in.
- * Note: we may fail to generate a satisfactory CPI,
- * but we'll ignore that.
- */
- pi->our_spi = get_my_cpi(sr, tunnel_mode);
- out_raw((u_char *) &pi->our_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE
- , &r_proposal_pbs, "CPI");
- }
- else
- {
- pi->our_spi = get_ipsec_spi(pi->attrs.spi
- , r_proposal.isap_protoid == PROTO_IPSEC_AH ?
- IPPROTO_AH : IPPROTO_ESP
- , sr
- , tunnel_mode);
- /* XXX should check for errors */
- out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE
- , &r_proposal_pbs, "SPI");
- }
-
- /* Transform */
- r_trans.isat_np = ISAKMP_NEXT_NONE;
- if (!out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs))
- impossible();
-
- /* Transform Attributes: pure echo */
- trans_pbs->cur = trans_pbs->start + sizeof(struct isakmp_transform);
- if (!out_raw(trans_pbs->cur, pbs_left(trans_pbs)
- , &r_trans_pbs, "attributes"))
- impossible();
-
- close_output_pbs(&r_trans_pbs);
- close_output_pbs(&r_proposal_pbs);
-}
-
-notification_t
-parse_ipsec_sa_body(
- pb_stream *sa_pbs, /* body of input SA Payload */
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit body of winning SA */
- bool selection, /* if this SA is a selection, only one transform may appear */
- struct state *st) /* current state object */
-{
- const struct connection *c = st->st_connection;
- u_int32_t ipsecdoisit;
- pb_stream next_proposal_pbs;
-
- struct isakmp_proposal next_proposal;
- ipsec_spi_t next_spi;
-
- bool next_full = TRUE;
-
- /* DOI */
- if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
- {
- loglog(RC_LOG_SERIOUS, "Unknown or unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
- /* XXX Could send notification back */
- return DOI_NOT_SUPPORTED;
- }
-
- /* Situation */
- if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
- return SITUATION_NOT_SUPPORTED;
-
- if (ipsecdoisit != SIT_IDENTITY_ONLY)
- {
- loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
- , bitnamesof(sit_bit_names, ipsecdoisit));
- /* XXX Could send notification back */
- return SITUATION_NOT_SUPPORTED;
- }
-
- /* The rules for IPsec SAs are scattered.
- * RFC 2408 "ISAKMP" section 4.2 gives some info.
- * There may be multiple proposals. Those with identical proposal
- * numbers must be considered as conjuncts. Those with different
- * numbers are disjuncts.
- * Each proposal may have several transforms, each considered
- * an alternative.
- * Each transform may have several attributes, all applying.
- *
- * To handle the way proposals are combined, we need to do a
- * look-ahead.
- */
-
- if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
- return BAD_PROPOSAL_SYNTAX;
-
- /* for each conjunction of proposals... */
- while (next_full)
- {
- int propno = next_proposal.isap_proposal;
- pb_stream ah_prop_pbs, esp_prop_pbs, ipcomp_prop_pbs;
- struct isakmp_proposal ah_proposal, esp_proposal, ipcomp_proposal;
- ipsec_spi_t ah_spi = 0;
- ipsec_spi_t esp_spi = 0;
- ipsec_spi_t ipcomp_cpi = 0;
- bool ah_seen = FALSE;
- bool esp_seen = FALSE;
- bool ipcomp_seen = FALSE;
- bool tunnel_mode = FALSE;
- int inner_proto = 0;
- u_int16_t well_known_cpi = 0;
-
- pb_stream ah_trans_pbs, esp_trans_pbs, ipcomp_trans_pbs;
- struct isakmp_transform ah_trans, esp_trans, ipcomp_trans;
- struct ipsec_trans_attrs ah_attrs, esp_attrs, ipcomp_attrs;
-
- /* for each proposal in the conjunction */
- do {
-
- if (next_proposal.isap_protoid == PROTO_IPCOMP)
- {
- /* IPCOMP CPI */
- if (next_proposal.isap_spisize == IPSEC_DOI_SPI_SIZE)
- {
- /* This code is to accommodate those peculiar
- * implementations that send a CPI in the bottom of an
- * SPI-sized field.
- * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1
- */
- u_int8_t filler[IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE];
-
- if (!in_raw(filler, sizeof(filler)
- , &next_proposal_pbs, "CPI filler")
- || !all_zero(filler, sizeof(filler)))
- return INVALID_SPI;
- }
- else if (next_proposal.isap_spisize != IPCOMP_CPI_SIZE)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper CPI size (%u)"
- , next_proposal.isap_spisize);
- return INVALID_SPI;
- }
-
- /* We store CPI in the low order of a network order
- * ipsec_spi_t. So we start a couple of bytes in.
- */
- zero(&next_spi);
- if (!in_raw((u_char *)&next_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE, &next_proposal_pbs, "CPI"))
- return INVALID_SPI;
-
- /* If sanity ruled, CPIs would have to be such that
- * the SAID (the triple (CPI, IPCOM, destination IP))
- * would be unique, just like for SPIs. But there is a
- * perversion where CPIs can be well-known and consequently
- * the triple is not unique. We hide this fact from
- * ourselves by fudging the top 16 bits to make
- * the property true internally!
- */
- switch (ntohl(next_spi))
- {
- case IPCOMP_DEFLATE:
- well_known_cpi = ntohl(next_spi);
- next_spi = uniquify_his_cpi(next_spi, st);
- if (next_spi == 0)
- {
- loglog(RC_LOG_SERIOUS
- , "IPsec Proposal contains well-known CPI that I cannot uniquify");
- return INVALID_SPI;
- }
- break;
- default:
- if (ntohl(next_spi) < IPCOMP_FIRST_NEGOTIATED
- || ntohl(next_spi) > IPCOMP_LAST_NEGOTIATED)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains CPI from non-negotiated range (0x%lx)"
- , (unsigned long) ntohl(next_spi));
- return INVALID_SPI;
- }
- break;
- }
- }
- else
- {
- /* AH or ESP SPI */
- if (next_proposal.isap_spisize != IPSEC_DOI_SPI_SIZE)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper SPI size (%u)"
- , next_proposal.isap_spisize);
- return INVALID_SPI;
- }
-
- if (!in_raw((u_char *)&next_spi, sizeof(next_spi), &next_proposal_pbs, "SPI"))
- return INVALID_SPI;
-
- /* SPI value 0 is invalid and values 1-255 are reserved to IANA.
- * RFC 2402 (ESP) 2.4, RFC 2406 (AH) 2.1
- * IPCOMP???
- */
- if (ntohl(next_spi) < IPSEC_DOI_SPI_MIN)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains invalid SPI (0x%lx)"
- , (unsigned long) ntohl(next_spi));
- return INVALID_SPI;
- }
- }
-
- if (next_proposal.isap_notrans == 0)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains no Transforms");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- switch (next_proposal.isap_protoid)
- {
- case PROTO_IPSEC_AH:
- if (ah_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous AH Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- ah_seen = TRUE;
- ah_prop_pbs = next_proposal_pbs;
- ah_proposal = next_proposal;
- ah_spi = next_spi;
- break;
-
- case PROTO_IPSEC_ESP:
- if (esp_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous ESP Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- esp_seen = TRUE;
- esp_prop_pbs = next_proposal_pbs;
- esp_proposal = next_proposal;
- esp_spi = next_spi;
- break;
-
- case PROTO_IPCOMP:
- if (ipcomp_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous IPCOMP Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- ipcomp_seen = TRUE;
- ipcomp_prop_pbs = next_proposal_pbs;
- ipcomp_proposal = next_proposal;
- ipcomp_cpi = next_spi;
- break;
-
- default:
- loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) in IPsec Proposal"
- , enum_show(&protocol_names, next_proposal.isap_protoid));
- return INVALID_PROTOCOL_ID;
- }
-
- /* refill next_proposal */
- if (next_proposal.isap_np == ISAKMP_NEXT_NONE)
- {
- next_full = FALSE;
- break;
- }
- else if (next_proposal.isap_np != ISAKMP_NEXT_P)
- {
- loglog(RC_LOG_SERIOUS, "unexpected in Proposal: %s"
- , enum_show(&payload_names, next_proposal.isap_np));
- return BAD_PROPOSAL_SYNTAX;
- }
-
- if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
- return BAD_PROPOSAL_SYNTAX;
- } while (next_proposal.isap_proposal == propno);
-
- /* Now that we have all conjuncts, we should try
- * the Cartesian product of eachs tranforms!
- * At the moment, we take short-cuts on account of
- * our rudimentary hard-wired policy.
- * For now, we find an acceptable AH (if any)
- * and then an acceptable ESP. The only interaction
- * is that the ESP acceptance can know whether there
- * was an acceptable AH and hence not require an AUTH.
- */
-
- if (ah_seen)
- {
- int previous_transnum = -1;
- int tn;
-
- for (tn = 0; tn != ah_proposal.isap_notrans; tn++)
- {
- int ok_transid = 0;
- bool ok_auth = FALSE;
-
- if (!parse_ipsec_transform(&ah_trans
- , &ah_attrs
- , &ah_prop_pbs
- , &ah_trans_pbs
- , &isakmp_ah_transform_desc
- , previous_transnum
- , selection
- , tn == ah_proposal.isap_notrans - 1
- , FALSE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = ah_trans.isat_transnum;
-
- /* we must understand ah_attrs.transid
- * COMBINED with ah_attrs.auth.
- * See RFC 2407 "IPsec DOI" section 4.4.3
- * The following combinations are legal,
- * but we don't implement all of them:
- * It seems as if each auth algorithm
- * only applies to one ah transid.
- * AH_MD5, AUTH_ALGORITHM_HMAC_MD5
- * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)
- * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1
- * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)
- */
- switch (ah_attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- loglog(RC_LOG_SERIOUS, "AUTH_ALGORITHM attribute missing in AH Transform");
- return BAD_PROPOSAL_SYNTAX;
-
- case AUTH_ALGORITHM_HMAC_MD5:
- ok_auth = TRUE;
- /* fall through */
- case AUTH_ALGORITHM_KPDK:
- ok_transid = AH_MD5;
- break;
-
- case AUTH_ALGORITHM_HMAC_SHA1:
- ok_auth = TRUE;
- ok_transid = AH_SHA;
- break;
-
- case AUTH_ALGORITHM_DES_MAC:
- ok_transid = AH_DES;
- break;
- }
- if (ah_attrs.transid != ok_transid)
- {
- loglog(RC_LOG_SERIOUS, "%s attribute inappropriate in %s Transform"
- , enum_name(&auth_alg_names, ah_attrs.auth)
- , enum_show(&ah_transformid_names, ah_attrs.transid));
- return BAD_PROPOSAL_SYNTAX;
- }
- if (!ok_auth)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("%s attribute unsupported"
- " in %s Transform from %s"
- , enum_name(&auth_alg_names, ah_attrs.auth)
- , enum_show(&ah_transformid_names, ah_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- break; /* we seem to be happy */
- }
- if (tn == ah_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
- ah_attrs.spi = ah_spi;
- inner_proto = IPPROTO_AH;
- if (ah_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
- }
-
- if (esp_seen)
- {
- int previous_transnum = -1;
- int tn;
-
- for (tn = 0; tn != esp_proposal.isap_notrans; tn++)
- {
- if (!parse_ipsec_transform(&esp_trans
- , &esp_attrs
- , &esp_prop_pbs
- , &esp_trans_pbs
- , &isakmp_esp_transform_desc
- , previous_transnum
- , selection
- , tn == esp_proposal.isap_notrans - 1
- , FALSE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = esp_trans.isat_transnum;
-
- /* set default key length for AES encryption */
- if (!esp_attrs.key_len && esp_attrs.transid == ESP_AES)
- {
- esp_attrs.key_len = 128 / BITS_PER_BYTE;
- }
-
- if (!kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len
- ,c->alg_info_esp))
- {
- switch (esp_attrs.transid)
- {
- case ESP_3DES:
- break;
-#ifdef SUPPORT_ESP_NULL /* should be about as secure as AH-only */
- case ESP_NULL:
- if (esp_attrs.auth == AUTH_ALGORITHM_NONE)
- {
- loglog(RC_LOG_SERIOUS, "ESP_NULL requires auth algorithm");
- return BAD_PROPOSAL_SYNTAX;
- }
- if (st->st_policy & POLICY_ENCRYPT)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP_NULL Transform Proposal from %s"
- " does not satisfy POLICY_ENCRYPT"
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- break;
-#endif
- default:
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported ESP Transform %s from %s"
- , enum_show(&esp_transformid_names, esp_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- }
-
- if (!kernel_alg_esp_auth_ok(esp_attrs.auth, c->alg_info_esp))
- {
- switch (esp_attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- if (!ah_seen)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP from %s must either have AUTH or be combined with AH"
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- break;
- case AUTH_ALGORITHM_HMAC_MD5:
- case AUTH_ALGORITHM_HMAC_SHA1:
- break;
- default:
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported ESP auth alg %s from %s"
- , enum_show(&auth_alg_names, esp_attrs.auth)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- }
-
- /* A last check for allowed transforms in alg_info_esp
- * (ALG_INFO_F_STRICT flag)
- */
- if (!kernel_alg_esp_ok_final(esp_attrs.transid, esp_attrs.key_len
- ,esp_attrs.auth, c->alg_info_esp))
- {
- continue;
- }
-
- if (ah_seen && ah_attrs.encapsulation != esp_attrs.encapsulation)
- {
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("AH and ESP transforms disagree about encapsulation; TUNNEL presumed"));
- }
-
- break; /* we seem to be happy */
- }
- if (tn == esp_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
-
- esp_attrs.spi = esp_spi;
- inner_proto = IPPROTO_ESP;
- if (esp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
- }
- else if (st->st_policy & POLICY_ENCRYPT)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("policy for \"%s\" requires encryption but ESP not in Proposal from %s"
- , c->name, ip_str(&c->spd.that.host_addr)));
- continue; /* we needed encryption, but didn't find ESP */
- }
- else if ((st->st_policy & POLICY_AUTHENTICATE) && !ah_seen)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("policy for \"%s\" requires authentication"
- " but none in Proposal from %s"
- , c->name, ip_str(&c->spd.that.host_addr)));
- continue; /* we need authentication, but we found neither ESP nor AH */
- }
-
- if (ipcomp_seen)
- {
- int previous_transnum = -1;
- int tn;
-
-#ifdef NEVER /* we think IPcomp is working now */
- /**** FUDGE TO PREVENT UNREQUESTED IPCOMP:
- **** NEEDED BECAUSE OUR IPCOMP IS EXPERIMENTAL (UNSTABLE).
- ****/
- if (!(st->st_policy & POLICY_COMPRESS))
- {
- plog("compression proposed by %s, but policy for \"%s\" forbids it"
- , ip_str(&c->spd.that.host_addr), c->name);
- continue; /* unwanted compression proposal */
- }
-#endif
- if (!can_do_IPcomp)
- {
- plog("compression proposed by %s, but KLIPS is not configured with IPCOMP"
- , ip_str(&c->spd.that.host_addr));
- continue;
- }
-
- if (well_known_cpi != 0 && !ah_seen && !esp_seen)
- {
- plog("illegal proposal: bare IPCOMP used with well-known CPI");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- for (tn = 0; tn != ipcomp_proposal.isap_notrans; tn++)
- {
- if (!parse_ipsec_transform(&ipcomp_trans
- , &ipcomp_attrs
- , &ipcomp_prop_pbs
- , &ipcomp_trans_pbs
- , &isakmp_ipcomp_transform_desc
- , previous_transnum
- , selection
- , tn == ipcomp_proposal.isap_notrans - 1
- , TRUE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = ipcomp_trans.isat_transnum;
-
- if (well_known_cpi != 0 && ipcomp_attrs.transid != well_known_cpi)
- {
- plog("illegal proposal: IPCOMP well-known CPI disagrees with transform");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- switch (ipcomp_attrs.transid)
- {
- case IPCOMP_DEFLATE: /* all we can handle! */
- break;
-
- default:
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported IPCOMP Transform %s from %s"
- , enum_show(&ipcomp_transformid_names, ipcomp_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
-
- if (ah_seen && ah_attrs.encapsulation != ipcomp_attrs.encapsulation)
- {
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("AH and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
- } else if (esp_seen && esp_attrs.encapsulation != ipcomp_attrs.encapsulation)
- {
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
- }
-
- break; /* we seem to be happy */
- }
- if (tn == ipcomp_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
- ipcomp_attrs.spi = ipcomp_cpi;
- inner_proto = IPPROTO_COMP;
- if (ipcomp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
- }
-
- /* Eureka: we liked what we saw -- accept it. */
-
- if (r_sa_pbs != NULL)
- {
- /* emit what we've accepted */
-
- /* Situation */
- if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
- impossible();
-
- /* AH proposal */
- if (ah_seen)
- echo_proposal(ah_proposal
- , ah_trans
- , esp_seen || ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_ah
- , &isakmp_ah_transform_desc
- , &ah_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_AH);
-
- /* ESP proposal */
- if (esp_seen)
- echo_proposal(esp_proposal
- , esp_trans
- , ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_esp
- , &isakmp_esp_transform_desc
- , &esp_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_ESP);
-
- /* IPCOMP proposal */
- if (ipcomp_seen)
- echo_proposal(ipcomp_proposal
- , ipcomp_trans
- , ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_ipcomp
- , &isakmp_ipcomp_transform_desc
- , &ipcomp_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_COMP);
-
- close_output_pbs(r_sa_pbs);
- }
-
- /* save decoded version of winning SA in state */
-
- st->st_ah.present = ah_seen;
- if (ah_seen)
- st->st_ah.attrs = ah_attrs;
-
- st->st_esp.present = esp_seen;
- if (esp_seen)
- st->st_esp.attrs = esp_attrs;
-
- st->st_ipcomp.present = ipcomp_seen;
- if (ipcomp_seen)
- st->st_ipcomp.attrs = ipcomp_attrs;
-
- return NOTHING_WRONG;
- }
-
- loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");
- return NO_PROPOSAL_CHOSEN;
-}
diff --git a/programs/pluto/spdb.h b/programs/pluto/spdb.h
deleted file mode 100644
index 6cb92f036..000000000
--- a/programs/pluto/spdb.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Security Policy Data Base (such as it is)
- * Copyright (C) 1998, 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: spdb.h,v 1.5 2007/01/10 00:36:19 as Exp $
- */
-
-#ifndef _SPDB_H
-#define _SPDB_H
-
-#include "packet.h"
-
-/* database of SA properties */
-
-/* Attribute type and value pair.
- * Note: only "basic" values are represented so far.
- */
-struct db_attr {
- u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
- u_int16_t val;
-};
-
-/* transform */
-struct db_trans {
- u_int8_t transid; /* Transform-Id */
- struct db_attr *attrs; /* array */
- int attr_cnt; /* number of elements */
-};
-
-/* proposal */
-struct db_prop {
- u_int8_t protoid; /* Protocol-Id */
- struct db_trans *trans; /* array (disjunction) */
- int trans_cnt; /* number of elements */
- /* SPI size and value isn't part of DB */
-};
-
-/* conjunction of proposals */
-struct db_prop_conj {
- struct db_prop *props; /* array */
- int prop_cnt; /* number of elements */
-};
-
-/* security association */
-struct db_sa {
- struct db_prop_conj *prop_conjs; /* array */
- int prop_conj_cnt; /* number of elements */
- /* Hardwired for now;
- * DOI: ISAKMP_DOI_IPSEC
- * Situation: SIT_IDENTITY_ONLY
- */
-};
-
-/* The oakley sadb */
-extern struct db_sa oakley_sadb;
-
-/* The ipsec sadb is subscripted by a bitset with members
- * from POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS
- */
-extern struct db_sa ipsec_sadb[1 << 3];
-
-/* forward declaration */
-struct state;
-
-extern bool out_sa(
- pb_stream *outs,
- struct db_sa *sadb,
- struct state *st,
- bool oakley_mode,
- u_int8_t np);
-
-extern notification_t preparse_isakmp_sa_body(
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *sa_pbs, /* body of input SA Payload */
- u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
- pb_stream *proposal_pbs, /* body of proposal Payload */
- struct isakmp_proposal *proposal);
-
-extern notification_t parse_isakmp_policy(
- pb_stream *proposal_pbs, /* body of proposal Payload */
- u_int notrans, /* number of transforms */
- lset_t *policy); /* RSA, PSK or XAUTH policy */
-
-extern notification_t parse_isakmp_sa_body(
- u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
- pb_stream *proposal_pbs, /* body of proposal Payload */
- struct isakmp_proposal *proposal,
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- struct state *st, /* current state object */
- bool initiator); /* is caller initiator? */
-
-extern notification_t parse_ipsec_sa_body(
- pb_stream *sa_pbs, /* body of input SA Payload */
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- bool selection, /* if this SA is a selection, only one tranform can appear */
- struct state *st); /* current state object */
-
-extern void backup_pbs(pb_stream *pbs);
-extern void restore_pbs(pb_stream *pbs);
-
-#endif /* _SPDB_H */
-
diff --git a/programs/pluto/state.c b/programs/pluto/state.c
deleted file mode 100644
index 8181c34b4..000000000
--- a/programs/pluto/state.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-/* routines for state objects
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: state.c,v 1.15 2006/10/20 15:02:23 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "kernel.h"
-#include "log.h"
-#include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */
-#include "keys.h" /* for free_public_key */
-#include "rnd.h"
-#include "timer.h"
-#include "whack.h"
-#include "demux.h" /* needs packet.h */
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-
-/*
- * Global variables: had to go somewhere, might as well be this file.
- */
-
-u_int16_t pluto_port = IKE_UDP_PORT; /* Pluto's port */
-
-/*
- * This file has the functions that handle the
- * state hash table and the Message ID list.
- */
-
-/* Message-IDs
- *
- * A Message ID is contained in each IKE message header.
- * For Phase 1 exchanges (Main and Aggressive), it will be zero.
- * For other exchanges, which must be under the protection of an
- * ISAKMP SA, the Message ID must be unique within that ISAKMP SA.
- * Effectively, this labels the message as belonging to a particular
- * exchange.
- * BTW, we feel this uniqueness allows rekeying to be somewhat simpler
- * than specified by draft-jenkins-ipsec-rekeying-06.txt.
- *
- * A MessageID is a 32 bit unsigned number. We represent the value
- * internally in network order -- they are just blobs to us.
- * They are unsigned numbers to make hashing and comparing easy.
- *
- * The following mechanism is used to allocate message IDs. This
- * requires that we keep track of which numbers have already been used
- * so that we don't allocate one in use.
- */
-
-struct msgid_list
-{
- msgid_t msgid; /* network order */
- struct msgid_list *next;
-};
-
-bool
-reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
-{
- struct msgid_list *p;
-
- passert(msgid != MAINMODE_MSGID);
- passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
-
- for (p = isakmp_sa->st_used_msgids; p != NULL; p = p->next)
- if (p->msgid == msgid)
- return FALSE;
-
- p = alloc_thing(struct msgid_list, "msgid");
- p->msgid = msgid;
- p->next = isakmp_sa->st_used_msgids;
- isakmp_sa->st_used_msgids = p;
- return TRUE;
-}
-
-msgid_t
-generate_msgid(struct state *isakmp_sa)
-{
- int timeout = 100; /* only try so hard for unique msgid */
- msgid_t msgid;
-
- passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
-
- for (;;)
- {
- get_rnd_bytes((void *) &msgid, sizeof(msgid));
- if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
- break;
-
- if (--timeout == 0)
- {
- plog("gave up looking for unique msgid; using 0x%08lx"
- , (unsigned long) msgid);
- break;
- }
- }
- return msgid;
-}
-
-
-/* state table functions */
-
-#define STATE_TABLE_SIZE 32
-
-static struct state *statetable[STATE_TABLE_SIZE];
-
-static struct state **
-state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
-{
- u_int i = 0, j;
- const unsigned char *byte_ptr;
- size_t length = addrbytesptr(peer, &byte_ptr);
-
- DBG(DBG_RAW | DBG_CONTROL,
- DBG_dump("ICOOKIE:", icookie, COOKIE_SIZE);
- DBG_dump("RCOOKIE:", rcookie, COOKIE_SIZE);
- DBG_dump("peer:", byte_ptr, length));
-
- /* XXX the following hash is pretty pathetic */
-
- for (j = 0; j < COOKIE_SIZE; j++)
- i = i * 407 + icookie[j] + rcookie[j];
-
- for (j = 0; j < length; j++)
- i = i * 613 + byte_ptr[j];
-
- i = i % STATE_TABLE_SIZE;
-
- DBG(DBG_CONTROL, DBG_log("state hash entry %d", i));
-
- return &statetable[i];
-}
-
-/* Get a state object.
- * Caller must schedule an event for this object so that it doesn't leak.
- * Caller must insert_state().
- */
-struct state *
-new_state(void)
-{
- static const struct state blank_state; /* initialized all to zero & NULL */
- static so_serial_t next_so = SOS_FIRST;
- struct state *st;
-
- st = clone_thing(blank_state, "struct state in new_state()");
- st->st_serialno = next_so++;
- passert(next_so > SOS_FIRST); /* overflow can't happen! */
- st->st_whack_sock = NULL_FD;
- DBG(DBG_CONTROL, DBG_log("creating state object #%lu at %p",
- st->st_serialno, (void *) st));
- return st;
-}
-
-/*
- * Initialize the state table (and mask*).
- */
-void
-init_states(void)
-{
- int i;
-
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- statetable[i] = (struct state *) NULL;
-}
-
-/* Find the state object with this serial number.
- * This allows state object references that don't turn into dangerous
- * dangling pointers: reference a state by its serial number.
- * Returns NULL if there is no such state.
- * If this turns out to be a significant CPU hog, it could be
- * improved to use a hash table rather than sequential seartch.
- */
-struct state *
-state_with_serialno(so_serial_t sn)
-{
- if (sn >= SOS_FIRST)
- {
- struct state *st;
- int i;
-
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_serialno == sn)
- return st;
- }
- return NULL;
-}
-
-/* Insert a state object in the hash table. The object is inserted
- * at the begining of list.
- * Needs cookies, connection, and msgid.
- */
-void
-insert_state(struct state *st)
-{
- struct state **p = state_hash(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr);
-
- passert(st->st_hashchain_prev == NULL && st->st_hashchain_next == NULL);
-
- if (*p != NULL)
- {
- passert((*p)->st_hashchain_prev == NULL);
- (*p)->st_hashchain_prev = st;
- }
- st->st_hashchain_next = *p;
- *p = st;
-
- /* Ensure that somebody is in charge of killing this state:
- * if no event is scheduled for it, schedule one to discard the state.
- * If nothing goes wrong, this event will be replaced by
- * a more appropriate one.
- */
- if (st->st_event == NULL)
- event_schedule(EVENT_SO_DISCARD, 0, st);
-}
-
-/* unlink a state object from the hash table, but don't free it
- */
-void
-unhash_state(struct state *st)
-{
- /* unlink from forward chain */
- struct state **p = st->st_hashchain_prev == NULL
- ? state_hash(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr)
- : &st->st_hashchain_prev->st_hashchain_next;
-
- /* unlink from forward chain */
- passert(*p == st);
- *p = st->st_hashchain_next;
-
- /* unlink from backward chain */
- if (st->st_hashchain_next != NULL)
- {
- passert(st->st_hashchain_next->st_hashchain_prev == st);
- st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
- }
-
- st->st_hashchain_next = st->st_hashchain_prev = NULL;
-}
-
-/* Free the Whack socket file descriptor.
- * This has the side effect of telling Whack that we're done.
- */
-void
-release_whack(struct state *st)
-{
- close_any(st->st_whack_sock);
-}
-
-/* delete a state object */
-void
-delete_state(struct state *st)
-{
- struct connection *const c = st->st_connection;
- struct state *old_cur_state = cur_state == st? NULL : cur_state;
-
- set_cur_state(st);
-
- /* If DPD is enabled on this state object, clear any pending events */
- if(st->st_dpd_event != NULL)
- delete_dpd_event(st);
-
- /* if there is a suspended state transition, disconnect us */
- if (st->st_suspended_md != NULL)
- {
- passert(st->st_suspended_md->st == st);
- st->st_suspended_md->st = NULL;
- }
-
- /* tell the other side of any IPSEC SAs that are going down */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- || IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- send_delete(st);
-
- delete_event(st); /* delete any pending timer event */
-
- /* Ditch anything pending on ISAKMP SA being established.
- * Note: this must be done before the unhash_state to prevent
- * flush_pending_by_state inadvertently and prematurely
- * deleting our connection.
- */
- flush_pending_by_state(st);
-
- /* effectively, this deletes any ISAKMP SA that this state represents */
- unhash_state(st);
-
- /* tell kernel to delete any IPSEC SA
- * ??? we ought to tell peer to delete IPSEC SAs
- */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- delete_ipsec_sa(st, FALSE);
- else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
- delete_ipsec_sa(st, TRUE);
-
- if (c->newest_ipsec_sa == st->st_serialno)
- c->newest_ipsec_sa = SOS_NOBODY;
-
- if (c->newest_isakmp_sa == st->st_serialno)
- c->newest_isakmp_sa = SOS_NOBODY;
-
- st->st_connection = NULL; /* we might be about to free it */
- cur_state = old_cur_state; /* without st_connection, st isn't complete */
- connection_discard(c);
-
- release_whack(st);
-
- /* from here on we are just freeing RAM */
-
- {
- struct msgid_list *p = st->st_used_msgids;
-
- while (p != NULL)
- {
- struct msgid_list *q = p;
- p = p->next;
- pfree(q);
- }
- }
-
- unreference_key(&st->st_peer_pubkey);
-
- if (st->st_sec_in_use)
- mpz_clear(&(st->st_sec));
-
- pfreeany(st->st_tpacket.ptr);
- pfreeany(st->st_rpacket.ptr);
- pfreeany(st->st_p1isa.ptr);
- pfreeany(st->st_gi.ptr);
- pfreeany(st->st_gr.ptr);
- pfreeany(st->st_shared.ptr);
- pfreeany(st->st_ni.ptr);
- pfreeany(st->st_nr.ptr);
- pfreeany(st->st_skeyid.ptr);
- pfreeany(st->st_skeyid_d.ptr);
- pfreeany(st->st_skeyid_a.ptr);
- pfreeany(st->st_skeyid_e.ptr);
- pfreeany(st->st_enc_key.ptr);
- pfreeany(st->st_ah.our_keymat);
- pfreeany(st->st_ah.peer_keymat);
- pfreeany(st->st_esp.our_keymat);
- pfreeany(st->st_esp.peer_keymat);
-
- pfree(st);
-}
-
-/*
- * Is a connection in use by some state?
- */
-bool
-states_use_connection(struct connection *c)
-{
- /* are there any states still using it? */
- struct state *st = NULL;
- int i;
-
- for (i = 0; st == NULL && i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_connection == c)
- return TRUE;
-
- return FALSE;
-}
-
-/*
- * delete all states that were created for a given connection.
- * if relations == TRUE, then also delete states that share
- * the same phase 1 SA.
- */
-void
-delete_states_by_connection(struct connection *c, bool relations)
-{
- int pass;
- /* this kludge avoids an n^2 algorithm */
- enum connection_kind ck = c->kind;
- struct spd_route *sr;
-
- /* save this connection's isakmp SA, since it will get set to later SOS_NOBODY */
- so_serial_t parent_sa = c->newest_isakmp_sa;
-
- if (ck == CK_INSTANCE)
- c->kind = CK_GOING_AWAY;
-
- /* We take two passes so that we delete any ISAKMP SAs last.
- * This allows Delete Notifications to be sent.
- * ?? We could probably double the performance by caching any
- * ISAKMP SA states found in the first pass, avoiding a second.
- */
- for (pass = 0; pass != 2; pass++)
- {
- int i;
-
- /* For each hash chain... */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- /* For each state in the hash chain... */
- for (st = statetable[i]; st != NULL; )
- {
- struct state *this = st;
-
- st = st->st_hashchain_next; /* before this is deleted */
-
-
- if ((this->st_connection == c
- || (relations && parent_sa != SOS_NOBODY
- && this->st_clonedfrom == parent_sa))
- && (pass == 1 || !IS_ISAKMP_SA_ESTABLISHED(this->st_state)))
- {
- struct state *old_cur_state
- = cur_state == this? NULL : cur_state;
-#ifdef DEBUG
- lset_t old_cur_debugging = cur_debugging;
-#endif
-
- set_cur_state(this);
- plog("deleting state (%s)"
- , enum_show(&state_names, this->st_state));
- delete_state(this);
- cur_state = old_cur_state;
-#ifdef DEBUG
- cur_debugging = old_cur_debugging;
-#endif
- }
- }
- }
- }
-
- sr = &c->spd;
- while (sr != NULL)
- {
- passert(sr->eroute_owner == SOS_NOBODY);
- passert(sr->routing != RT_ROUTED_TUNNEL);
- sr = sr->next;
- }
-
- if (ck == CK_INSTANCE)
- {
- c->kind = ck;
- delete_connection(c, relations);
- }
-}
-
-/* Walk through the state table, and delete each state whose phase 1 (IKE)
- * peer is among those given.
- */
-void
-delete_states_by_peer(ip_address *peer)
-{
- char peerstr[ADDRTOT_BUF];
- int i;
-
- addrtot(peer, 0, peerstr, sizeof(peerstr));
-
- /* For each hash chain... */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- /* For each state in the hash chain... */
- for (st = statetable[i]; st != NULL; )
- {
- struct state *this = st;
- struct spd_route *sr;
- struct connection *c = this->st_connection;
-
- st = st->st_hashchain_next; /* before this is deleted */
-
- /* ??? Is it not the case that the peer is the same for all spds? */
- for (sr = &c->spd; sr != NULL; sr = sr->next)
- {
- if (sameaddr(&sr->that.host_addr, peer))
- {
- plog("peer %s for connection %s deleting - claimed to have crashed"
- , peerstr
- , c->name);
- delete_states_by_connection(c, TRUE);
- break; /* can only delete it once */
- }
- }
- }
- }
-}
-
-/* Duplicate a Phase 1 state object, to create a Phase 2 object.
- * Caller must schedule an event for this object so that it doesn't leak.
- * Caller must insert_state().
- */
-struct state *
-duplicate_state(struct state *st)
-{
- struct state *nst;
-
- DBG(DBG_CONTROL, DBG_log("duplicating state object #%lu",
- st->st_serialno));
-
- /* record use of the Phase 1 state */
- st->st_outbound_count++;
- st->st_outbound_time = now();
-
- nst = new_state();
-
- memcpy(nst->st_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(nst->st_rcookie, st->st_rcookie, COOKIE_SIZE);
-
- nst->st_connection = st->st_connection;
- nst->st_doi = st->st_doi;
- nst->st_situation = st->st_situation;
- nst->st_clonedfrom = st->st_serialno;
- nst->st_oakley = st->st_oakley;
- nst->st_modecfg = st->st_modecfg;
-
-# define clone_chunk(ch, name) \
- clonetochunk(nst->ch, st->ch.ptr, st->ch.len, name)
-
- clone_chunk(st_skeyid_d, "st_skeyid_d in duplicate_state");
- clone_chunk(st_skeyid_a, "st_skeyid_a in duplicate_state");
- clone_chunk(st_skeyid_e, "st_skeyid_e in duplicate_state");
- clone_chunk(st_enc_key, "st_enc_key in duplicate_state");
-
-# undef clone_chunk
-
- return nst;
-}
-
-#if 1
-void for_each_state(void *(f)(struct state *, void *data), void *data)
-{
- struct state *st, *ocs = cur_state;
- int i;
- for (i=0; i<STATE_TABLE_SIZE; i++) {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next) {
- set_cur_state(st);
- f(st, data);
- }
- }
- cur_state = ocs;
-}
-#endif
-
-/*
- * Find a state object.
- */
-struct state *
-find_state(const u_char *icookie
-, const u_char *rcookie
-, const ip_address *peer
-, msgid_t /*network order*/ msgid)
-{
- struct state *st = *state_hash(icookie, rcookie, peer);
-
- while (st != (struct state *) NULL)
- if (sameaddr(peer, &st->st_connection->spd.that.host_addr)
- && memcmp(icookie, st->st_icookie, COOKIE_SIZE) == 0
- && memcmp(rcookie, st->st_rcookie, COOKIE_SIZE) == 0
- && msgid == st->st_msgid)
- break;
- else
- st = st->st_hashchain_next;
-
- DBG(DBG_CONTROL,
- if (st == NULL)
- DBG_log("state object not found");
- else
- DBG_log("state object #%lu found, in %s"
- , st->st_serialno
- , enum_show(&state_names, st->st_state)));
-
- return st;
-}
-
-/* Find the state that sent a packet
- * ??? this could be expensive -- it should be rate-limited to avoid DoS
- */
-struct state *
-find_sender(size_t packet_len, u_char *packet)
-{
- int i;
- struct state *st;
-
- if (packet_len >= sizeof(struct isakmp_hdr))
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_tpacket.ptr != NULL
- && st->st_tpacket.len == packet_len
- && memcmp(st->st_tpacket.ptr, packet, packet_len) == 0)
- return st;
-
- return NULL;
-}
-
-struct state *
-find_phase2_state_to_delete(const struct state *p1st
-, u_int8_t protoid
-, ipsec_spi_t spi
-, bool *bogus)
-{
- struct state *st;
- int i;
-
- *bogus = FALSE;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- {
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- && p1st->st_connection->host_pair == st->st_connection->host_pair
- && same_peer_ids(p1st->st_connection, st->st_connection, NULL))
- {
- struct ipsec_proto_info *pr = protoid == PROTO_IPSEC_AH
- ? &st->st_ah : &st->st_esp;
-
- if (pr->present)
- {
- if (pr->attrs.spi == spi)
- return st;
- if (pr->our_spi == spi)
- *bogus = TRUE;
- }
- }
- }
- }
- return NULL;
-}
-
-/* Find newest Phase 1 negotiation state object for suitable for connection c
- */
-struct state *
-find_phase1_state(const struct connection *c, lset_t ok_states)
-{
- struct state
- *st,
- *best = NULL;
- int i;
-
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (LHAS(ok_states, st->st_state)
- && c->host_pair == st->st_connection->host_pair
- && same_peer_ids(c, st->st_connection, NULL)
- && (best == NULL || best->st_serialno < st->st_serialno))
- best = st;
-
- return best;
-}
-
-void
-state_eroute_usage(ip_subnet *ours, ip_subnet *his
-, unsigned long count, time_t nw)
-{
- struct state *st;
- int i;
-
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- {
- struct connection *c = st->st_connection;
-
- /* XXX spd-enum */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- && c->spd.eroute_owner == st->st_serialno
- && c->spd.routing == RT_ROUTED_TUNNEL
- && samesubnet(&c->spd.this.client, ours)
- && samesubnet(&c->spd.that.client, his))
- {
- if (st->st_outbound_count != count)
- {
- st->st_outbound_count = count;
- st->st_outbound_time = nw;
- }
- return;
- }
- }
- }
- DBG(DBG_CONTROL,
- {
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
-
- subnettot(ours, 0, ourst, sizeof(ourst));
- subnettot(his, 0, hist, sizeof(hist));
- DBG_log("unknown tunnel eroute %s -> %s found in scan"
- , ourst, hist);
- });
-}
-
-void fmt_state(bool all, struct state *st, time_t n
-, char *state_buf, size_t state_buf_len
-, char *state_buf2, size_t state_buf2_len)
-{
- /* what the heck is interesting about a state? */
- const struct connection *c = st->st_connection;
-
- long delta = st->st_event->ev_time >= n
- ? (long)(st->st_event->ev_time - n)
- : -(long)(n - st->st_event->ev_time);
-
- char inst[CONN_INST_BUF];
- const char *np1 = c->newest_isakmp_sa == st->st_serialno
- ? "; newest ISAKMP" : "";
- const char *np2 = c->newest_ipsec_sa == st->st_serialno
- ? "; newest IPSEC" : "";
- /* XXX spd-enum */
- const char *eo = c->spd.eroute_owner == st->st_serialno
- ? "; eroute owner" : "";
- const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
- ? "; DPD active" : "";
-
- passert(st->st_event != 0);
-
- fmt_conn_instance(c, inst);
-
- snprintf(state_buf, state_buf_len
- , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s%s"
- , st->st_serialno
- , c->name, inst
- , enum_name(&state_names, st->st_state)
- , state_story[st->st_state - STATE_MAIN_R0]
- , enum_name(&timer_event_names, st->st_event->ev_type)
- , delta
- , np1, np2, eo, dpd);
-
- /* print out SPIs if SAs are established */
- if (state_buf2_len != 0)
- state_buf2[0] = '\0'; /* default to empty */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
-
- bool tunnel;
- char buf[SATOT_BUF*6 + 2*20 + 1];
- const char *p_end = buf + sizeof(buf);
- char *p = buf;
-
-# define add_said(adst, aspi, aproto) { \
- ip_said s; \
- \
- initsaid(adst, aspi, aproto, &s); \
- if (p < p_end - 1) \
- { \
- *p++ = ' '; \
- p += satot(&s, 0, p, p_end - p) - 1; \
- } \
- }
-
-# define add_sa_info(st, inbound) { \
- u_int bytes; \
- time_t use_time; \
- \
- if (get_sa_info(st, inbound, &bytes, &use_time)) \
- { \
- p += snprintf(p, p_end - p, " (%'u bytes", bytes); \
- if (bytes > 0 && use_time != UNDEFINED_TIME) \
- p += snprintf(p, p_end - p, ", %ds ago", (int)(now - use_time)); \
- p += snprintf(p, p_end - p, ")"); \
- } \
- }
-
- *p = '\0';
- if (st->st_ah.present)
- {
- add_said(&c->spd.that.host_addr, st->st_ah.attrs.spi, SA_AH);
- add_said(&c->spd.this.host_addr, st->st_ah.our_spi, SA_AH);
- }
- if (st->st_esp.present)
- {
- time_t now = time(NULL);
-
- add_said(&c->spd.that.host_addr, st->st_esp.attrs.spi, SA_ESP);
- add_sa_info(st, FALSE);
- add_said(&c->spd.this.host_addr, st->st_esp.our_spi, SA_ESP);
- add_sa_info(st, TRUE);
- }
- if (st->st_ipcomp.present)
- {
- add_said(&c->spd.that.host_addr, st->st_ipcomp.attrs.spi, SA_COMP);
- add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, SA_COMP);
- }
-#ifdef KLIPS
- tunnel = st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
- p += snprintf(p, p_end - p, "; %s", tunnel? "tunnel":"transport");
-#endif
-
- snprintf(state_buf2, state_buf2_len
- , "#%lu: \"%s\"%s%s"
- , st->st_serialno
- , c->name, inst
- , buf);
-
-# undef add_said
-# undef add_sa_info
- }
-}
-
-/*
- * sorting logic is:
- *
- * name
- * type
- * instance#
- * isakmp_sa (XXX probably wrong)
- *
- */
-static int
-state_compare(const void *a, const void *b)
-{
- const struct state *sap = *(const struct state *const *)a;
- struct connection *ca = sap->st_connection;
- const struct state *sbp = *(const struct state *const *)b;
- struct connection *cb = sbp->st_connection;
-
- /* DBG_log("comparing %s to %s", ca->name, cb->name); */
-
- return connection_compare(ca, cb);
-}
-
-void
-show_states_status(bool all, const char *name)
-{
- time_t n = now();
- int i;
- char state_buf[LOG_WIDTH];
- char state_buf2[LOG_WIDTH];
- int count;
- struct state **array;
-
- /* make count of states */
- count = 0;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- {
- if (name == NULL || streq(name, st->st_connection->name))
- count++;
- }
- }
-
- /* build the array */
- array = alloc_bytes(sizeof(struct state *)*count, "state array");
- count = 0;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- {
- if (name == NULL || streq(name, st->st_connection->name))
- array[count++]=st;
- }
- }
-
- /* sort it! */
- qsort(array, count, sizeof(struct state *), state_compare);
-
- /* now print sorted results */
- for (i = 0; i < count; i++)
- {
- struct state *st;
-
- st = array[i];
-
- fmt_state(all, st, n
- , state_buf, sizeof(state_buf)
- , state_buf2, sizeof(state_buf2));
- whack_log(RC_COMMENT, state_buf);
- if (state_buf2[0] != '\0')
- whack_log(RC_COMMENT, state_buf2);
-
- /* show any associated pending Phase 2s */
- if (IS_PHASE1(st->st_state))
- show_pending_phase2(st->st_connection->host_pair, st);
- }
- if (count > 0)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
-
- /* free the array */
- pfree(array);
-}
-
-/* Given that we've used up a range of unused CPI's,
- * search for a new range of currently unused ones.
- * Note: this is very expensive when not trivial!
- * If we can't find one easily, choose 0 (a bad SPI,
- * no matter what order) indicating failure.
- */
-void
-find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
-{
- int tries = 0;
- cpi_t base = *latest_cpi;
- cpi_t closest;
- int i;
-
-startover:
- closest = ~0; /* not close at all */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- {
- if (st->st_ipcomp.present)
- {
- cpi_t c = ntohl(st->st_ipcomp.our_spi) - base;
-
- if (c < closest)
- {
- if (c == 0)
- {
- /* oops: next spot is occupied; start over */
- if (++tries == 20)
- {
- /* FAILURE */
- *latest_cpi = *first_busy_cpi = 0;
- return;
- }
- base++;
- if (base > IPCOMP_LAST_NEGOTIATED)
- base = IPCOMP_FIRST_NEGOTIATED;
- goto startover; /* really a tail call */
- }
- closest = c;
- }
- }
- }
- }
- *latest_cpi = base; /* base is first in next free range */
- *first_busy_cpi = closest + base; /* and this is the roof */
-}
-
-/* Muck with high-order 16 bits of this SPI in order to make
- * the corresponding SAID unique.
- * Its low-order 16 bits hold a well-known IPCOMP CPI.
- * Oh, and remember that SPIs are stored in network order.
- * Kludge!!! So I name it with the non-English word "uniquify".
- * If we can't find one easily, return 0 (a bad SPI,
- * no matter what order) indicating failure.
- */
-ipsec_spi_t
-uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
-{
- int tries = 0;
- int i;
-
-startover:
-
- /* network order makes first two bytes our target */
- get_rnd_bytes((u_char *)&cpi, 2);
-
- /* Make sure that the result is unique.
- * Hard work. If there is no unique value, we'll loop forever!
- */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *s;
-
- for (s = statetable[i]; s != NULL; s = s->st_hashchain_next)
- {
- if (s->st_ipcomp.present
- && sameaddr(&s->st_connection->spd.that.host_addr
- , &st->st_connection->spd.that.host_addr)
- && cpi == s->st_ipcomp.attrs.spi)
- {
- if (++tries == 20)
- return 0; /* FAILURE */
- goto startover;
- }
- }
- }
- return cpi;
-}
-
-/*
- * Local Variables:
- * c-basic-offset:4
- * End:
- */
diff --git a/programs/pluto/state.h b/programs/pluto/state.h
deleted file mode 100644
index d885d145d..000000000
--- a/programs/pluto/state.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/* state and event objects
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: state.h,v 1.13 2007/01/10 00:36:19 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <time.h>
-#include <gmp.h> /* GNU MP library */
-
-#include "connections.h"
-
-/* Message ID mechanism.
- *
- * A Message ID is contained in each IKE message header.
- * For Phase 1 exchanges (Main and Aggressive), it will be zero.
- * For other exchanges, which must be under the protection of an
- * ISAKMP SA, the Message ID must be unique within that ISAKMP SA.
- * Effectively, this labels the message as belonging to a particular
- * exchange.
- *
- * RFC2408 "ISAKMP" 3.1 "ISAKMP Header Format" (near end) states that
- * the Message ID must be unique. We interpret this to be "unique within
- * one ISAKMP SA".
- *
- * BTW, we feel this uniqueness allows rekeying to be somewhat simpler
- * than specified by draft-jenkins-ipsec-rekeying-06.txt.
- */
-
-typedef u_int32_t msgid_t; /* Network order! */
-#define MAINMODE_MSGID ((msgid_t) 0)
-
-struct state; /* forward declaration of tag */
-extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid);
-extern msgid_t generate_msgid(struct state *isakmp_sa);
-
-
-/* Oakley (Phase 1 / Main Mode) transform and attributes
- * This is a flattened/decoded version of what is represented
- * in the Transaction Payload.
- * Names are chosen to match corresponding names in state.
- */
-struct oakley_trans_attrs {
- u_int16_t encrypt; /* Encryption algorithm */
- u_int16_t enckeylen; /* encryption key len (bits) */
- const struct encrypt_desc *encrypter; /* package of encryption routines */
- u_int16_t hash; /* Hash algorithm */
- const struct hash_desc *hasher; /* package of hashing routines */
- u_int16_t auth; /* Authentication method */
- const struct oakley_group_desc *group; /* Oakley group */
- time_t life_seconds; /* When this SA expires (seconds) */
- u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
-#if 0 /* not yet */
- u_int16_t prf; /* Pseudo Random Function */
-#endif
-};
-
-/* IPsec (Phase 2 / Quick Mode) transform and attributes
- * This is a flattened/decoded version of what is represented
- * by a Transaction Payload. There may be one for AH, one
- * for ESP, and a funny one for IPCOMP.
- */
-struct ipsec_trans_attrs {
- u_int8_t transid; /* transform id */
- ipsec_spi_t spi; /* his SPI */
- time_t life_seconds; /* When this SA expires */
- u_int32_t life_kilobytes; /* When this SA expires */
- u_int16_t encapsulation;
- u_int16_t auth;
- u_int16_t key_len;
- u_int16_t key_rounds;
-#if 0 /* not implemented yet */
- u_int16_t cmprs_dict_sz;
- u_int32_t cmprs_alg;
-#endif
-};
-
-/* IPsec per protocol state information */
-struct ipsec_proto_info {
- bool present; /* was this transform specified? */
- struct ipsec_trans_attrs attrs;
- ipsec_spi_t our_spi;
- u_int16_t keymat_len; /* same for both */
- u_char *our_keymat;
- u_char *peer_keymat;
-};
-
-/* state object: record the state of a (possibly nascent) SA
- *
- * Invariants (violated only during short transitions):
- * - each state object will be in statetable exactly once.
- * - each state object will always have a pending event.
- * This prevents leaks.
- */
-struct state
-{
- so_serial_t st_serialno; /* serial number (for seniority) */
- so_serial_t st_clonedfrom; /* serial number of parent */
-
- struct connection *st_connection; /* connection for this SA */
-
- int st_whack_sock; /* fd for our Whack TCP socket.
- * Single copy: close when freeing struct.
- */
-
- struct msg_digest *st_suspended_md; /* suspended state-transition */
-
- struct oakley_trans_attrs st_oakley;
-
- struct ipsec_proto_info st_ah;
- struct ipsec_proto_info st_esp;
- struct ipsec_proto_info st_ipcomp;
-#ifdef KLIPS
- ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
- ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
-#endif
-
- const struct oakley_group_desc *st_pfs_group; /* group for Phase 2 PFS */
-
- u_int32_t st_doi; /* Domain of Interpretation */
- u_int32_t st_situation;
-
- lset_t st_policy; /* policy for IPsec SA */
-
- msgid_t st_msgid; /* MSG-ID from header. Network Order! */
-
- /* only for a state representing an ISAKMP SA */
- struct msgid_list *st_used_msgids; /* used-up msgids */
-
-/* symmetric stuff */
-
- /* initiator stuff */
- chunk_t st_gi; /* Initiator public value */
- u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
- chunk_t st_ni; /* Ni nonce */
-
- /* responder stuff */
- chunk_t st_gr; /* Responder public value */
- u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
- chunk_t st_nr; /* Nr nonce */
-
-
- /* my stuff */
-
- chunk_t st_tpacket; /* Transmitted packet */
-
- /* Phase 2 ID payload info about my user */
- u_int8_t st_myuserprotoid; /* IDcx.protoid */
- u_int16_t st_myuserport;
-
- /* his stuff */
-
- chunk_t st_rpacket; /* Received packet */
-
- /* Phase 2 ID payload info about peer's user */
- u_int8_t st_peeruserprotoid; /* IDcx.protoid */
- u_int16_t st_peeruserport;
-
-/* end of symmetric stuff */
-
- u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */
- MP_INT st_sec; /* Our local secret value */
-
- chunk_t st_shared; /* Derived shared secret
- * Note: during Quick Mode,
- * presence indicates PFS
- * selected.
- */
-
- /* In a Phase 1 state, preserve peer's public key after authentication */
- struct pubkey *st_peer_pubkey;
-
- enum state_kind st_state; /* State of exchange */
- u_int8_t st_retransmit; /* Number of retransmits */
- unsigned long st_try; /* number of times rekeying attempted */
- /* 0 means the only time */
- time_t st_margin; /* life after EVENT_SA_REPLACE */
- unsigned long st_outbound_count; /* traffic through eroute */
- time_t st_outbound_time; /* time of last change to st_outbound_count */
- chunk_t st_p1isa; /* Phase 1 initiator SA (Payload) for HASH */
- chunk_t st_skeyid; /* Key material */
- chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
- chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
- chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
- u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
- u_char st_new_iv[MAX_DIGEST_LEN];
- u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
- unsigned int st_iv_len;
- unsigned int st_new_iv_len;
- unsigned int st_ph1_iv_len;
-
- chunk_t st_enc_key; /* Oakley Encryption key */
-
- struct event *st_event; /* backpointer for certain events */
- struct state *st_hashchain_next; /* Next in list */
- struct state *st_hashchain_prev; /* Previous in list */
-
- struct {
- bool vars_set;
- bool started;
- } st_modecfg;
-
- struct {
- int attempt;
- bool started;
- bool status;
- } st_xauth;
-
-#ifdef NAT_TRAVERSAL
- u_int32_t nat_traversal;
- ip_address nat_oa;
-#endif
-
- /* RFC 3706 Dead Peer Detection */
- bool st_dpd; /* Peer supports DPD */
- time_t st_last_dpd; /* Time of last DPD transmit */
- u_int32_t st_dpd_seqno; /* Next R_U_THERE to send */
- u_int32_t st_dpd_expectseqno; /* Next R_U_THERE_ACK to receive */
- u_int32_t st_dpd_peerseqno; /* global variables */
- struct event *st_dpd_event; /* backpointer for DPD events */
-
- u_int32_t st_seen_vendorid; /* Bit field about recognized Vendor ID */
-};
-
-/* global variables */
-
-extern u_int16_t pluto_port; /* Pluto's port */
-
-extern bool states_use_connection(struct connection *c);
-
-/* state functions */
-
-extern struct state *new_state(void);
-extern void init_states(void);
-extern void insert_state(struct state *st);
-extern void unhash_state(struct state *st);
-extern void release_whack(struct state *st);
-extern void state_eroute_usage(ip_subnet *ours, ip_subnet *his
- , unsigned long count, time_t nw);
-extern void delete_state(struct state *st);
-extern void delete_states_by_connection(struct connection *c, bool relations);
-
-extern struct state
- *duplicate_state(struct state *st),
- *find_state(const u_char *icookie
- , const u_char *rcookie
- , const ip_address *peer
- , msgid_t msgid),
- *state_with_serialno(so_serial_t sn),
- *find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
- , ipsec_spi_t spi, bool *bogus),
- *find_phase1_state(const struct connection *c, lset_t ok_states),
- *find_sender(size_t packet_len, u_char *packet);
-
-extern void show_states_status(bool all, const char *name);
-extern void for_each_state(void *(f)(struct state *, void *data), void *data);
-extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi);
-extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
-extern void fmt_state(bool all, struct state *st, time_t n
- , char *state_buf, size_t state_buf_len
- , char *state_buf2, size_t state_buf_len2);
-extern void delete_states_by_peer(ip_address *peer);
diff --git a/programs/pluto/timer.c b/programs/pluto/timer.c
deleted file mode 100644
index 4d9ef8fab..000000000
--- a/programs/pluto/timer.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/* timer event handling
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: timer.c,v 1.5 2004/09/17 21:36:57 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/queue.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "connections.h"
-#include "state.h"
-#include "demux.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-#include "kernel.h"
-#include "server.h"
-#include "log.h"
-#include "rnd.h"
-#include "timer.h"
-#include "whack.h"
-
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-/* monotonic version of time(3) */
-time_t
-now(void)
-{
- static time_t delta = 0
- , last_time = 0;
- time_t n = time((time_t)NULL);
-
- passert(n != (time_t)-1);
- if (last_time > n)
- {
- plog("time moved backwards %ld seconds", (long)(last_time - n));
- delta += last_time - n;
- }
- last_time = n;
- return n + delta;
-}
-
-/* This file has the event handling routines. Events are
- * kept as a linked list of event structures. These structures
- * have information like event type, expiration time and a pointer
- * to event specific data (for example, to a state structure).
- */
-
-static struct event *evlist = (struct event *) NULL;
-
-/*
- * This routine places an event in the event list.
- */
-void
-event_schedule(enum event_type type, time_t tm, struct state *st)
-{
- struct event *ev = alloc_thing(struct event, "struct event in event_schedule()");
-
- ev->ev_type = type;
- ev->ev_time = tm + now();
- ev->ev_state = st;
-
- /* If the event is associated with a state, put a backpointer to the
- * event in the state object, so we can find and delete the event
- * if we need to (for example, if we receive a reply).
- */
- if (st != NULL)
- {
- if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
- {
- passert(st->st_dpd_event == NULL);
- st->st_dpd_event = ev;
- }
- else
- {
- passert(st->st_event == NULL);
- st->st_event = ev;
- }
- }
-
- DBG(DBG_CONTROL,
- if (st == NULL)
- DBG_log("inserting event %s, timeout in %lu seconds"
- , enum_show(&timer_event_names, type), (unsigned long)tm);
- else
- DBG_log("inserting event %s, timeout in %lu seconds for #%lu"
- , enum_show(&timer_event_names, type), (unsigned long)tm
- , ev->ev_state->st_serialno));
-
- if (evlist == (struct event *) NULL
- || evlist->ev_time >= ev->ev_time)
- {
- ev->ev_next = evlist;
- evlist = ev;
- }
- else
- {
- struct event *evt;
-
- for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
- if (evt->ev_next->ev_time >= ev->ev_time)
- break;
-
-#ifdef NEVER /* this seems to be overkill */
- DBG(DBG_CONTROL,
- if (evt->ev_state == NULL)
- DBG_log("event added after event %s"
- , enum_show(&timer_event_names, evt->ev_type));
- else
- DBG_log("event added after event %s for #%lu"
- , enum_show(&timer_event_names, evt->ev_type)
- , evt->ev_state->st_serialno));
-#endif /* NEVER */
-
- ev->ev_next = evt->ev_next;
- evt->ev_next = ev;
- }
-}
-
-/*
- * Handle the first event on the list.
- */
-void
-handle_timer_event(void)
-{
- time_t tm;
- struct event *ev = evlist;
- int type;
- struct state *st;
- struct connection *c = NULL;
- ip_address peer;
-
- if (ev == (struct event *) NULL) /* Just paranoid */
- {
- DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
- return;
- }
-
- type = ev->ev_type;
- st = ev->ev_state;
-
- tm = now();
-
- if (tm < ev->ev_time)
- {
- DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)"
- , (unsigned long)tm, (unsigned long)ev->ev_time
- , enum_show(&timer_event_names, type)));
-
- /* This will happen if the most close-to-expire event was
- * a retransmission or cleanup, and we received a packet
- * at the same time as the event expired. Due to the processing
- * order in call_server(), the packet processing will happen first,
- * and the event will be removed.
- */
- return;
- }
-
- evlist = evlist->ev_next; /* Ok, we'll handle this event */
-
- DBG(DBG_CONTROL,
- if (evlist != (struct event *) NULL)
- DBG_log("event after this is %s in %ld seconds"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long) (evlist->ev_time - tm)));
-
- /* for state-associated events, pick up the state pointer
- * and remove the backpointer from the state object.
- * We'll eventually either schedule a new event, or delete the state.
- */
- passert(GLOBALS_ARE_RESET());
- if (st != NULL)
- {
- c = st->st_connection;
- if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
- {
- passert(st->st_dpd_event == ev);
- st->st_dpd_event = NULL;
- }
- else
- {
- passert(st->st_event == ev);
- st->st_event = NULL;
- }
- peer = c->spd.that.host_addr;
- set_cur_state(st);
- }
-
- switch (type)
- {
- case EVENT_REINIT_SECRET:
- passert(st == NULL);
- DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
- init_secret();
- break;
-
-#ifdef KLIPS
- case EVENT_SHUNT_SCAN:
- passert(st == NULL);
- scan_proc_shunts();
- break;
-#endif
-
- case EVENT_LOG_DAILY:
- daily_log_event();
- break;
-
- case EVENT_RETRANSMIT:
- /* Time to retransmit, or give up.
- *
- * Generally, we'll only try to send the message
- * MAXIMUM_RETRANSMISSIONS times. Each time we double
- * our patience.
- *
- * As a special case, if this is the first initiating message
- * of a Main Mode exchange, and we have been directed to try
- * forever, we'll extend the number of retransmissions to
- * MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
- * extended attempts having the same patience. The intention
- * is to reduce the bother when nobody is home.
- */
- {
- time_t delay = 0;
-
- DBG(DBG_CONTROL, DBG_log(
- "handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
- , ip_str(&peer), c->name, st->st_serialno));
-
- if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
- delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
- else if (st->st_state == STATE_MAIN_I1
- && c->sa_keying_tries == 0
- && st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
- delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
-
- if (delay != 0)
- {
- st->st_retransmit++;
- whack_log(RC_RETRANSMISSION
- , "%s: retransmission; will wait %lus for response"
- , enum_name(&state_names, st->st_state)
- , (unsigned long)delay);
- send_packet(st, "EVENT_RETRANSMIT");
- event_schedule(EVENT_RETRANSMIT, delay, st);
- }
- else
- {
- /* check if we've tried rekeying enough times.
- * st->st_try == 0 means that this should be the only try.
- * c->sa_keying_tries == 0 means that there is no limit.
- */
- unsigned long try = st->st_try;
- unsigned long try_limit = c->sa_keying_tries;
- const char *details = "";
-
- switch (st->st_state)
- {
- case STATE_MAIN_I3:
- details = ". Possible authentication failure:"
- " no acceptable response to our"
- " first encrypted message";
- break;
- case STATE_MAIN_I1:
- details = ". No response (or no acceptable response) to our"
- " first IKE message";
- break;
- case STATE_QUICK_I1:
- if (c->newest_ipsec_sa == SOS_NOBODY)
- details = ". No acceptable response to our"
- " first Quick Mode message:"
- " perhaps peer likes no proposal";
- break;
- default:
- break;
- }
- loglog(RC_NORETRANSMISSION
- , "max number of retransmissions (%d) reached %s%s"
- , st->st_retransmit
- , enum_show(&state_names, st->st_state), details);
- if (try != 0 && try != try_limit)
- {
- /* A lot like EVENT_SA_REPLACE, but over again.
- * Since we know that st cannot be in use,
- * we can delete it right away.
- */
- char story[80]; /* arbitrary limit */
-
- try++;
- snprintf(story, sizeof(story), try_limit == 0
- ? "starting keying attempt %ld of an unlimited number"
- : "starting keying attempt %ld of at most %ld"
- , try, try_limit);
-
- if (st->st_whack_sock != NULL_FD)
- {
- /* Release whack because the observer will get bored. */
- loglog(RC_COMMENT, "%s, but releasing whack"
- , story);
- release_pending_whacks(st, story);
- }
- else
- {
- /* no whack: just log to syslog */
- plog("%s", story);
- }
- ipsecdoi_replace(st, try);
- }
- delete_state(st);
- }
- }
- break;
-
- case EVENT_SA_REPLACE:
- case EVENT_SA_REPLACE_IF_USED:
- {
- so_serial_t newest = IS_PHASE1(st->st_state)
- ? c->newest_isakmp_sa : c->newest_ipsec_sa;
-
- if (newest != st->st_serialno
- && newest != SOS_NOBODY)
- {
- /* not very interesting: no need to replace */
- DBG(DBG_LIFECYCLE
- , plog("not replacing stale %s SA: #%lu will do"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
- , newest));
- }
- else if (type == EVENT_SA_REPLACE_IF_USED
- && st->st_outbound_time <= tm - c->sa_rekey_margin)
- {
- /* we observed no recent use: no need to replace
- *
- * The sampling effects mean that st_outbound_time
- * could be up to SHUNT_SCAN_INTERVAL more recent
- * than actual traffic because the sampler looks at change
- * over that interval.
- * st_outbound_time could also not yet reflect traffic
- * in the last SHUNT_SCAN_INTERVAL.
- * We expect that SHUNT_SCAN_INTERVAL is smaller than
- * c->sa_rekey_margin so that the effects of this will
- * be unimportant.
- * This is just an optimization: correctness is not
- * at stake.
- *
- * Note: we are abusing the DBG mechanism to control
- * normal log output.
- */
- DBG(DBG_LIFECYCLE
- , plog("not replacing stale %s SA: inactive for %lus"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
- , (unsigned long)(tm - st->st_outbound_time)));
- }
- else
- {
- DBG(DBG_LIFECYCLE
- , plog("replacing stale %s SA"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
- ipsecdoi_replace(st, 1);
- }
- delete_dpd_event(st);
- event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
- }
- break;
-
- case EVENT_SA_EXPIRE:
- {
- const char *satype;
- so_serial_t latest;
-
- if (IS_PHASE1(st->st_state))
- {
- satype = "ISAKMP";
- latest = c->newest_isakmp_sa;
- }
- else
- {
- satype = "IPsec";
- latest = c->newest_ipsec_sa;
- }
-
- if (st->st_serialno != latest)
- {
- /* not very interesting: already superseded */
- DBG(DBG_LIFECYCLE
- , plog("%s SA expired (superseded by #%lu)"
- , satype, latest));
- }
- else
- {
- plog("%s SA expired (%s)", satype
- , (c->policy & POLICY_DONT_REKEY)
- ? "--dontrekey"
- : "LATEST!"
- );
- }
- }
- /* FALLTHROUGH */
- case EVENT_SO_DISCARD:
- /* Delete this state object. It must be in the hash table. */
- delete_state(st);
- break;
-
- case EVENT_DPD:
- dpd_outI(st);
- break;
- case EVENT_DPD_TIMEOUT:
- dpd_timeout(st);
- break;
-#ifdef NAT_TRAVERSAL
- case EVENT_NAT_T_KEEPALIVE:
- nat_traversal_ka_event();
- break;
-#endif
- default:
- loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %s"
- , enum_show(&timer_event_names, type));
- }
-
- pfree(ev);
- reset_cur_state();
-}
-
-/*
- * Return the time until the next event in the queue
- * expires (never negative), or -1 if no jobs in queue.
- */
-long
-next_event(void)
-{
- time_t tm;
-
- if (evlist == (struct event *) NULL)
- return -1;
-
- tm = now();
-
- DBG(DBG_CONTROL,
- if (evlist->ev_state == NULL)
- DBG_log("next event %s in %ld seconds"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long)evlist->ev_time - (long)tm);
- else
- DBG_log("next event %s in %ld seconds for #%lu"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long)evlist->ev_time - (long)tm
- , evlist->ev_state->st_serialno));
-
- if (evlist->ev_time - tm <= 0)
- return 0;
- else
- return evlist->ev_time - tm;
-}
-
-/*
- * Delete an event.
- */
-void
-delete_event(struct state *st)
-{
- if (st->st_event != (struct event *) NULL)
- {
- struct event **ev;
-
- for (ev = &evlist; ; ev = &(*ev)->ev_next)
- {
- if (*ev == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
- enum_show(&timer_event_names, st->st_event->ev_type)));
- break;
- }
- if ((*ev) == st->st_event)
- {
- *ev = (*ev)->ev_next;
-
- if (st->st_event->ev_type == EVENT_RETRANSMIT)
- st->st_retransmit = 0;
- pfree(st->st_event);
- st->st_event = (struct event *) NULL;
-
- break;
- }
- }
- }
-}
-
-/*
- * Delete a DPD event.
- */
-void
-delete_dpd_event(struct state *st)
-{
- if (st->st_dpd_event != (struct event *) NULL)
- {
- struct event **ev;
-
- for (ev = &evlist; ; ev = &(*ev)->ev_next)
- {
- if (*ev == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
- enum_show(&timer_event_names, st->st_dpd_event->ev_type)));
- break;
- }
- if ((*ev) == st->st_dpd_event)
- {
- *ev = (*ev)->ev_next;
- pfree(st->st_dpd_event);
- st->st_dpd_event = (struct event *) NULL;
- break;
- }
- }
- }
-}
-
-
diff --git a/programs/pluto/timer.h b/programs/pluto/timer.h
deleted file mode 100644
index 92464192c..000000000
--- a/programs/pluto/timer.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* timing machinery
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: timer.h,v 1.2 2004/07/29 18:33:45 as Exp $
- */
-
-extern time_t now(void); /* careful version of time(2) */
-
-struct state; /* forward declaration */
-
-struct event
-{
- time_t ev_time;
- int ev_type; /* Event type */
- struct state *ev_state; /* Pointer to relevant state (if any) */
- struct event *ev_next; /* Pointer to next event */
-};
-
-extern void event_schedule(enum event_type type, time_t tm, struct state *st);
-extern void handle_timer_event(void);
-extern long next_event(void);
-extern void delete_event(struct state *st);
-extern void delete_dpd_event(struct state *st);
-extern void daily_log_event(void);
diff --git a/programs/pluto/vendor.c b/programs/pluto/vendor.c
deleted file mode 100644
index 6d1137c09..000000000
--- a/programs/pluto/vendor.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/* ISAKMP VendorID
- * Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: vendor.c,v 1.46 2007/02/21 14:20:25 as Exp $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/queue.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "md5.h"
-#include "connections.h"
-#include "packet.h"
-#include "demux.h"
-#include "whack.h"
-#include "vendor.h"
-#include "kernel.h"
-
-#ifdef NAT_TRAVERSAL
-#include "nat_traversal.h"
-#endif
-
-/**
- * Unknown/Special VID:
- *
- * SafeNet SoftRemote 8.0.0:
- * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e302e3020284275696c6420313029000000
- * >> 382e302e3020284275696c6420313029 = '8.0.0 (Build 10)'
- * da8e937880010000
- *
- * SafeNet SoftRemote 9.0.1
- * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310392e302e3120284275696c6420313229000000
- * >> 392e302e3120284275696c6420313229 = '9.0.1 (Build 12)'
- * da8e937880010000
- *
- * Netscreen:
- * d6b45f82f24bacb288af59a978830ab7
- * cf49908791073fb46439790fdeb6aeed981101ab0000000500000300
- *
- * Cisco:
- * 1f07f70eaa6514d3b0fa96542a500300 (VPN 3000 version 3.0.0)
- * 1f07f70eaa6514d3b0fa96542a500301 (VPN 3000 version 3.0.1)
- * 1f07f70eaa6514d3b0fa96542a500305 (VPN 3000 version 3.0.5)
- * 1f07f70eaa6514d3b0fa96542a500407 (VPN 3000 version 4.0.7)
- * (Can you see the pattern?)
- * afcad71368a1f1c96b8696fc77570100 (Non-RFC Dead Peer Detection ?)
- * c32364b3b4f447eb17c488ab2a480a57
- * 6d761ddc26aceca1b0ed11fabbb860c4
- * 5946c258f99a1a57b03eb9d1759e0f24 (From a Cisco VPN 3k)
- * ebbc5b00141d0c895e11bd395902d690 (From a Cisco VPN 3k)
- *
- * Microsoft L2TP (???):
- * 47bbe7c993f1fc13b4e6d0db565c68e5010201010201010310382e312e3020284275696c6420313029000000
- * >> 382e312e3020284275696c6420313029 = '8.1.0 (Build 10)'
- * 3025dbd21062b9e53dc441c6aab5293600000000
- * da8e937880010000
- *
- * 3COM-superstack
- * da8e937880010000
- * 404bf439522ca3f6
- *
-
- * If someone know what they mean, mail me.
- */
-
-#define MAX_LOG_VID_LEN 32
-
-#define VID_KEEP 0x0000
-#define VID_MD5HASH 0x0001
-#define VID_STRING 0x0002
-#define VID_FSWAN_HASH 0x0004
-
-#define VID_SUBSTRING_DUMPHEXA 0x0100
-#define VID_SUBSTRING_DUMPASCII 0x0200
-#define VID_SUBSTRING_MATCH 0x0400
-#define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH)
-
-struct vid_struct {
- enum known_vendorid id;
- unsigned short flags;
- const char *data;
- const char *descr;
- const char *vid;
- u_int vid_len;
-};
-
-#define DEC_MD5_VID_D(id,str,descr) \
- { VID_##id, VID_MD5HASH, str, descr, NULL, 0 },
-#define DEC_MD5_VID(id,str) \
- { VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
-#define DEC_FSWAN_VID(id,str,descr) \
- { VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 },
-
-static struct vid_struct _vid_tab[] = {
-
- /* Implementation names */
-
- { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
-
- DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
-
- { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
- "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
-
- DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
- DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
- DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
- DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
- DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
- DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
-
- /* These ones come from SSH vendors.txt */
- DEC_MD5_VID(SSH_IPSEC_1_1_0,
- "Ssh Communications Security IPSEC Express version 1.1.0")
- DEC_MD5_VID(SSH_IPSEC_1_1_1,
- "Ssh Communications Security IPSEC Express version 1.1.1")
- DEC_MD5_VID(SSH_IPSEC_1_1_2,
- "Ssh Communications Security IPSEC Express version 1.1.2")
- DEC_MD5_VID(SSH_IPSEC_1_2_1,
- "Ssh Communications Security IPSEC Express version 1.2.1")
- DEC_MD5_VID(SSH_IPSEC_1_2_2,
- "Ssh Communications Security IPSEC Express version 1.2.2")
- DEC_MD5_VID(SSH_IPSEC_2_0_0,
- "SSH Communications Security IPSEC Express version 2.0.0")
- DEC_MD5_VID(SSH_IPSEC_2_1_0,
- "SSH Communications Security IPSEC Express version 2.1.0")
- DEC_MD5_VID(SSH_IPSEC_2_1_1,
- "SSH Communications Security IPSEC Express version 2.1.1")
- DEC_MD5_VID(SSH_IPSEC_2_1_2,
- "SSH Communications Security IPSEC Express version 2.1.2")
- DEC_MD5_VID(SSH_IPSEC_3_0_0,
- "SSH Communications Security IPSEC Express version 3.0.0")
- DEC_MD5_VID(SSH_IPSEC_3_0_1,
- "SSH Communications Security IPSEC Express version 3.0.1")
- DEC_MD5_VID(SSH_IPSEC_4_0_0,
- "SSH Communications Security IPSEC Express version 4.0.0")
- DEC_MD5_VID(SSH_IPSEC_4_0_1,
- "SSH Communications Security IPSEC Express version 4.0.1")
- DEC_MD5_VID(SSH_IPSEC_4_1_0,
- "SSH Communications Security IPSEC Express version 4.1.0")
- DEC_MD5_VID(SSH_IPSEC_4_2_0,
- "SSH Communications Security IPSEC Express version 4.2.0")
-
- /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
- { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
- "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
- 16 },
-
- { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH,
- NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14},
-
- { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
- NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
-
- /*
- * Timestep VID seen:
- * - 54494d455354455020312053475720313532302033313520322e303145303133
- * = 'TIMESTEP 1 SGW 1520 315 2.01E013'
- */
- { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
- NULL, NULL, 0 },
-
- /*
- * Netscreen:
- * 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
- */
- { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
- "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
-
- /*
- * MacOS X
- */
- { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
- "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", NULL, 0},
-
- /*
- * Openswan
- */
- DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
-
- /* NCP */
- { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
- "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
- { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
- "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
- /*
- * strongSwan
- */
- DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
- DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
- DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
- DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
- DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
- DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
- DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
- DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7")
-
- DEC_MD5_VID(STRONGSWAN, "strongSwan 2.8.3")
- DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
- DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
- DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
- DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
- DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
- DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
- DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
- DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
- DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
- DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")
- DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1")
- DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0")
- DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7")
- DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6")
- DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5")
- DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4")
- DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3")
- DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2")
- DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1")
- DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0")
- DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4")
- DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3")
- DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2")
- DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1")
- DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0")
- DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2")
- DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1")
- DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0")
- DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2")
- DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1")
- DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0")
-
- /* NAT-Traversal */
-
- DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
- DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
- DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
- DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
- DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
- DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
- /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
- DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
- DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
- DEC_MD5_VID(NATT_RFC, "RFC 3947")
-
- /* misc */
-
- { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
- "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
-
- { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
- "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 },
-
- DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
-
- DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
-
- /**
- * Cisco VPN 3000
- */
- { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
- "FRAGMENTATION", NULL, NULL, 0 },
-
- /* -- */
- { 0, 0, NULL, NULL, NULL, 0 }
-
-};
-
-static const char _hexdig[] = "0123456789abcdef";
-
-static int _vid_struct_init = 0;
-
-void
-init_vendorid(void)
-{
- struct vid_struct *vid;
- MD5_CTX ctx;
- int i;
-
- for (vid = _vid_tab; vid->id; vid++)
- {
- if (vid->flags & VID_STRING)
- {
- /** VendorID is a string **/
- vid->vid = strdup(vid->data);
- vid->vid_len = strlen(vid->data);
- }
- else if (vid->flags & VID_MD5HASH)
- {
- /** VendorID is a string to hash with MD5 **/
- char *vidm = malloc(MD5_DIGEST_SIZE);
-
- vid->vid = vidm;
- if (vidm)
- {
- MD5Init(&ctx);
- MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
- MD5Final(vidm, &ctx);
- vid->vid_len = MD5_DIGEST_SIZE;
- }
- }
- else if (vid->flags & VID_FSWAN_HASH)
- {
- /** FreeS/WAN 2.00+ specific hash **/
-#define FSWAN_VID_SIZE 12
- unsigned char hash[MD5_DIGEST_SIZE];
- char *vidm = malloc(FSWAN_VID_SIZE);
-
- vid->vid = vidm;
- if (vidm)
- {
- MD5Init(&ctx);
- MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
- MD5Final(hash, &ctx);
- vidm[0] = 'O';
- vidm[1] = 'E';
-#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
- memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
-#else
- memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
- memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
- FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
-#endif
- for (i = 2; i < FSWAN_VID_SIZE; i++)
- {
- vidm[i] &= 0x7f;
- vidm[i] |= 0x40;
- }
- vid->vid_len = FSWAN_VID_SIZE;
- }
- }
-
- if (vid->descr == NULL)
- {
- /** Find something to display **/
- vid->descr = vid->data;
- }
- }
- _vid_struct_init = 1;
-}
-
-static void
-handle_known_vendorid (struct msg_digest *md
-, const char *vidstr, size_t len, struct vid_struct *vid)
-{
- char vid_dump[128];
- bool vid_useful = FALSE;
- size_t i, j;
-
- switch (vid->id) {
- /* Remote side supports OpenPGP certificates */
- case VID_OPENPGP:
- md->openpgp = TRUE;
- vid_useful = TRUE;
- break;
-#ifdef NAT_TRAVERSAL
- /*
- * Use most recent supported NAT-Traversal method and ignore the
- * other ones (implementations will send all supported methods but
- * only one will be used)
- *
- * Note: most recent == higher id in vendor.h
- */
- case VID_NATT_IETF_00:
- if (!nat_traversal_support_non_ike)
- break;
- if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
- {
- md->nat_traversal_vid = vid->id;
- vid_useful = TRUE;
- }
- break;
- case VID_NATT_IETF_02:
- case VID_NATT_IETF_02_N:
- case VID_NATT_IETF_03:
- case VID_NATT_RFC:
- if (nat_traversal_support_port_floating
- && md->nat_traversal_vid < vid->id)
- {
- md->nat_traversal_vid = vid->id;
- vid_useful = TRUE;
- }
- break;
-#endif
- /* Remote side would like to do DPD with us on this connection */
- case VID_MISC_DPD:
- md->dpd = TRUE;
- vid_useful = TRUE;
- break;
- case VID_MISC_XAUTH:
- vid_useful = TRUE;
- break;
- default:
- break;
- }
-
- if (vid->flags & VID_SUBSTRING_DUMPHEXA)
- {
- /* Dump description + Hexa */
- memset(vid_dump, 0, sizeof(vid_dump));
- snprintf(vid_dump, sizeof(vid_dump), "%s ",
- vid->descr ? vid->descr : "");
- for (i = strlen(vid_dump), j = vid->vid_len;
- j < len && i < sizeof(vid_dump) - 2;
- i += 2, j++)
- {
- vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
- vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
- }
- }
- else if (vid->flags & VID_SUBSTRING_DUMPASCII)
- {
- /* Dump ASCII content */
- memset(vid_dump, 0, sizeof(vid_dump));
- for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
- {
- vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
- }
- }
- else
- {
- /* Dump description (descr) */
- snprintf(vid_dump, sizeof(vid_dump), "%s",
- vid->descr ? vid->descr : "");
- }
-
- loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
- vid_useful ? "received" : "ignoring", vid_dump);
-}
-
-void
-handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
-{
- struct vid_struct *pvid;
-
- if (!_vid_struct_init)
- init_vendorid();
-
- /*
- * Find known VendorID in _vid_tab
- */
- for (pvid = _vid_tab; pvid->id; pvid++)
- {
- if (pvid->vid && vid && pvid->vid_len && len)
- {
- if (pvid->vid_len == len)
- {
- if (memcmp(pvid->vid, vid, len) == 0)
- {
- handle_known_vendorid(md, vid, len, pvid);
- return;
- }
- }
- else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
- {
- if (memcmp(pvid->vid, vid, pvid->vid_len) == 0)
- {
- handle_known_vendorid(md, vid, len, pvid);
- return;
- }
- }
- }
- }
-
- /*
- * Unknown VendorID. Log the beginning.
- */
- {
- char log_vid[2*MAX_LOG_VID_LEN+1];
- size_t i;
-
- memset(log_vid, 0, sizeof(log_vid));
-
- for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
- {
- log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
- log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
- }
- loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
- log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
- }
-}
-
-/**
- * Add a vendor id payload to the msg
- */
-bool
-out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
-{
- struct vid_struct *pvid;
-
- if (!_vid_struct_init)
- init_vendorid();
-
- for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++);
-
- if (pvid->id != vid)
- return STF_INTERNAL_ERROR; /* not found */
- if (!pvid->vid)
- return STF_INTERNAL_ERROR; /* not initialized */
-
- DBG(DBG_EMITTING,
- DBG_log("out_vendorid(): sending [%s]", pvid->descr)
- )
- return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
- pvid->vid, pvid->vid_len, "V_ID");
-}
-
diff --git a/programs/pluto/vendor.h b/programs/pluto/vendor.h
deleted file mode 100644
index 69d98cd38..000000000
--- a/programs/pluto/vendor.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* FreeS/WAN ISAKMP VendorID
- * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: vendor.h,v 1.41 2007/02/21 14:20:25 as Exp $
- */
-
-#ifndef _VENDOR_H_
-#define _VENDOR_H_
-
-enum known_vendorid {
-/* 1 - 100 : Implementation names */
- VID_OPENPGP = 1,
- VID_KAME_RACOON = 2,
- VID_MS_NT5 = 3,
- VID_SSH_SENTINEL = 4,
- VID_SSH_SENTINEL_1_1 = 5,
- VID_SSH_SENTINEL_1_2 = 6,
- VID_SSH_SENTINEL_1_3 = 7,
- VID_SSH_SENTINEL_1_4 = 8,
- VID_SSH_SENTINEL_1_4_1 = 9,
- VID_SSH_IPSEC_1_1_0 = 10,
- VID_SSH_IPSEC_1_1_1 = 11,
- VID_SSH_IPSEC_1_1_2 = 12,
- VID_SSH_IPSEC_1_2_1 = 13,
- VID_SSH_IPSEC_1_2_2 = 14,
- VID_SSH_IPSEC_2_0_0 = 15,
- VID_SSH_IPSEC_2_1_0 = 16,
- VID_SSH_IPSEC_2_1_1 = 17,
- VID_SSH_IPSEC_2_1_2 = 18,
- VID_SSH_IPSEC_3_0_0 = 19,
- VID_SSH_IPSEC_3_0_1 = 20,
- VID_SSH_IPSEC_4_0_0 = 21,
- VID_SSH_IPSEC_4_0_1 = 22,
- VID_SSH_IPSEC_4_1_0 = 23,
- VID_SSH_IPSEC_4_2_0 = 24,
- VID_CISCO_UNITY = 25,
- VID_CISCO3K = 26,
- VID_CISCO_IOS = 27,
- VID_TIMESTEP = 28,
- VID_SAFENET = 29,
- VID_MACOSX = 30,
- VID_OPENSWAN2 = 31,
- VID_NCP_SERVER = 32,
- VID_NCP_CLIENT = 33,
- VID_STRONGSWAN = 34,
- VID_STRONGSWAN_2_2_0 = 35,
- VID_STRONGSWAN_2_2_1 = 36,
- VID_STRONGSWAN_2_2_2 = 37,
- VID_STRONGSWAN_2_3_0 = 38,
- VID_STRONGSWAN_2_3_1 = 39,
- VID_STRONGSWAN_2_3_2 = 40,
- VID_STRONGSWAN_2_4_0 = 41,
- VID_STRONGSWAN_2_4_1 = 42,
- VID_STRONGSWAN_2_4_2 = 43,
- VID_STRONGSWAN_2_4_3 = 44,
- VID_STRONGSWAN_2_4_4 = 45,
- VID_STRONGSWAN_2_5_0 = 46,
- VID_STRONGSWAN_2_5_1 = 47,
- VID_STRONGSWAN_2_5_2 = 48,
- VID_STRONGSWAN_2_5_3 = 49,
- VID_STRONGSWAN_2_5_4 = 50,
- VID_STRONGSWAN_2_5_5 = 51,
- VID_STRONGSWAN_2_5_6 = 52,
- VID_STRONGSWAN_2_5_7 = 53,
- VID_STRONGSWAN_2_6_0 = 54,
- VID_STRONGSWAN_2_6_1 = 55,
- VID_STRONGSWAN_2_6_2 = 56,
- VID_STRONGSWAN_2_6_3 = 57,
- VID_STRONGSWAN_2_6_4 = 58,
- VID_STRONGSWAN_2_7_0 = 59,
- VID_STRONGSWAN_2_7_1 = 60,
- VID_STRONGSWAN_2_7_2 = 61,
- VID_STRONGSWAN_2_7_3 = 62,
- VID_STRONGSWAN_2_8_0 = 63,
- VID_STRONGSWAN_2_8_1 = 64,
- VID_STRONGSWAN_2_8_2 = 65,
-
- VID_STRONGSWAN_4_0_0 = 70,
- VID_STRONGSWAN_4_0_1 = 71,
- VID_STRONGSWAN_4_0_2 = 72,
- VID_STRONGSWAN_4_0_3 = 73,
- VID_STRONGSWAN_4_0_4 = 74,
- VID_STRONGSWAN_4_0_5 = 75,
- VID_STRONGSWAN_4_0_6 = 76,
- VID_STRONGSWAN_4_0_7 = 77,
-
- /* 101 - 200 : NAT-Traversal */
- VID_NATT_STENBERG_01 =101,
- VID_NATT_STENBERG_02 =102,
- VID_NATT_HUTTUNEN =103,
- VID_NATT_HUTTUNEN_ESPINUDP =104,
- VID_NATT_IETF_00 =105,
- VID_NATT_IETF_02_N =106,
- VID_NATT_IETF_02 =107,
- VID_NATT_IETF_03 =108,
- VID_NATT_RFC =109,
-
- /* 201 - 300 : Misc */
- VID_MISC_XAUTH =201,
- VID_MISC_DPD =202,
- VID_MISC_HEARTBEAT_NOTIFY =203,
- VID_MISC_FRAGMENTATION =204,
- VID_INITIAL_CONTACT =205,
- VID_CISCO3K_FRAGMENTATION =206
-};
-
-void init_vendorid(void);
-
-struct msg_digest;
-void handle_vendorid (struct msg_digest *md, const char *vid, size_t len);
-
-bool out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid);
-
-#endif /* _VENDOR_H_ */
-
diff --git a/programs/pluto/virtual.c b/programs/pluto/virtual.c
deleted file mode 100644
index 58487c1e8..000000000
--- a/programs/pluto/virtual.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* FreeS/WAN Virtual IP Management
- * Copyright (C) 2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: virtual.c,v 1.4 2004/04/02 10:38:52 as Exp $
- */
-
-#ifdef VIRTUAL_IP
-
-#include <freeswan.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/queue.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "connections.h"
-#include "whack.h"
-#include "virtual.h"
-
-#define F_VIRTUAL_NO 1
-#define F_VIRTUAL_DHCP 2
-#define F_VIRTUAL_IKE_CONFIG 4
-#define F_VIRTUAL_PRIVATE 8
-#define F_VIRTUAL_ALL 16
-#define F_VIRTUAL_HOST 32
-
-struct virtual_t {
- unsigned short flags;
- unsigned short n_net;
- ip_subnet net[0];
-};
-
-static ip_subnet *private_net_ok=NULL, *private_net_ko=NULL;
-static unsigned short private_net_ok_len=0, private_net_ko_len=0;
-
-/**
- * read %v4:x.x.x.x/y or %v6:xxxxxxxxx/yy
- * or %v4:!x.x.x.x/y if dstko not NULL
- */
-static bool
-_read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko,
- bool *isok)
-{
- bool ok;
- int af;
-
- if ((len > 4) && (strncmp(src, "%v4:", 4)==0))
- {
- af = AF_INET;
- }
- else if ((len > 4) && (strncmp(src, "%v6:", 4)==0))
- {
- af = AF_INET6;
- }
- else
- {
- return FALSE;
- }
-
- ok = (src[4] != '!');
- src += ok ? 4 : 5;
- len -= ok ? 4 : 5;
-
- if (!len)
- return FALSE;
- if (!ok && !dstko)
- return FALSE;
-
- passert ( ((ok)?(dst):(dstko))!=NULL );
-
- if (ttosubnet(src, len, af, ((ok)?(dst):(dstko))))
- {
- return FALSE;
- }
- if (isok)
- *isok = ok;
- return TRUE;
-}
-
-void
-init_virtual_ip(const char *private_list)
-{
- const char *next, *str=private_list;
- unsigned short ign = 0, i_ok, i_ko;
- ip_subnet sub;
- bool ok;
-
- /** Count **/
- private_net_ok_len=0;
- private_net_ko_len=0;
-
- while (str)
- {
- next = strchr(str,',');
- if (!next)
- next = str + strlen(str);
- if (_read_subnet(str, next-str, &sub, &sub, &ok))
- if (ok)
- private_net_ok_len++;
- else
- private_net_ko_len++;
- else
- ign++;
- str = *next ? next+1 : NULL;
- }
-
- if (!ign)
- {
- /** Allocate **/
- if (private_net_ok_len)
- {
- private_net_ok = (ip_subnet *)alloc_bytes(
- (private_net_ok_len*sizeof(ip_subnet)),
- "private_net_ok subnets");
- }
- if (private_net_ko_len)
- {
- private_net_ko = (ip_subnet *)alloc_bytes(
- (private_net_ko_len*sizeof(ip_subnet)),
- "private_net_ko subnets");
- }
- if ((private_net_ok_len && !private_net_ok)
- || (private_net_ko_len && !private_net_ko))
- {
- loglog(RC_LOG_SERIOUS,
- "can't alloc in init_virtual_ip");
- pfreeany(private_net_ok);
- private_net_ok = NULL;
- pfreeany(private_net_ko);
- private_net_ko = NULL;
- }
- else
- {
- /** Fill **/
- str = private_list;
- i_ok = 0;
- i_ko = 0;
-
- while (str)
- {
- next = strchr(str,',');
- if (!next)
- next = str + strlen(str);
- if (_read_subnet(str, next-str,
- &(private_net_ok[i_ok]), &(private_net_ko[i_ko]), &ok))
- {
- if (ok)
- i_ok++;
- else
- i_ko++;
- }
- str = *next ? next+1 : NULL;
- }
- }
- }
- else
- loglog(RC_LOG_SERIOUS,
- "%d bad entries in virtual_private - none loaded", ign);
-}
-
-/**
- * virtual string must be :
- * {vhost,vnet}:[%method]*
- *
- * vhost = accept only a host (/32)
- * vnet = accept any network
- *
- * %no = no virtual IP (accept public IP)
- * %dhcp = accept DHCP SA (0.0.0.0/0) of affected IP [not implemented]
- * %ike = accept affected IKE Config Mode IP [not implemented]
- * %priv = accept system-wide private net list
- * %v4:x = accept ipv4 in list 'x'
- * %v6:x = accept ipv6 in list 'x'
- * %all = accept all ips [only for testing]
- *
- * ex: vhost:%no,%dhcp,%priv,%v4:192.168.1.0/24
- */
-struct virtual_t
-*create_virtual(const struct connection *c, const char *string)
-{
- unsigned short flags=0, n_net=0, i;
- const char *str = string, *next, *first_net=NULL;
- ip_subnet sub;
- struct virtual_t *v;
-
- if (!string || string[0] == '\0')
- return NULL;
-
- if (strlen(string) >= 6 && strncmp(string,"vhost:",6) == 0)
- {
- flags |= F_VIRTUAL_HOST;
- str += 6;
- }
- else if (strlen(string) >= 5 && strncmp(string,"vnet:",5) == 0)
- str += 5;
- else
- goto fail;
-
- /**
- * Parse string : fill flags & count subnets
- */
- while ((str) && (*str))
- {
- next = strchr(str,',');
- if (!next) next = str + strlen(str);
- if (next-str == 3 && strncmp(str, "%no", 3) == 0)
- flags |= F_VIRTUAL_NO;
-#if 0
- else if (next-str == 4 && strncmp(str, "%ike", 4) == 0)
- flags |= F_VIRTUAL_IKE_CONFIG;
- else if (next-str == 5 && strncmp(str, "%dhcp", 5) == 0)
- flags |= F_VIRTUAL_DHCP;
-#endif
- else if (next-str == 5 && strncmp(str, "%priv", 5) == 0)
- flags |= F_VIRTUAL_PRIVATE;
- else if (next-str == 4 && strncmp(str, "%all", 4) == 0)
- flags |= F_VIRTUAL_ALL;
- else if (_read_subnet(str, next-str, &sub, NULL, NULL))
- {
- n_net++;
- if (!first_net)
- first_net = str;
- }
- else
- goto fail;
-
- str = *next ? next+1 : NULL;
- }
-
- v = (struct virtual_t *)alloc_bytes(
- sizeof(struct virtual_t) + (n_net*sizeof(ip_subnet)),
- "virtual description");
- if (!v) goto fail;
-
- v->flags = flags;
- v->n_net = n_net;
- if (n_net && first_net)
- {
- /**
- * Save subnets in newly allocated struct
- */
- for (str = first_net, i = 0; str && *str; )
- {
- next = strchr(str,',');
- if (!next) next = str + strlen(str);
- if (_read_subnet(str, next-str, &(v->net[i]), NULL, NULL))
- i++;
- str = *next ? next+1 : NULL;
- }
- }
-
- return v;
-
-fail:
- plog("invalid virtual string [%s] - "
- "virtual selection disabled for connection '%s'", string, c->name);
- return NULL;
-}
-
-bool
-is_virtual_end(const struct end *that)
-{
- return ((that->virt)?TRUE:FALSE);
-}
-
-bool
-is_virtual_connection(const struct connection *c)
-{
- return ((c->spd.that.virt)?TRUE:FALSE);
-}
-
-static bool
-net_in_list(const ip_subnet *peer_net, const ip_subnet *list,
- unsigned short len)
-{
- unsigned short i;
-
- if (!list || !len)
- return FALSE;
-
- for (i = 0; i < len; i++)
- {
- if (subnetinsubnet(peer_net, &(list[i])))
- return TRUE;
- }
- return FALSE;
-}
-
-bool
-is_virtual_net_allowed(const struct connection *c, const ip_subnet *peer_net,
- const ip_address *his_addr)
-{
- if (c->spd.that.virt == NULL)
- return FALSE;
-
- if ((c->spd.that.virt->flags & F_VIRTUAL_HOST)
- && !subnetishost(peer_net))
- return FALSE;
-
- if ((c->spd.that.virt->flags & F_VIRTUAL_NO)
- && subnetishost(peer_net) && addrinsubnet(his_addr, peer_net))
- return TRUE;
-
- if ((c->spd.that.virt->flags & F_VIRTUAL_PRIVATE)
- && net_in_list(peer_net, private_net_ok, private_net_ok_len)
- && !net_in_list(peer_net, private_net_ko, private_net_ko_len))
- return TRUE;
-
- if (c->spd.that.virt->n_net
- && net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net))
- return TRUE;
-
- if (c->spd.that.virt->flags & F_VIRTUAL_ALL)
- {
- /** %all must only be used for testing - log it **/
- loglog(RC_LOG_SERIOUS, "Warning - "
- "v%s:%%all must only be used for testing",
- (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net");
- return TRUE;
- }
-
- return FALSE;
-}
-
-#endif
-
diff --git a/programs/pluto/virtual.h b/programs/pluto/virtual.h
deleted file mode 100644
index 2d5bf27ae..000000000
--- a/programs/pluto/virtual.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* FreeS/WAN Virtual IP Management
- * Copyright (C) 2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: virtual.h,v 1.2 2004/03/22 21:53:20 as Exp $
- */
-
-#ifndef _VIRTUAL_IP_H
-#define _VIRTUAL_IP_H
-
-extern void init_virtual_ip(const char *private_list);
-
-extern struct virtual_t *create_virtual(const struct connection *c,
- const char *string);
-
-extern bool is_virtual_end(const struct end *that);
-extern bool is_virtual_connection(const struct connection *c);
-extern bool is_virtual_net_allowed(const struct connection *c,
- const ip_subnet *peer_net, const ip_address *his_addr);
-
-#endif /* _VIRTUAL_IP_H */
-
diff --git a/programs/pluto/whack.c b/programs/pluto/whack.c
deleted file mode 100644
index a3b983771..000000000
--- a/programs/pluto/whack.c
+++ /dev/null
@@ -1,1911 +0,0 @@
-/* command interface to Pluto
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: whack.c,v 1.21 2006/04/20 04:42:12 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <assert.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "whack.h"
-
-static void
-help(void)
-{
- fprintf(stderr
- , "Usage:\n\n"
- "all forms:"
- " [--optionsfrom <filename>]"
- " [--ctlbase <path>]"
- " [--label <string>]"
- "\n\n"
- "help: whack"
- " [--help]"
- " [--version]"
- "\n\n"
- "connection: whack"
- " --name <connection_name>"
- " \\\n "
- " [--ipv4 | --ipv6]"
- " [--tunnelipv4 | --tunnelipv6]"
- " \\\n "
- " (--host <ip-address> | --id <identity>)"
- " \\\n "
- " [--cert <path>]"
- " [--ca <distinguished name>]"
- " [--sendcert <policy>]"
- " \\\n "
- " [--groups <access control groups>]"
- " \\\n "
- " [--ikeport <port-number>]"
- " [--nexthop <ip-address>]"
- " [--srcip <ip-address>]"
- " \\\n "
- " [--client <subnet> | --clientwithin <address range>]"
- " [--clientprotoport <protocol>/<port>]"
- " \\\n "
- " [--dnskeyondemand]"
- " [--updown <updown>]"
- " \\\n "
- " --to"
- " (--host <ip-address> | --id <identity>)"
- " \\\n "
- " [--cert <path>]"
- " [--ca <distinguished name>]"
- " [--sendcert <policy>]"
- " \\\n "
- " [--ikeport <port-number>]"
- " [--nexthop <ip-address>]"
- " [--srcip <ip-address>]"
- " \\\n "
- " [--client <subnet> | --clientwithin <address range>]"
- " [--clientprotoport <protocol>/<port>]"
- " \\\n "
- " [--dnskeyondemand]"
- " [--updown <updown>]"
- " [--psk]"
- " [--rsasig]"
- " \\\n "
- " [--encrypt]"
- " [--authenticate]"
- " [--compress]"
- " [--tunnel]"
- " [--pfs]"
- " \\\n "
- " [--ikelifetime <seconds>]"
- " [--ipseclifetime <seconds>]"
- " \\\n "
- " [--reykeymargin <seconds>]"
- " [--reykeyfuzz <percentage>]"
- " \\\n "
- " [--keyingtries <count>]"
- " \\\n "
- " [--esp <esp-algos>]"
- " \\\n "
- " [--dontrekey]"
-
- " [--dpdaction (none|clear|hold|restart)]"
- " \\\n "
- " [--dpddelay <seconds> --dpdtimeout <seconds>]"
- " \\\n "
- " [--initiateontraffic|--pass|--drop|--reject]"
- " \\\n "
- " [--failnone|--failpass|--faildrop|--failreject]"
- "\n\n"
- "routing: whack"
- " (--route | --unroute)"
- " --name <connection_name>"
- "\n\n"
- "initiation:"
- "\n "
- " whack"
- " (--initiate | --terminate)"
- " --name <connection_name>"
- " [--asynchronous]"
- "\n\n"
- "opportunistic initiation: whack"
- " [--tunnelipv4 | --tunnelipv6]"
- " \\\n "
- " --oppohere <ip-address>"
- " --oppothere <ip-address>"
- "\n\n"
- "delete: whack"
- " --delete"
- " (--name <connection_name> | --caname <ca name>)"
- "\n\n"
- "deletestate: whack"
- " --deletestate <state_object_number>"
- " --crash <ip-address>"
- "\n\n"
- "pubkey: whack"
- " --keyid <id>"
- " [--addkey]"
- " [--pubkeyrsa <key>]"
- "\n\n"
- "myid: whack"
- " --myid <id>"
- "\n\n"
- "ca: whack"
- " --caname <name>"
- " --cacert <path>"
- " \\\n "
- " [--ldaphost <hostname>]"
- " [--ldapbase <base>]"
- " \\\n "
- " [--crluri <uri>]"
- " [--crluri2 <uri>]"
- " [--ocspuri <uri>]"
- " [--strictcrlpolicy]"
- "\n\n"
-#ifdef DEBUG
- "debug: whack [--name <connection_name>]"
- " \\\n "
- " [--debug-none]"
- " [--debug-all]"
- " \\\n "
- " [--debug-raw]"
- " [--debug-crypt]"
- " [--debug-parsing]"
- " [--debug-emitting]"
- " \\\n "
- " [--debug-control]"
- " [--debug-lifecycle]"
- " [--debug-klips]"
- " [--debug-dns]"
- " \\\n "
- " [--debug-natt]"
- " [--debug-oppo]"
- " [--debug-controlmore]"
- " [--debug-private]"
- "\n\n"
-#endif
- "listen: whack"
- " (--listen | --unlisten)"
- "\n\n"
- "list: whack [--utc]"
- " [--listalgs]"
- " [--listpubkeys]"
- " [--listcerts]"
- " [--listcacerts]"
- " \\\n "
- " [--listacerts]"
- " [--listaacerts]"
- " [--listocspcerts]"
- " [--listgroups]"
- " \\\n "
- " [--listcainfos]"
- " [--listcrls]"
- " [--listocsp]"
- " [--listcards]"
- " [--listall]"
- "\n\n"
- "purge: whack"
- " [--purgeocsp]"
- "\n\n"
- "reread: whack"
- " [--rereadsecrets]"
- " [--rereadcacerts]"
- " [--rereadaacerts]"
- " \\\n "
- " [--rereadocspcerts]"
- " [--rereadacerts]"
- " [--rereadcrls]"
- " [--rereadall]"
- "\n\n"
- "status: whack"
- " [--name <connection_name>] --status|--statusall"
- "\n\n"
- "scdecrypt: whack"
- " --scencrypt|scdecrypt <value>"
- " [--inbase <base>]"
- " [--outbase <base>]"
- " [--keyid <id>]"
- "\n\n"
- "shutdown: whack"
- " --shutdown"
- "\n\n"
- "strongSwan %s\n"
- , ipsec_version_code());
-}
-
-static const char *label = NULL; /* --label operand, saved for diagnostics */
-
-static const char *name = NULL; /* --name operand, saved for diagnostics */
-
-/* print a string as a diagnostic, then exit whack unhappily */
-static void
-diag(const char *mess)
-{
- if (mess != NULL)
- {
- fprintf(stderr, "whack error: ");
- if (label != NULL)
- fprintf(stderr, "%s ", label);
- if (name != NULL)
- fprintf(stderr, "\"%s\" ", name);
- fprintf(stderr, "%s\n", mess);
- }
-
- exit(RC_WHACK_PROBLEM);
-}
-
-/* conditially calls diag; prints second arg, if non-NULL, as quoted string */
-static void
-diagq(err_t ugh, const char *this)
-{
- if (ugh != NULL)
- {
- if (this == NULL)
- {
- diag(ugh);
- }
- else
- {
- char buf[120]; /* arbitrary limit */
-
- snprintf(buf, sizeof(buf), "%s \"%s\"", ugh, this);
- diag(buf);
- }
- }
-}
-
-/* complex combined operands return one of these enumerated values
- * Note: these become flags in an lset_t. Since there are more than
- * 32, we partition them into:
- * - OPT_* options (most random options)
- * - LST_* options (list various internal data)
- * - DBGOPT_* option (DEBUG options)
- * - END_* options (End description options)
- * - CD_* options (Connection Description options)
- * - CA_* options (CA description options)
- */
-enum {
-# define OPT_FIRST OPT_CTLBASE
- OPT_CTLBASE,
- OPT_NAME,
-
- OPT_CD,
-
- OPT_KEYID,
- OPT_ADDKEY,
- OPT_PUBKEYRSA,
-
- OPT_MYID,
-
- OPT_ROUTE,
- OPT_UNROUTE,
-
- OPT_INITIATE,
- OPT_TERMINATE,
- OPT_DELETE,
- OPT_DELETESTATE,
- OPT_LISTEN,
- OPT_UNLISTEN,
-
- OPT_PURGEOCSP,
-
- OPT_REREADSECRETS,
- OPT_REREADCACERTS,
- OPT_REREADAACERTS,
- OPT_REREADOCSPCERTS,
- OPT_REREADACERTS,
- OPT_REREADCRLS,
- OPT_REREADALL,
-
- OPT_STATUS,
- OPT_STATUSALL,
- OPT_SHUTDOWN,
-
- OPT_OPPO_HERE,
- OPT_OPPO_THERE,
-
- OPT_ASYNC,
- OPT_DELETECRASH,
-
-# define OPT_LAST OPT_ASYNC /* last "normal" option */
-
-/* Smartcard options */
-
-# define SC_FIRST SC_ENCRYPT /* first smartcard option */
-
- SC_ENCRYPT,
- SC_DECRYPT,
- SC_INBASE,
- SC_OUTBASE,
-
-# define SC_LAST SC_OUTBASE /* last "smartcard" option */
-
-/* List options */
-
-# define LST_FIRST LST_UTC /* first list option */
- LST_UTC,
- LST_ALGS,
- LST_PUBKEYS,
- LST_CERTS,
- LST_CACERTS,
- LST_ACERTS,
- LST_AACERTS,
- LST_OCSPCERTS,
- LST_GROUPS,
- LST_CAINFOS,
- LST_CRLS,
- LST_OCSP,
- LST_CARDS,
- LST_ALL,
-
-# define LST_LAST LST_ALL /* last list option */
-
-/* Connection End Description options */
-
-# define END_FIRST END_HOST /* first end description */
- END_HOST,
- END_ID,
- END_CERT,
- END_CA,
- END_SENDCERT,
- END_GROUPS,
- END_IKEPORT,
- END_NEXTHOP,
- END_CLIENT,
- END_CLIENTWITHIN,
- END_CLIENTPROTOPORT,
- END_DNSKEYONDEMAND,
- END_SRCIP,
- END_HOSTACCESS,
- END_UPDOWN,
-
-#define END_LAST END_UPDOWN /* last end description*/
-
-/* Connection Description options -- segregated */
-
-# define CD_FIRST CD_TO /* first connection description */
- CD_TO,
-
-# define CD_POLICY_FIRST CD_PSK
- CD_PSK, /* same order as POLICY_* */
- CD_RSASIG, /* same order as POLICY_* */
- CD_ENCRYPT, /* same order as POLICY_* */
- CD_AUTHENTICATE, /* same order as POLICY_* */
- CD_COMPRESS, /* same order as POLICY_* */
- CD_TUNNEL, /* same order as POLICY_* */
- CD_PFS, /* same order as POLICY_* */
- CD_DISABLEARRIVALCHECK, /* same order as POLICY_* */
- CD_SHUNT0, /* same order as POLICY_* */
- CD_SHUNT1, /* same order as POLICY_* */
- CD_FAIL0, /* same order as POLICY_* */
- CD_FAIL1, /* same order as POLICY_* */
- CD_DONT_REKEY, /* same order as POLICY_* */
-
- CD_TUNNELIPV4,
- CD_TUNNELIPV6,
- CD_CONNIPV4,
- CD_CONNIPV6,
-
- CD_IKELIFETIME,
- CD_IPSECLIFETIME,
- CD_RKMARGIN,
- CD_RKFUZZ,
- CD_KTRIES,
- CD_DPDACTION,
- CD_DPDDELAY,
- CD_DPDTIMEOUT,
- CD_IKE,
- CD_PFSGROUP,
- CD_ESP,
-
-# define CD_LAST CD_ESP /* last connection description */
-
-/* Certificate Authority (CA) description options */
-
-# define CA_FIRST CA_NAME /* first ca description */
-
- CA_NAME,
- CA_CERT,
- CA_LDAPHOST,
- CA_LDAPBASE,
- CA_CRLURI,
- CA_CRLURI2,
- CA_OCSPURI,
- CA_STRICT
-
-# define CA_LAST CA_STRICT /* last ca description */
-
-#ifdef DEBUG /* must be last so others are less than 32 to fit in lset_t */
-# define DBGOPT_FIRST DBGOPT_NONE
- ,
- /* NOTE: these definitions must match DBG_* and IMPAIR_* in constants.h */
- DBGOPT_NONE,
- DBGOPT_ALL,
-
- DBGOPT_RAW, /* same order as DBG_* */
- DBGOPT_CRYPT, /* same order as DBG_* */
- DBGOPT_PARSING, /* same order as DBG_* */
- DBGOPT_EMITTING, /* same order as DBG_* */
- DBGOPT_CONTROL, /* same order as DBG_* */
- DBGOPT_LIFECYCLE, /* same order as DBG_* */
- DBGOPT_KLIPS, /* same order as DBG_* */
- DBGOPT_DNS, /* same order as DBG_* */
- DBGOPT_NATT, /* same order as DBG_* */
- DBGOPT_OPPO, /* same order as DBG_* */
- DBGOPT_CONTROLMORE, /* same order as DBG_* */
-
- DBGOPT_PRIVATE, /* same order as DBG_* */
-
- DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_BUST_MI2, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_BUST_MR2 /* same order as IMPAIR_* */
-
-# define DBGOPT_LAST DBGOPT_IMPAIR_BUST_MR2
-#endif
-
-};
-
-/* Carve up space for result from getop_long.
- * Stupidly, the only result is an int.
- * Numeric arg is bit immediately left of basic value.
- *
- */
-#define OPTION_OFFSET 256 /* to get out of the way of letter options */
-#define NUMERIC_ARG (1 << 9) /* expect a numeric argument */
-#define AUX_SHIFT 10 /* amount to shift for aux information */
-
-static const struct option long_opts[] = {
-# define OO OPTION_OFFSET
- /* name, has_arg, flag, val */
-
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "label", required_argument, NULL, 'l' },
-
- { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
- { "name", required_argument, NULL, OPT_NAME + OO },
-
- { "keyid", required_argument, NULL, OPT_KEYID + OO },
- { "addkey", no_argument, NULL, OPT_ADDKEY + OO },
- { "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO },
-
- { "myid", required_argument, NULL, OPT_MYID + OO },
-
- { "route", no_argument, NULL, OPT_ROUTE + OO },
- { "unroute", no_argument, NULL, OPT_UNROUTE + OO },
-
- { "initiate", no_argument, NULL, OPT_INITIATE + OO },
- { "terminate", no_argument, NULL, OPT_TERMINATE + OO },
- { "delete", no_argument, NULL, OPT_DELETE + OO },
- { "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
- { "crash", required_argument, NULL, OPT_DELETECRASH + OO },
- { "listen", no_argument, NULL, OPT_LISTEN + OO },
- { "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
-
- { "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
-
- { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
- { "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
- { "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
- { "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
- { "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
- { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
- { "rereadall", no_argument, NULL, OPT_REREADALL + OO },
- { "status", no_argument, NULL, OPT_STATUS + OO },
- { "statusall", no_argument, NULL, OPT_STATUSALL + OO },
- { "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
-
- { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
- { "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO },
-
- { "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
-
- /* smartcard options */
-
- { "scencrypt", required_argument, NULL, SC_ENCRYPT + OO },
- { "scdecrypt", required_argument, NULL, SC_DECRYPT + OO },
- { "inbase", required_argument, NULL, SC_INBASE + OO },
- { "outbase", required_argument, NULL, SC_OUTBASE + OO },
-
- /* list options */
-
- { "utc", no_argument, NULL, LST_UTC + OO },
- { "listalgs", no_argument, NULL, LST_ALGS + OO },
- { "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
- { "listcerts", no_argument, NULL, LST_CERTS + OO },
- { "listcacerts", no_argument, NULL, LST_CACERTS + OO },
- { "listacerts", no_argument, NULL, LST_ACERTS + OO },
- { "listaacerts", no_argument, NULL, LST_AACERTS + OO },
- { "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
- { "listgroups", no_argument, NULL, LST_GROUPS + OO },
- { "listcainfos", no_argument, NULL, LST_CAINFOS + OO },
- { "listcrls", no_argument, NULL, LST_CRLS + OO },
- { "listocsp", no_argument, NULL, LST_OCSP + OO },
- { "listcards", no_argument, NULL, LST_CARDS + OO },
- { "listall", no_argument, NULL, LST_ALL + OO },
-
- /* options for an end description */
-
- { "host", required_argument, NULL, END_HOST + OO },
- { "id", required_argument, NULL, END_ID + OO },
- { "cert", required_argument, NULL, END_CERT + OO },
- { "ca", required_argument, NULL, END_CA + OO },
- { "sendcert", required_argument, NULL, END_SENDCERT + OO },
- { "groups", required_argument, NULL, END_GROUPS + OO },
- { "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
- { "nexthop", required_argument, NULL, END_NEXTHOP + OO },
- { "client", required_argument, NULL, END_CLIENT + OO },
- { "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
- { "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
- { "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
- { "srcip", required_argument, NULL, END_SRCIP + OO },
- { "hostaccess", no_argument, NULL, END_HOSTACCESS + OO },
- { "updown", required_argument, NULL, END_UPDOWN + OO },
-
- /* options for a connection description */
-
- { "to", no_argument, NULL, CD_TO + OO },
-
- { "psk", no_argument, NULL, CD_PSK + OO },
- { "rsasig", no_argument, NULL, CD_RSASIG + OO },
-
- { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
- { "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
- { "compress", no_argument, NULL, CD_COMPRESS + OO },
- { "tunnel", no_argument, NULL, CD_TUNNEL + OO },
- { "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
- { "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
- { "pfs", no_argument, NULL, CD_PFS + OO },
- { "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
- { "initiateontraffic", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "pass", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "drop", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "reject", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "failnone", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "failpass", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "faildrop", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "failreject", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
- { "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
- { "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
-
- { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
- { "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
- { "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
- { "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
- { "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
- { "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
- { "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
- { "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
- { "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
- { "ike", required_argument, NULL, CD_IKE + OO },
- { "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
- { "esp", required_argument, NULL, CD_ESP + OO },
-
- /* options for a ca description */
-
- { "caname", required_argument, NULL, CA_NAME + OO },
- { "cacert", required_argument, NULL, CA_CERT + OO },
- { "ldaphost", required_argument, NULL, CA_LDAPHOST + OO },
- { "ldapbase", required_argument, NULL, CA_LDAPBASE + OO },
- { "crluri", required_argument, NULL, CA_CRLURI + OO },
- { "crluri2", required_argument, NULL, CA_CRLURI2 + OO },
- { "ocspuri", required_argument, NULL, CA_OCSPURI + OO },
- { "strictcrlpolicy", no_argument, NULL, CA_STRICT + OO },
-
-#ifdef DEBUG
- { "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
- { "debug-all]", no_argument, NULL, DBGOPT_ALL + OO },
- { "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
- { "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
- { "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
- { "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
- { "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
- { "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
- { "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
- { "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
- { "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
- { "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
- { "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
- { "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
-
- { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
- { "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
- { "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
- { "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
-#endif
-# undef OO
- { 0,0,0,0 }
-};
-
-struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
-
-/* helper variables and function to encode strings from whack message */
-
-static char
- *next_str,
- *str_roof;
-
-static bool
-pack_str(char **p)
-{
- const char *s = *p == NULL? "" : *p; /* note: NULL becomes ""! */
- size_t len = strlen(s) + 1;
-
- if (str_roof - next_str < (ptrdiff_t)len)
- {
- return FALSE; /* fishy: no end found */
- }
- else
- {
- strcpy(next_str, s);
- next_str += len;
- *p = NULL; /* don't send pointers on the wire! */
- return TRUE;
- }
-}
-
-static void
-check_life_time(time_t life, time_t limit, const char *which
-, const whack_message_t *msg)
-{
- time_t mint = msg->sa_rekey_margin * (100 + msg->sa_rekey_fuzz) / 100;
-
- if (life > limit)
- {
- char buf[200]; /* arbitrary limit */
-
- snprintf(buf, sizeof(buf)
- , "%s [%lu seconds] must be less than %lu seconds"
- , which, (unsigned long)life, (unsigned long)limit);
- diag(buf);
- }
- if ((msg->policy & POLICY_DONT_REKEY) == LEMPTY && life <= mint)
- {
- char buf[200]; /* arbitrary limit */
-
- snprintf(buf, sizeof(buf)
- , "%s [%lu] must be greater than"
- " rekeymargin*(100+rekeyfuzz)/100 [%lu*(100+%lu)/100 = %lu]"
- , which
- , (unsigned long)life
- , (unsigned long)msg->sa_rekey_margin
- , (unsigned long)msg->sa_rekey_fuzz
- , (unsigned long)mint);
- diag(buf);
- }
-}
-
-static void
-clear_end(whack_end_t *e)
-{
- zero(e);
- e->id = NULL;
- e->cert = NULL;
- e->ca = NULL;
- e->updown = NULL;
- e->host_port = IKE_UDP_PORT;
-}
-
-static void
-update_ports(whack_message_t *m)
-{
- int port;
-
- if (m->left.port != 0) {
- port = htons(m->left.port);
- setportof(port, &m->left.host_addr);
- setportof(port, &m->left.client.addr);
- }
- if (m->right.port != 0) {
- port = htons(m->right.port);
- setportof(port, &m->right.host_addr);
- setportof(port, &m->right.client.addr);
- }
-}
-
-static void
-check_end(whack_end_t *this, whack_end_t *that
-, bool default_nexthop, sa_family_t caf, sa_family_t taf)
-{
- if (caf != addrtypeof(&this->host_addr))
- diag("address family of host inconsistent");
-
- if (default_nexthop)
- {
- if (isanyaddr(&that->host_addr))
- diag("our nexthop must be specified when other host is a %any or %opportunistic");
- this->host_nexthop = that->host_addr;
- }
-
- if (caf != addrtypeof(&this->host_nexthop))
- diag("address family of nexthop inconsistent");
-
- if (this->has_client)
- {
- if (taf != subnettypeof(&this->client))
- diag("address family of client subnet inconsistent");
- }
- else
- {
- /* fill in anyaddr-anyaddr as (missing) client subnet */
- ip_address cn;
-
- diagq(anyaddr(caf, &cn), NULL);
- diagq(rangetosubnet(&cn, &cn, &this->client), NULL);
- }
-
- /* fill in anyaddr if source IP is not defined */
- if (!this->has_srcip)
- diagq(anyaddr(caf, &this->host_srcip), optarg);
-
- /* check protocol */
- if (this->protocol != that->protocol)
- diag("the protocol for leftprotoport and rightprotoport must be the same");
-}
-
-static void
-get_secret(int sock)
-{
- const char *buf, *secret;
- int len;
-
- fflush(stdout);
- usleep(20000); /* give fflush time for flushing */
- buf = getpass("Enter: ");
- secret = (buf == NULL)? "" : buf;
-
- /* send the secret to pluto */
- len = strlen(secret) + 1;
- if (write(sock, secret, len) != len)
- {
- int e = errno;
-
- fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
-}
-
-/* This is a hack for initiating ISAKMP exchanges. */
-
-int
-main(int argc, char **argv)
-{
- whack_message_t msg;
- char esp_buf[256]; /* uses snprintf */
- lset_t
- opts_seen = LEMPTY,
- sc_seen = LEMPTY,
- lst_seen = LEMPTY,
- cd_seen = LEMPTY,
- ca_seen = LEMPTY,
- end_seen = LEMPTY,
- end_seen_before_to = LEMPTY;
- const char
- *af_used_by = NULL,
- *tunnel_af_used_by = NULL;
-
- /* check division of numbering space */
-#ifdef DEBUG
- assert(OPTION_OFFSET + DBGOPT_LAST < NUMERIC_ARG);
-#else
- assert(OPTION_OFFSET + CA_LAST < NUMERIC_ARG);
-#endif
- assert(OPT_LAST - OPT_FIRST < (sizeof opts_seen * BITS_PER_BYTE));
- assert(SC_LAST - SC_FIRST < (sizeof sc_seen * BITS_PER_BYTE));
- assert(LST_LAST - LST_FIRST < (sizeof lst_seen * BITS_PER_BYTE));
- assert(END_LAST - END_FIRST < (sizeof end_seen * BITS_PER_BYTE));
- assert(CD_LAST - CD_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
- assert(CA_LAST - CA_FIRST < (sizeof ca_seen * BITS_PER_BYTE));
-#ifdef DEBUG /* must be last so others are less than (sizeof cd_seen * BITS_PER_BYTE) to fit in lset_t */
- assert(DBGOPT_LAST - DBGOPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
-#endif
- /* check that POLICY bit assignment matches with CD_ */
- assert(LELEM(CD_DONT_REKEY - CD_POLICY_FIRST) == POLICY_DONT_REKEY);
-
- zero(&msg);
-
- clear_end(&msg.right); /* left set from this after --to */
-
- msg.name = NULL;
- msg.keyid = NULL;
- msg.keyval.ptr = NULL;
- msg.esp = NULL;
- msg.ike = NULL;
- msg.pfsgroup = NULL;
-
- msg.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
- msg.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
- msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
- msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
- msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
-
- msg.addr_family = AF_INET;
- msg.tunnel_addr_family = AF_INET;
-
- msg.cacert = NULL;
- msg.ldaphost = NULL;
- msg.ldapbase = NULL;
- msg.crluri = NULL;
- msg.crluri2 = NULL;
- msg.ocspuri = NULL;
-
- for (;;)
- {
- int long_index;
- unsigned long opt_whole = 0; /* numeric argument for some flags */
-
- /* Note: we don't like the way short options get parsed
- * by getopt_long, so we simply pass an empty string as
- * the list. It could be "hp:d:c:o:eatfs" "NARXPECK".
- */
- int c = getopt_long(argc, argv, "", long_opts, &long_index) - OPTION_OFFSET;
- int aux = 0;
-
- /* decode a numeric argument, if expected */
- if (0 <= c)
- {
- if (c & NUMERIC_ARG)
- {
- char *endptr;
-
- c -= NUMERIC_ARG;
- opt_whole = strtoul(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg)
- diagq("badly formed numeric argument", optarg);
- }
- if (c >= (1 << AUX_SHIFT))
- {
- aux = c >> AUX_SHIFT;
- c -= aux << AUX_SHIFT;
- }
- }
-
- /* per-class option processing */
- if (0 <= c && c <= OPT_LAST)
- {
- /* OPT_* options get added to opts_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c);
-
- if (opts_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- opts_seen |= f;
- }
- else if (SC_FIRST <= c && c <= SC_LAST)
- {
- /* SC_* options get added to sc_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - SC_FIRST);
-
- if (sc_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- sc_seen |= f;
- }
- else if (LST_FIRST <= c && c <= LST_LAST)
- {
- /* LST_* options get added to lst_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - LST_FIRST);
-
- if (lst_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- lst_seen |= f;
- }
-#ifdef DEBUG
- else if (DBGOPT_FIRST <= c && c <= DBGOPT_LAST)
- {
- msg.whack_options = TRUE;
- }
-#endif
- else if (END_FIRST <= c && c <= END_LAST)
- {
- /* END_* options are added to end_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - END_FIRST);
-
- if (end_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- end_seen |= f;
- opts_seen |= LELEM(OPT_CD);
- }
- else if (CD_FIRST <= c && c <= CD_LAST)
- {
- /* CD_* options are added to cd_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - CD_FIRST);
-
- if (cd_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- cd_seen |= f;
- opts_seen |= LELEM(OPT_CD);
- }
- else if (CA_FIRST <= c && c <= CA_LAST)
- {
- /* CA_* options are added to ca_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - CA_FIRST);
-
- if (ca_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- ca_seen |= f;
- }
-
- /* Note: "break"ing from switch terminates loop.
- * most cases should end with "continue".
- */
- switch (c)
- {
- case EOF - OPTION_OFFSET: /* end of flags */
- break;
-
- case 0 - OPTION_OFFSET: /* long option already handled */
- continue;
-
- case ':' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
- case '?' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
- diag(NULL); /* print no additional diagnostic, but exit sadly */
- break; /* not actually reached */
-
- case 'h' - OPTION_OFFSET: /* --help */
- help();
- return 0; /* GNU coding standards say to stop here */
-
- case 'v' - OPTION_OFFSET: /* --version */
- {
- const char **sp = ipsec_copyright_notice();
-
- printf("%s\n", ipsec_version_string());
- for (; *sp != NULL; sp++)
- puts(*sp);
- }
- return 0; /* GNU coding standards say to stop here */
-
- case 'l' - OPTION_OFFSET: /* --label <string> */
- label = optarg; /* remember for diagnostics */
- continue;
-
- case '+' - OPTION_OFFSET: /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- /* the rest of the options combine in complex ways */
-
- case OPT_CTLBASE: /* --port <ctlbase> */
- if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
- , "%s%s", optarg, CTL_SUFFIX) == -1)
- diag("<ctlbase>" CTL_SUFFIX " must be fit in a sun_addr");
- continue;
-
- case OPT_NAME: /* --name <connection-name> */
- name = optarg;
- msg.name = optarg;
- continue;
-
- case OPT_KEYID: /* --keyid <identity> */
- msg.whack_key = !msg.whack_sc_op;
- msg.keyid = optarg; /* decoded by Pluto */
- continue;
-
- case OPT_MYID: /* --myid <identity> */
- msg.whack_myid = TRUE;
- msg.myid = optarg; /* decoded by Pluto */
- continue;
-
- case OPT_ADDKEY: /* --addkey */
- msg.whack_addkey = TRUE;
- continue;
-
- case OPT_PUBKEYRSA: /* --pubkeyrsa <key> */
- {
- static char keyspace[RSA_MAX_ENCODING_BYTES]; /* room for 8K bit key */
- char diag_space[TTODATAV_BUF];
- const char *ugh = ttodatav(optarg, 0, 0
- , keyspace, sizeof(keyspace)
- , &msg.keyval.len, diag_space, sizeof(diag_space)
- , TTODATAV_SPACECOUNTS);
-
- if (ugh != NULL)
- {
- char ugh_space[80]; /* perhaps enough space */
-
- snprintf(ugh_space, sizeof(ugh_space)
- , "RSA public-key data malformed (%s)", ugh);
- diagq(ugh_space, optarg);
- }
- msg.pubkey_alg = PUBKEY_ALG_RSA;
- msg.keyval.ptr = keyspace;
- }
- continue;
-
- case OPT_ROUTE: /* --route */
- msg.whack_route = TRUE;
- continue;
-
- case OPT_UNROUTE: /* --unroute */
- msg.whack_unroute = TRUE;
- continue;
-
- case OPT_INITIATE: /* --initiate */
- msg.whack_initiate = TRUE;
- continue;
-
- case OPT_TERMINATE: /* --terminate */
- msg.whack_terminate = TRUE;
- continue;
-
- case OPT_DELETE: /* --delete */
- msg.whack_delete = TRUE;
- continue;
-
- case OPT_DELETESTATE: /* --deletestate <state_object_number> */
- msg.whack_deletestate = TRUE;
- msg.whack_deletestateno = opt_whole;
- continue;
-
- case OPT_DELETECRASH: /* --crash <ip-address> */
- msg.whack_crash = TRUE;
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.whack_crash_peer), optarg);
- if (isanyaddr(&msg.whack_crash_peer))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_LISTEN: /* --listen */
- msg.whack_listen = TRUE;
- continue;
-
- case OPT_UNLISTEN: /* --unlisten */
- msg.whack_unlisten = TRUE;
- continue;
-
- case OPT_PURGEOCSP: /* --purgeocsp */
- msg.whack_purgeocsp = TRUE;
- continue;
-
- case OPT_REREADSECRETS: /* --rereadsecrets */
- case OPT_REREADCACERTS: /* --rereadcacerts */
- case OPT_REREADAACERTS: /* --rereadaacerts */
- case OPT_REREADOCSPCERTS: /* --rereadocspcerts */
- case OPT_REREADACERTS: /* --rereadacerts */
- case OPT_REREADCRLS: /* --rereadcrls */
- msg.whack_reread |= LELEM(c-OPT_REREADSECRETS);
- continue;
-
- case OPT_REREADALL: /* --rereadall */
- msg.whack_reread = REREAD_ALL;
- continue;
-
- case OPT_STATUSALL: /* --statusall */
- msg.whack_statusall = TRUE;
-
- case OPT_STATUS: /* --status */
- msg.whack_status = TRUE;
- continue;
-
- case OPT_SHUTDOWN: /* --shutdown */
- msg.whack_shutdown = TRUE;
- continue;
-
- case OPT_OPPO_HERE: /* --oppohere <ip-address> */
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_my_client), optarg);
- if (isanyaddr(&msg.oppo_my_client))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_OPPO_THERE: /* --oppohere <ip-address> */
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_peer_client), optarg);
- if (isanyaddr(&msg.oppo_peer_client))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_ASYNC:
- msg.whack_async = TRUE;
- continue;
-
- /* Smartcard options */
-
- case SC_ENCRYPT: /* --scencrypt <plaintext data> */
- case SC_DECRYPT: /* --scdecrypt <encrypted data> */
- msg.whack_sc_op = 1 + c - SC_ENCRYPT;
- msg.whack_key = FALSE;
- msg.sc_data = optarg;
- continue;
-
- case SC_INBASE: /* --inform <format> */
- case SC_OUTBASE: /* --outform <format> */
- {
- int base = 0;
-
- if (streq(optarg, "16") || strcaseeq(optarg, "hex"))
- base = 16;
- else if (streq(optarg, "64") || strcaseeq(optarg, "base64"))
- base = 64;
- else if (streq(optarg, "256") || strcaseeq(optarg, "text")
- || strcaseeq(optarg, "ascii"))
- base = 256;
- else
- diagq("not a valid base", optarg);
-
- if (c == SC_INBASE)
- msg.inbase = base;
- else
- msg.outbase = base;
- }
- continue;
-
- /* List options */
-
- case LST_UTC: /* --utc */
- msg.whack_utc = TRUE;
- continue;
-
- case LST_ALGS: /* --listalgs */
- case LST_PUBKEYS: /* --listpubkeys */
- case LST_CERTS: /* --listcerts */
- case LST_CACERTS: /* --listcacerts */
- case LST_ACERTS: /* --listacerts */
- case LST_AACERTS: /* --listaacerts */
- case LST_OCSPCERTS: /* --listocspcerts */
- case LST_GROUPS: /* --listgroups */
- case LST_CAINFOS: /* --listcainfos */
- case LST_CRLS: /* --listcrls */
- case LST_OCSP: /* --listocsp */
- case LST_CARDS: /* --listcards */
- msg.whack_list |= LELEM(c - LST_ALGS);
- continue;
-
- case LST_ALL: /* --listall */
- msg.whack_list = LIST_ALL;
- continue;
-
- /* Connection Description options */
-
- case END_HOST: /* --host <ip-address> */
- {
- lset_t new_policy = LEMPTY;
-
- af_used_by = long_opts[long_index].name;
- diagq(anyaddr(msg.addr_family, &msg.right.host_addr), optarg);
- if (streq(optarg, "%any"))
- {
- }
- else if (streq(optarg, "%opportunistic"))
- {
- /* always use tunnel mode; mark as opportunistic */
- new_policy |= POLICY_TUNNEL | POLICY_OPPO;
- }
- else if (streq(optarg, "%group"))
- {
- /* always use tunnel mode; mark as group */
- new_policy |= POLICY_TUNNEL | POLICY_GROUP;
- }
- else if (streq(optarg, "%opportunisticgroup"))
- {
- /* always use tunnel mode; mark as opportunistic */
- new_policy |= POLICY_TUNNEL | POLICY_OPPO | POLICY_GROUP;
- }
- else
- {
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_addr), optarg);
- }
-
- msg.policy |= new_policy;
-
- if (new_policy & (POLICY_OPPO | POLICY_GROUP))
- {
- if (!LHAS(end_seen, END_CLIENT - END_FIRST))
- {
- /* set host to 0.0.0 and --client to 0.0.0.0/0
- * or IPV6 equivalent
- */
- ip_address any;
-
- tunnel_af_used_by = optarg;
- diagq(anyaddr(msg.tunnel_addr_family, &any), optarg);
- diagq(initsubnet(&any, 0, '0', &msg.right.client), optarg);
- }
- msg.right.has_client = TRUE;
- }
- if (new_policy & POLICY_GROUP)
- {
- /* client subnet must not be specified by user:
- * it will come from the group's file.
- */
- if (LHAS(end_seen, END_CLIENT - END_FIRST))
- diag("--host %group clashes with --client");
-
- end_seen |= LELEM(END_CLIENT - END_FIRST);
- }
- if (new_policy & POLICY_OPPO)
- msg.right.key_from_DNS_on_demand = TRUE;
- continue;
- }
- case END_ID: /* --id <identity> */
- msg.right.id = optarg; /* decoded by Pluto */
- continue;
-
- case END_CERT: /* --cert <path> */
- msg.right.cert = optarg; /* decoded by Pluto */
- continue;
-
- case END_CA: /* --ca <distinguished name> */
- msg.right.ca = optarg; /* decoded by Pluto */
- continue;
-
- case END_SENDCERT:
- if (streq(optarg, "yes") || streq(optarg, "always"))
- {
- msg.right.sendcert = CERT_ALWAYS_SEND;
- }
- else if (streq(optarg, "no") || streq(optarg, "never"))
- {
- msg.right.sendcert = CERT_NEVER_SEND;
- }
- else if (streq(optarg, "ifasked"))
- {
- msg.right.sendcert = CERT_SEND_IF_ASKED;
- }
- else
- {
- diagq("whack sendcert value is not legal", optarg);
- }
- continue;
-
- case END_GROUPS:/* --groups <access control groups> */
- msg.right.groups = optarg; /* decoded by Pluto */
- continue;
-
- case END_IKEPORT: /* --ikeport <port-number> */
- if (opt_whole<=0 || opt_whole >= 0x10000)
- diagq("<port-number> must be a number between 1 and 65535", optarg);
- msg.right.host_port = opt_whole;
- continue;
-
- case END_NEXTHOP: /* --nexthop <ip-address> */
- af_used_by = long_opts[long_index].name;
- if (streq(optarg, "%direct"))
- diagq(anyaddr(msg.addr_family
- , &msg.right.host_nexthop), optarg);
- else
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_nexthop), optarg);
- continue;
-
- case END_SRCIP: /* --srcip <ip-address> */
- af_used_by = long_opts[long_index].name;
- if (streq(optarg, "%modeconfig") || streq(optarg, "%modecfg"))
- {
- msg.right.modecfg = TRUE;
- }
- else
- {
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_srcip), optarg);
- msg.right.has_srcip = TRUE;
- }
- msg.policy |= POLICY_TUNNEL; /* srcip => tunnel */
- continue;
-
- case END_CLIENT: /* --client <subnet> */
- if (end_seen & LELEM(END_CLIENTWITHIN - END_FIRST))
- diag("--client conflicts with --clientwithin");
- tunnel_af_used_by = long_opts[long_index].name;
-#ifdef VIRTUAL_IP
- if ((strlen(optarg) >= 6 && strncmp(optarg,"vhost:",6) == 0)
- || (strlen(optarg) >= 5 && strncmp(optarg,"vnet:",5) == 0))
- {
- msg.right.virt = optarg;
- }
- else
- {
- diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
- msg.right.has_client = TRUE;
- }
-#else
- diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
- msg.right.has_client = TRUE;
-#endif
- msg.policy |= POLICY_TUNNEL; /* client => tunnel */
- continue;
-
- case END_CLIENTWITHIN: /* --clienwithin <address range> */
- if (end_seen & LELEM(END_CLIENT - END_FIRST))
- diag("--clientwithin conflicts with --client");
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
- msg.right.has_client = TRUE;
- msg.policy |= POLICY_TUNNEL; /* client => tunnel */
- msg.right.has_client_wildcard = TRUE;
- continue;
-
- case END_CLIENTPROTOPORT: /* --clientprotoport <protocol>/<port> */
- diagq(ttoprotoport(optarg, 0, &msg.right.protocol, &msg.right.port
- , &msg.right.has_port_wildcard), optarg);
- continue;
-
- case END_DNSKEYONDEMAND: /* --dnskeyondemand */
- msg.right.key_from_DNS_on_demand = TRUE;
- continue;
-
- case END_HOSTACCESS: /* --hostaccess */
- msg.right.hostaccess = TRUE;
- continue;
-
- case END_UPDOWN: /* --updown <updown> */
- msg.right.updown = optarg;
- continue;
-
- case CD_TO: /* --to */
- /* process right end, move it to left, reset it */
- if (!LHAS(end_seen, END_HOST - END_FIRST))
- diag("connection missing --host before --to");
- msg.left = msg.right;
- clear_end(&msg.right);
- end_seen_before_to = end_seen;
- end_seen = LEMPTY;
- continue;
-
- case CD_PSK: /* --psk */
- case CD_RSASIG: /* --rsasig */
- case CD_ENCRYPT: /* --encrypt */
- case CD_AUTHENTICATE: /* --authenticate */
- case CD_COMPRESS: /* --compress */
- case CD_TUNNEL: /* --tunnel */
- case CD_PFS: /* --pfs */
- case CD_DISABLEARRIVALCHECK: /* --disablearrivalcheck */
- case CD_DONT_REKEY: /* --donotrekey */
- msg.policy |= LELEM(c - CD_POLICY_FIRST);
- continue;
-
- /* --initiateontraffic
- * --pass
- * --drop
- * --reject
- */
- case CD_SHUNT0:
- msg.policy = (msg.policy & ~POLICY_SHUNT_MASK)
- | ((lset_t)aux << POLICY_SHUNT_SHIFT);
- continue;
-
- /* --failnone
- * --failpass
- * --faildrop
- * --failreject
- */
- case CD_FAIL0:
- msg.policy = (msg.policy & ~POLICY_FAIL_MASK)
- | ((lset_t)aux << POLICY_FAIL_SHIFT);
- continue;
-
- case CD_IKELIFETIME: /* --ikelifetime <seconds> */
- msg.sa_ike_life_seconds = opt_whole;
- continue;
-
- case CD_IPSECLIFETIME: /* --ipseclifetime <seconds> */
- msg.sa_ipsec_life_seconds = opt_whole;
- continue;
-
- case CD_RKMARGIN: /* --rekeymargin <seconds> */
- msg.sa_rekey_margin = opt_whole;
- continue;
-
- case CD_RKFUZZ: /* --rekeyfuzz <percentage> */
- msg.sa_rekey_fuzz = opt_whole;
- continue;
-
- case CD_KTRIES: /* --keyingtries <count> */
- msg.sa_keying_tries = opt_whole;
- continue;
-
- case CD_DPDACTION:
- if (streq(optarg, "none"))
- msg.dpd_action = DPD_ACTION_NONE;
- else if (streq(optarg, "clear"))
- msg.dpd_action = DPD_ACTION_CLEAR;
- else if (streq(optarg, "hold"))
- msg.dpd_action = DPD_ACTION_HOLD;
- else if (streq(optarg, "restart"))
- msg.dpd_action = DPD_ACTION_RESTART;
- else
- msg.dpd_action = DPD_ACTION_UNKNOWN;
- continue;
-
- case CD_DPDDELAY:
- msg.dpd_delay = opt_whole;
- continue;
-
- case CD_DPDTIMEOUT:
- msg.dpd_timeout = opt_whole;
- continue;
-
- case CD_IKE: /* --ike <ike_alg1,ike_alg2,...> */
- msg.ike = optarg;
- continue;
-
- case CD_PFSGROUP: /* --pfsgroup modpXXXX */
- msg.pfsgroup = optarg;
- continue;
-
- case CD_ESP: /* --esp <esp_alg1,esp_alg2,...> */
- msg.esp = optarg;
- continue;
-
- case CD_CONNIPV4:
- if (LHAS(cd_seen, CD_CONNIPV6 - CD_FIRST))
- diag("--ipv4 conflicts with --ipv6");
-
- /* Since this is the default, the flag is redundant.
- * So we don't need to set msg.addr_family
- * and we don't need to check af_used_by
- * and we don't have to consider defaulting tunnel_addr_family.
- */
- continue;
-
- case CD_CONNIPV6:
- if (LHAS(cd_seen, CD_CONNIPV4 - CD_FIRST))
- diag("--ipv6 conflicts with --ipv4");
-
- if (af_used_by != NULL)
- diagq("--ipv6 must precede", af_used_by);
-
- af_used_by = long_opts[long_index].name;
- msg.addr_family = AF_INET6;
-
- /* Consider defaulting tunnel_addr_family to AF_INET6.
- * Do so only if it hasn't yet been specified or used.
- */
- if (LDISJOINT(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST))
- && tunnel_af_used_by == NULL)
- msg.tunnel_addr_family = AF_INET6;
- continue;
-
- case CD_TUNNELIPV4:
- if (LHAS(cd_seen, CD_TUNNELIPV6 - CD_FIRST))
- diag("--tunnelipv4 conflicts with --tunnelipv6");
-
- if (tunnel_af_used_by != NULL)
- diagq("--tunnelipv4 must precede", af_used_by);
-
- msg.tunnel_addr_family = AF_INET;
- continue;
-
- case CD_TUNNELIPV6:
- if (LHAS(cd_seen, CD_TUNNELIPV4 - CD_FIRST))
- diag("--tunnelipv6 conflicts with --tunnelipv4");
-
- if (tunnel_af_used_by != NULL)
- diagq("--tunnelipv6 must precede", af_used_by);
-
- msg.tunnel_addr_family = AF_INET6;
- continue;
-
- case CA_NAME: /* --caname <name> */
- msg.name = optarg;
- msg.whack_ca = TRUE;
- continue;
- case CA_CERT: /* --cacert <path> */
- msg.cacert = optarg;
- continue;
- case CA_LDAPHOST: /* --ldaphost <hostname> */
- msg.ldaphost = optarg;
- continue;
- case CA_LDAPBASE: /* --ldapbase <base> */
- msg.ldapbase = optarg;
- continue;
- case CA_CRLURI: /* --crluri <uri> */
- msg.crluri = optarg;
- continue;
- case CA_CRLURI2: /* --crluri2 <uri> */
- msg.crluri2 = optarg;
- continue;
- case CA_OCSPURI: /* --ocspuri <uri> */
- msg.ocspuri = optarg;
- continue;
- case CA_STRICT: /* --strictcrlpolicy */
- msg.whack_strict = TRUE;
- continue;
-
-#ifdef DEBUG
- case DBGOPT_NONE: /* --debug-none */
- msg.debugging = DBG_NONE;
- continue;
-
- case DBGOPT_ALL: /* --debug-all */
- msg.debugging |= DBG_ALL; /* note: does not include PRIVATE */
- continue;
-
- case DBGOPT_RAW: /* --debug-raw */
- case DBGOPT_CRYPT: /* --debug-crypt */
- case DBGOPT_PARSING: /* --debug-parsing */
- case DBGOPT_EMITTING: /* --debug-emitting */
- case DBGOPT_CONTROL: /* --debug-control */
- case DBGOPT_LIFECYCLE: /* --debug-lifecycle */
- case DBGOPT_KLIPS: /* --debug-klips */
- case DBGOPT_DNS: /* --debug-dns */
- case DBGOPT_NATT: /* --debug-natt */
- case DBGOPT_OPPO: /* --debug-oppo */
- case DBGOPT_CONTROLMORE: /* --debug-controlmore */
- case DBGOPT_PRIVATE: /* --debug-private */
- case DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER: /* --impair-delay-adns-key-answer */
- case DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER: /* --impair-delay-adns-txt-answer */
- case DBGOPT_IMPAIR_BUST_MI2: /* --impair_bust_mi2 */
- case DBGOPT_IMPAIR_BUST_MR2: /* --impair_bust_mr2 */
- msg.debugging |= LELEM(c-DBGOPT_RAW);
- continue;
-#endif
- default:
- assert(FALSE); /* unknown return value */
- }
- break;
- }
-
- if (optind != argc)
- {
- /* If you see this message unexpectedly, perhaps the
- * case for the previous option ended with "break"
- * instead of "continue"
- */
- diagq("unexpected argument", argv[optind]);
- }
-
- /* For each possible form of the command, figure out if an argument
- * suggests whether that form was intended, and if so, whether all
- * required information was supplied.
- */
-
- /* check opportunistic initiation simulation request */
- switch (opts_seen & (LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE)))
- {
- case LELEM(OPT_OPPO_HERE):
- case LELEM(OPT_OPPO_THERE):
- diag("--oppohere and --oppothere must be used together");
- /*NOTREACHED*/
- case LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE):
- msg.whack_oppo_initiate = TRUE;
- if (LIN(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST)))
- opts_seen &= ~LELEM(OPT_CD);
- break;
- }
-
- /* check connection description */
- if (LHAS(opts_seen, OPT_CD))
- {
- if (!LHAS(cd_seen, CD_TO-CD_FIRST))
- diag("connection description option, but no --to");
-
- if (!LHAS(end_seen, END_HOST-END_FIRST))
- diag("connection missing --host after --to");
-
- if (isanyaddr(&msg.left.host_addr)
- && isanyaddr(&msg.right.host_addr))
- diag("hosts cannot both be 0.0.0.0 or 0::0");
-
- if (msg.policy & POLICY_OPPO)
- {
- if ((msg.policy & (POLICY_PSK | POLICY_RSASIG)) != POLICY_RSASIG)
- diag("only RSASIG is supported for opportunism");
- if ((msg.policy & POLICY_PFS) == 0)
- diag("PFS required for opportunism");
- if ((msg.policy & POLICY_ENCRYPT) == 0)
- diag("encryption required for opportunism");
- }
-
- check_end(&msg.left, &msg.right, !LHAS(end_seen_before_to, END_NEXTHOP-END_FIRST)
- , msg.addr_family, msg.tunnel_addr_family);
-
- check_end(&msg.right, &msg.left, !LHAS(end_seen, END_NEXTHOP-END_FIRST)
- , msg.addr_family, msg.tunnel_addr_family);
-
- if (subnettypeof(&msg.left.client) != subnettypeof(&msg.right.client))
- diag("endpoints clash: one is IPv4 and the other is IPv6");
-
- if (NEVER_NEGOTIATE(msg.policy))
- {
- /* we think this is just a shunt (because he didn't specify
- * a host authentication method). If he didn't specify a
- * shunt type, he's probably gotten it wrong.
- */
- if ((msg.policy & POLICY_SHUNT_MASK) == POLICY_SHUNT_TRAP)
- diag("non-shunt connection must have --psk or --rsasig or both");
- }
- else
- {
- /* not just a shunt: a real ipsec connection */
- if ((msg.policy & POLICY_ID_AUTH_MASK) == LEMPTY)
- diag("must specify --rsasig or --psk for a connection");
-
- if (!HAS_IPSEC_POLICY(msg.policy)
- && (msg.left.has_client || msg.right.has_client))
- diag("must not specify clients for ISAKMP-only connection");
- }
-
- msg.whack_connection = TRUE;
- }
-
- /* decide whether --name is mandatory or forbidden */
- if (!LDISJOINT(opts_seen
- , LELEM(OPT_ROUTE) | LELEM(OPT_UNROUTE)
- | LELEM(OPT_INITIATE) | LELEM(OPT_TERMINATE)
- | LELEM(OPT_DELETE) | LELEM(OPT_CD)))
- {
- if (!LHAS(opts_seen, OPT_NAME) && !msg.whack_ca)
- diag("missing --name <connection_name>");
- }
- else if (!msg.whack_options && !msg.whack_status)
- {
- if (LHAS(opts_seen, OPT_NAME))
- diag("no reason for --name");
- }
-
- if (!LDISJOINT(opts_seen, LELEM(OPT_PUBKEYRSA) | LELEM(OPT_ADDKEY)))
- {
- if (!LHAS(opts_seen, OPT_KEYID))
- diag("--addkey and --pubkeyrsa require --keyid");
- }
-
- if (!(msg.whack_connection || msg.whack_key || msg.whack_myid
- || msg.whack_delete || msg.whack_deletestate
- || msg.whack_initiate || msg.whack_oppo_initiate || msg.whack_terminate
- || msg.whack_route || msg.whack_unroute || msg.whack_listen
- || msg.whack_unlisten || msg.whack_list || msg.whack_purgeocsp || msg.whack_reread
- || msg.whack_ca || msg.whack_status || msg.whack_options || msg.whack_shutdown
- || msg.whack_sc_op))
- {
- diag("no action specified; try --help for hints");
- }
-
- update_ports(&msg);
-
- /* tricky quick and dirty check for wild values */
- if (msg.sa_rekey_margin != 0
- && msg.sa_rekey_fuzz * msg.sa_rekey_margin * 4 / msg.sa_rekey_margin / 4
- != msg.sa_rekey_fuzz)
- diag("rekeymargin or rekeyfuzz values are so large that they cause oveflow");
-
- check_life_time (msg.sa_ike_life_seconds, OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM
- , "ikelifetime", &msg);
-
- check_life_time(msg.sa_ipsec_life_seconds, SA_LIFE_DURATION_MAXIMUM
- , "ipseclifetime", &msg);
-
- if (msg.dpd_action == DPD_ACTION_UNKNOWN)
- diag("dpdaction must be \"none\", \"clear\", \"hold\" or \"restart\"");
-
- if (msg.dpd_action != DPD_ACTION_NONE)
- {
- if (msg.dpd_delay <= 0)
- diag("dpddelay must be larger than zero");
-
- if (msg.dpd_timeout <= 0)
- diag("dpdtimeout must be larger than zero");
-
- if (msg.dpd_timeout <= msg.dpd_delay)
- diag("dpdtimeout must be larger than dpddelay");
- }
-
- /* pack strings for inclusion in message */
- next_str = msg.string;
- str_roof = &msg.string[sizeof(msg.string)];
-
- /* build esp message as esp="<esp>;<pfsgroup>" */
- if (msg.pfsgroup) {
- snprintf(esp_buf, sizeof (esp_buf), "%s;%s",
- msg.esp ? msg.esp : "",
- msg.pfsgroup ? msg.pfsgroup : "");
- msg.esp=esp_buf;
- }
- if (!pack_str(&msg.name) /* string 1 */
- || !pack_str(&msg.left.id) /* string 2 */
- || !pack_str(&msg.left.cert) /* string 3 */
- || !pack_str(&msg.left.ca) /* string 4 */
- || !pack_str(&msg.left.groups) /* string 5 */
- || !pack_str(&msg.left.updown) /* string 6 */
-#ifdef VIRTUAL_IP
- || !pack_str(&msg.left.virt)
-#endif
- || !pack_str(&msg.right.id) /* string 7 */
- || !pack_str(&msg.right.cert) /* string 8 */
- || !pack_str(&msg.right.ca) /* string 9 */
- || !pack_str(&msg.right.groups) /* string 10 */
- || !pack_str(&msg.right.updown) /* string 11 */
-#ifdef VIRTUAL_IP
- || !pack_str(&msg.right.virt)
-#endif
- || !pack_str(&msg.keyid) /* string 12 */
- || !pack_str(&msg.myid) /* string 13 */
- || !pack_str(&msg.cacert) /* string 14 */
- || !pack_str(&msg.ldaphost) /* string 15 */
- || !pack_str(&msg.ldapbase) /* string 16 */
- || !pack_str(&msg.crluri) /* string 17 */
- || !pack_str(&msg.crluri2) /* string 18 */
- || !pack_str(&msg.ocspuri) /* string 19 */
- || !pack_str(&msg.ike) /* string 20 */
- || !pack_str(&msg.esp) /* string 21 */
- || !pack_str(&msg.sc_data) /* string 22 */
- || str_roof - next_str < (ptrdiff_t)msg.keyval.len) /* chunk (sort of string 5) */
- diag("too many bytes of strings to fit in message to pluto");
-
- memcpy(next_str, msg.keyval.ptr, msg.keyval.len);
- msg.keyval.ptr = NULL;
- next_str += msg.keyval.len;
-
- msg.magic = ((opts_seen & ~LELEM(OPT_SHUTDOWN))
- | sc_seen | lst_seen | cd_seen | ca_seen) != LEMPTY
- || msg.whack_options
- ? WHACK_MAGIC : WHACK_BASIC_MAGIC;
-
- /* send message to Pluto */
- if (access(ctl_addr.sun_path, R_OK | W_OK) < 0)
- {
- int e = errno;
-
- switch (e)
- {
- case EACCES:
- fprintf(stderr, "whack: no right to communicate with pluto (access(\"%s\"))\n"
- , ctl_addr.sun_path);
- break;
- case ENOENT:
- fprintf(stderr, "whack: Pluto is not running (no \"%s\")\n"
- , ctl_addr.sun_path);
- break;
- default:
- fprintf(stderr, "whack: access(\"%s\") failed with %d %s\n"
- , ctl_addr.sun_path, errno, strerror(e));
- break;
- }
- exit(RC_WHACK_PROBLEM);
- }
- else
- {
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
- int exit_status = 0;
- ssize_t len = next_str - (char *)&msg;
-
- if (sock == -1)
- {
- int e = errno;
-
- fprintf(stderr, "whack: socket() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
-
- if (connect(sock, (struct sockaddr *)&ctl_addr
- , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- {
- int e = errno;
-
- fprintf(stderr, "whack:%s connect() for \"%s\" failed (%d %s)\n"
- , e == ECONNREFUSED? " is Pluto running? " : ""
- , ctl_addr.sun_path, e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
-
- if (write(sock, &msg, len) != len)
- {
- int e = errno;
-
- fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
-
- /* for now, just copy reply back to stdout */
-
- {
- char buf[4097]; /* arbitrary limit on log line length */
- char *be = buf;
-
- for (;;)
- {
- char *ls = buf;
- ssize_t rl = read(sock, be, (buf + sizeof(buf)-1) - be);
-
- if (rl < 0)
- {
- int e = errno;
-
- fprintf(stderr, "whack: read() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
- if (rl == 0)
- {
- if (be != buf)
- fprintf(stderr, "whack: last line from pluto too long or unterminated\n");
- break;
- }
-
- be += rl;
- *be = '\0';
-
- for (;;)
- {
- char *le = strchr(ls, '\n');
-
- if (le == NULL)
- {
- /* move last, partial line to start of buffer */
- memmove(buf, ls, be-ls);
- be -= ls - buf;
- break;
- }
-
- le++; /* include NL in line */
- write(1, ls, le - ls);
-
- /* figure out prefix number
- * and how it should affect our exit status
- */
- {
- unsigned long s = strtoul(ls, NULL, 10);
-
- switch (s)
- {
- case RC_COMMENT:
- case RC_LOG:
- /* ignore */
- break;
- case RC_SUCCESS:
- /* be happy */
- exit_status = 0;
- break;
- case RC_ENTERSECRET:
- get_secret(sock);
- break;
- /* case RC_LOG_SERIOUS: */
- default:
- /* pass through */
- exit_status = s;
- break;
- }
- }
- ls = le;
- }
- }
- }
- return exit_status;
- }
-}
diff --git a/programs/pluto/whack.h b/programs/pluto/whack.h
deleted file mode 100644
index 755918a2c..000000000
--- a/programs/pluto/whack.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/* Structure of messages from whack to Pluto proper.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: whack.h,v 1.17 2006/10/19 15:18:43 as Exp $
- */
-
-#ifndef _WHACK_H
-#define _WHACK_H
-
-#include <freeswan.h>
-
-#include "smartcard.h"
-
-/* Since the message remains on one host, native representation is used.
- * Think of this as horizontal microcode: all selected operations are
- * to be done (in the order declared here).
- *
- * MAGIC is used to help detect version mismatches between whack and Pluto.
- * Whenever the interface (i.e. this struct) changes in form or
- * meaning, change this value (probably by changing the last number).
- *
- * If the command only requires basic actions (status or shutdown),
- * it is likely that the relevant part of the message changes less frequently.
- * Whack uses WHACK_BASIC_MAGIC in those cases.
- *
- * NOTE: no value of WHACK_BASIC_MAGIC may equal any value of WHACK_MAGIC.
- * Otherwise certain version mismatches will not be detected.
- */
-
-#define WHACK_BASIC_MAGIC (((((('w' << 8) + 'h') << 8) + 'k') << 8) + 24)
-#define WHACK_MAGIC (((((('w' << 8) + 'h') << 8) + 'k') << 8) + 26)
-
-typedef struct whack_end whack_end_t;
-
-/* struct whack_end is a lot like connection.h's struct end
- * It differs because it is going to be shipped down a socket
- * and because whack is a separate program from pluto.
- */
-struct whack_end {
- char *id; /* id string (if any) -- decoded by pluto */
- char *cert; /* path string (if any) -- loaded by pluto */
- char *ca; /* distinguished name string (if any) -- parsed by pluto */
- char *groups; /* access control groups (if any) -- parsed by pluto */
- ip_address
- host_addr,
- host_nexthop,
- host_srcip;
- ip_subnet client;
-
- bool key_from_DNS_on_demand;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_srcip;
- bool has_natip;
- bool modecfg;
- bool hostaccess;
- certpolicy_t sendcert;
- char *updown; /* string */
- u_int16_t host_port; /* host order */
- u_int16_t port; /* host order */
- u_int8_t protocol;
-#ifdef VIRTUAL_IP
- char *virt;
-#endif
- };
-
-typedef struct whack_message whack_message_t;
-
-struct whack_message {
- unsigned int magic;
-
- /* for WHACK_STATUS: */
- bool whack_status;
- bool whack_statusall;
-
-
- /* for WHACK_SHUTDOWN */
- bool whack_shutdown;
-
- /* END OF BASIC COMMANDS
- * If you change anything earlier in this struct, update WHACK_BASIC_MAGIC.
- */
-
- /* name is used in connection, ca and initiate */
- size_t name_len; /* string 1 */
- char *name;
-
- /* for WHACK_OPTIONS: */
-
- bool whack_options;
-
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
-
- /* for WHACK_CONNECTION */
-
- bool whack_connection;
- bool whack_async;
-
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_rekey_fuzz;
- unsigned long sa_keying_tries;
-
- /* For DPD 3706 - Dead Peer Detection */
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
-
- /* note that each end contains string 2/5.id, string 3/6 cert,
- * and string 4/7 updown
- */
- whack_end_t left;
- whack_end_t right;
-
- /* note: if the client is the gateway, the following must be equal */
- sa_family_t addr_family; /* between gateways */
- sa_family_t tunnel_addr_family; /* between clients */
-
- char *ike; /* ike algo string (separated by commas) */
- char *pfsgroup; /* pfsgroup will be "encapsulated" in esp string for pluto */
- char *esp; /* esp algo string (separated by commas) */
-
- /* for WHACK_KEY: */
- bool whack_key;
- bool whack_addkey;
- char *keyid; /* string 8 */
- enum pubkey_alg pubkey_alg;
- chunk_t keyval; /* chunk */
-
- /* for WHACK_MYID: */
- bool whack_myid;
- char *myid; /* string 7 */
-
- /* for WHACK_ROUTE: */
- bool whack_route;
-
- /* for WHACK_UNROUTE: */
- bool whack_unroute;
-
- /* for WHACK_INITIATE: */
- bool whack_initiate;
-
- /* for WHACK_OPINITIATE */
- bool whack_oppo_initiate;
- ip_address oppo_my_client, oppo_peer_client;
-
- /* for WHACK_TERMINATE: */
- bool whack_terminate;
-
- /* for WHACK_DELETE: */
- bool whack_delete;
-
- /* for WHACK_DELETESTATE: */
- bool whack_deletestate;
- so_serial_t whack_deletestateno;
-
- /* for WHACK_LISTEN: */
- bool whack_listen, whack_unlisten;
-
- /* for WHACK_CRASH - note if a remote peer is known to have rebooted */
- bool whack_crash;
- ip_address whack_crash_peer;
-
- /* for WHACK_LIST */
- bool whack_utc;
- lset_t whack_list;
-
- /* for WHACK_PURGEOCSP */
- bool whack_purgeocsp;
-
- /* for WHACK_REREAD */
- u_char whack_reread;
-
- /* for WHACK_CA */
- bool whack_ca;
- bool whack_strict;
-
- char *cacert;
- char *ldaphost;
- char *ldapbase;
- char *crluri;
- char *crluri2;
- char *ocspuri;
-
- /* for WHACK_SC_OP */
- sc_op_t whack_sc_op;
- int inbase, outbase;
- char *sc_data;
-
- /* space for strings (hope there is enough room):
- * Note that pointers don't travel on wire.
- * 1 connection name [name_len]
- * 2 left's name [left.host.name.len]
- * 3 left's cert
- * 4 left's ca
- * 5 left's groups
- * 6 left's updown
- * 7 right's name [left.host.name.len]
- * 8 right's cert
- * 9 right's ca
- * 10 right's groups
- * 11 right's updown
- * 12 keyid
- * 13 myid
- * 14 cacert
- * 15 ldaphost
- * 16 ldapbase
- * 17 crluri
- * 18 crluri2
- * 19 ocspuri
- * 20 ike
- " 21 esp
- * 22 rsa_data
- * plus keyval (limit: 8K bits + overhead), a chunk.
- */
- size_t str_size;
- char string[2048];
-};
-
-/* Codes for status messages returned to whack.
- * These are 3 digit decimal numerals. The structure
- * is inspired by section 4.2 of RFC959 (FTP).
- * Since these will end up as the exit status of whack, they
- * must be less than 256.
- * NOTE: ipsec_auto(8) knows about some of these numbers -- change carefully.
- */
-enum rc_type {
- RC_COMMENT, /* non-commital utterance (does not affect exit status) */
- RC_WHACK_PROBLEM, /* whack-detected problem */
- RC_LOG, /* message aimed at log (does not affect exit status) */
- RC_LOG_SERIOUS, /* serious message aimed at log (does not affect exit status) */
- RC_SUCCESS, /* success (exit status 0) */
-
- /* failure, but not definitive */
-
- RC_RETRANSMISSION = 10,
-
- /* improper request */
-
- RC_DUPNAME = 20, /* attempt to reuse a connection name */
- RC_UNKNOWN_NAME, /* connection name unknown or state number */
- RC_ORIENT, /* cannot orient connection: neither end is us */
- RC_CLASH, /* clash between two Road Warrior connections OVERLOADED */
- RC_DEAF, /* need --listen before --initiate */
- RC_ROUTE, /* cannot route */
- RC_RTBUSY, /* cannot unroute: route busy */
- RC_BADID, /* malformed --id */
- RC_NOKEY, /* no key found through DNS */
- RC_NOPEERIP, /* cannot initiate when peer IP is unknown */
- RC_INITSHUNT, /* cannot initiate a shunt-oly connection */
- RC_WILDCARD, /* cannot initiate when ID has wildcards */
- RC_NOVALIDPIN, /* cannot initiate without valid PIN */
-
- /* permanent failure */
-
- RC_BADWHACKMESSAGE = 30,
- RC_NORETRANSMISSION,
- RC_INTERNALERR,
- RC_OPPOFAILURE, /* Opportunism failed */
-
- /* entry of secrets */
- RC_ENTERSECRET = 40,
-
- /* progress: start of range for successful state transition.
- * Actual value is RC_NEW_STATE plus the new state code.
- */
- RC_NEW_STATE = 100,
-
- /* start of range for notification.
- * Actual value is RC_NOTIFICATION plus code for notification
- * that should be generated by this Pluto.
- */
- RC_NOTIFICATION = 200 /* as per IKE notification messages */
-};
-
-/* options of whack --list*** command */
-
-#define LIST_NONE 0x0000 /* don't list anything */
-#define LIST_ALGS 0x0001 /* list all registered IKE algorithms */
-#define LIST_PUBKEYS 0x0002 /* list all public keys */
-#define LIST_CERTS 0x0004 /* list all host/user certs */
-#define LIST_CACERTS 0x0008 /* list all ca certs */
-#define LIST_ACERTS 0x0010 /* list all attribute certs */
-#define LIST_AACERTS 0x0020 /* list all aa certs */
-#define LIST_OCSPCERTS 0x0040 /* list all ocsp certs */
-#define LIST_GROUPS 0x0080 /* list all access control groups */
-#define LIST_CAINFOS 0x0100 /* list all ca information records */
-#define LIST_CRLS 0x0200 /* list all crls */
-#define LIST_OCSP 0x0400 /* list all ocsp cache entries */
-#define LIST_CARDS 0x0800 /* list all smartcard records */
-
-#define LIST_ALL LRANGES(LIST_ALGS, LIST_CARDS) /* all list options */
-
-/* options of whack --reread*** command */
-
-#define REREAD_NONE 0x00 /* don't reread anything */
-#define REREAD_SECRETS 0x01 /* reread /etc/ipsec.secrets */
-#define REREAD_CACERTS 0x02 /* reread certs in /etc/ipsec.d/cacerts */
-#define REREAD_AACERTS 0x04 /* reread certs in /etc/ipsec.d/aacerts */
-#define REREAD_OCSPCERTS 0x08 /* reread certs in /etc/ipsec.d/ocspcerts */
-#define REREAD_ACERTS 0x10 /* reread certs in /etc/ipsec.d/acerts */
-#define REREAD_CRLS 0x20 /* reread crls in /etc/ipsec.d/crls */
-
-#define REREAD_ALL LRANGES(REREAD_SECRETS, REREAD_CRLS) /* all reread options */
-
-#endif /* _WHACK_H */
diff --git a/programs/pluto/x509.c b/programs/pluto/x509.c
deleted file mode 100644
index c1b4cb6e3..000000000
--- a/programs/pluto/x509.c
+++ /dev/null
@@ -1,2241 +0,0 @@
-/* Support of X.509 certificates
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: x509.c,v 1.36 2006/04/10 16:08:33 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <time.h>
-#include <sys/types.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-#include "id.h"
-#include "asn1.h"
-#include "oid.h"
-#include "pkcs1.h"
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "certs.h"
-#include "keys.h"
-#include "whack.h"
-#include "fetch.h"
-#include "ocsp.h"
-#include "sha1.h"
-
-/* chained lists of X.509 end certificates */
-
-static x509cert_t *x509certs = NULL;
-
-/* ASN.1 definition of a basicConstraints extension */
-
-static const asn1Object_t basicConstraintsObjects[] = {
- { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "CA", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 1 */
- { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define BASIC_CONSTRAINTS_CA 1
-#define BASIC_CONSTRAINTS_ROOF 4
-
-/* ASN.1 definition of time */
-
-static const asn1Object_t timeObjects[] = {
- { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT |
- ASN1_BODY }, /* 0 */
- { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define TIME_UTC 0
-#define TIME_GENERALIZED 2
-#define TIME_ROOF 4
-
-/* ASN.1 definition of a keyIdentifier */
-
-static const asn1Object_t keyIdentifierObjects[] = {
- { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
-};
-
-/* ASN.1 definition of a authorityKeyIdentifier extension */
-
-static const asn1Object_t authorityKeyIdentifierObjects[] = {
- { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 3 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT |
- ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-
-#define AUTH_KEY_ID_KEY_ID 1
-#define AUTH_KEY_ID_CERT_ISSUER 3
-#define AUTH_KEY_ID_CERT_SERIAL 5
-#define AUTH_KEY_ID_ROOF 7
-
-/* ASN.1 definition of a authorityInfoAccess extension */
-
-static const asn1Object_t authorityInfoAccessObjects[] = {
- { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
-};
-
-#define AUTH_INFO_ACCESS_METHOD 2
-#define AUTH_INFO_ACCESS_LOCATION 3
-#define AUTH_INFO_ACCESS_ROOF 5
-
-/* ASN.1 definition of a extendedKeyUsage extension */
-
-static const asn1Object_t extendedKeyUsageObjects[] = {
- { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
-};
-
-#define EXT_KEY_USAGE_PURPOSE_ID 1
-#define EXT_KEY_USAGE_ROOF 3
-
-/* ASN.1 definition of generalNames */
-
-static const asn1Object_t generalNamesObjects[] = {
- { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-
-#define GENERAL_NAMES_GN 1
-#define GENERAL_NAMES_ROOF 3
-
-/* ASN.1 definition of generalName */
-
-static const asn1Object_t generalNameObjects[] = {
- { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 0 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT |
- ASN1_BODY }, /* 4 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT |
- ASN1_BODY }, /* 6 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT |
- ASN1_BODY }, /* 10 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "uniformResourceIdentifier", ASN1_CONTEXT_S_6, ASN1_OPT |
- ASN1_BODY }, /* 12 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
- { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT |
- ASN1_BODY }, /* 16 */
- { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
-};
-
-#define GN_OBJ_OTHER_NAME 0
-#define GN_OBJ_RFC822_NAME 2
-#define GN_OBJ_DNS_NAME 4
-#define GN_OBJ_X400_ADDRESS 6
-#define GN_OBJ_DIRECTORY_NAME 8
-#define GN_OBJ_EDI_PARTY_NAME 10
-#define GN_OBJ_URI 12
-#define GN_OBJ_IP_ADDRESS 14
-#define GN_OBJ_REGISTERED_ID 16
-#define GN_OBJ_ROOF 18
-
-/* ASN.1 definition of otherName */
-
-static const asn1Object_t otherNameObjects[] = {
- {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
- {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
-};
-
-#define ON_OBJ_ID_TYPE 0
-#define ON_OBJ_VALUE 1
-#define ON_OBJ_ROOF 2
-
-/* ASN.1 definition of crlDistributionPoints */
-
-static const asn1Object_t crlDistributionPointsObjects[] = {
- { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 2 */
- { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 3 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 3, "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_BODY }, /* 5 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT |
- ASN1_BODY }, /* 10 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
-};
-
-#define CRL_DIST_POINTS_FULLNAME 3
-#define CRL_DIST_POINTS_ROOF 13
-
-/* ASN.1 definition of an X.509v3 certificate */
-
-static const asn1Object_t certObjects[] = {
- { 0, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
- { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
- { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 2, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
- { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
- { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 14 */
- { 5, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 15 */
- { 5, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 16 */
- { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 17 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 19 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 21 */
- { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 22 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 23 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 24 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 25 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 26 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 27 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 28 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 29 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 30 */
-};
-
-#define X509_OBJ_CERTIFICATE 0
-#define X509_OBJ_TBS_CERTIFICATE 1
-#define X509_OBJ_VERSION 3
-#define X509_OBJ_SERIAL_NUMBER 4
-#define X509_OBJ_SIG_ALG 5
-#define X509_OBJ_ISSUER 6
-#define X509_OBJ_NOT_BEFORE 8
-#define X509_OBJ_NOT_AFTER 9
-#define X509_OBJ_SUBJECT 10
-#define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
-#define X509_OBJ_SUBJECT_PUBLIC_KEY 13
-#define X509_OBJ_RSA_PUBLIC_KEY 14
-#define X509_OBJ_MODULUS 15
-#define X509_OBJ_PUBLIC_EXPONENT 16
-#define X509_OBJ_EXTN_ID 24
-#define X509_OBJ_CRITICAL 25
-#define X509_OBJ_EXTN_VALUE 26
-#define X509_OBJ_ALGORITHM 29
-#define X509_OBJ_SIGNATURE 30
-#define X509_OBJ_ROOF 31
-
-
-const x509cert_t empty_x509cert = {
- NULL , /* *next */
- UNDEFINED_TIME, /* installed */
- 0 , /* count */
- FALSE , /* smartcard */
- AUTH_NONE , /* authority_flags */
- { NULL, 0 } , /* certificate */
- { NULL, 0 } , /* tbsCertificate */
- 1 , /* version */
- { NULL, 0 } , /* serialNumber */
- OID_UNKNOWN , /* sigAlg */
- { NULL, 0 } , /* issuer */
- /* validity */
- 0 , /* notBefore */
- 0 , /* notAfter */
- { NULL, 0 } , /* subject */
- /* subjectPublicKeyInfo */
- OID_UNKNOWN , /* subjectPublicKeyAlgorithm */
- { NULL, 0 } , /* subjectPublicKey */
- { NULL, 0 } , /* modulus */
- { NULL, 0 } , /* publicExponent */
- /* issuerUniqueID */
- /* subjectUniqueID */
- /* extensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- FALSE , /* isCA */
- FALSE , /* isOcspSigner */
- { NULL, 0 } , /* subjectKeyID */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKeySerialNumber */
- { NULL, 0 } , /* accessLocation */
- NULL , /* subjectAltName */
- NULL , /* crlDistributionPoints */
- OID_UNKNOWN , /* algorithm */
- { NULL, 0 } /* signature */
-};
-
-/* coding of X.501 distinguished name */
-
-typedef struct {
- const u_char *name;
- chunk_t oid;
- u_char type;
-} x501rdn_t;
-
-/* X.501 acronyms for well known object identifiers (OIDs) */
-
-static u_char oid_ND[] = {0x02, 0x82, 0x06, 0x01,
- 0x0A, 0x07, 0x14};
-static u_char oid_UID[] = {0x09, 0x92, 0x26, 0x89, 0x93,
- 0xF2, 0x2C, 0x64, 0x01, 0x01};
-static u_char oid_DC[] = {0x09, 0x92, 0x26, 0x89, 0x93,
- 0xF2, 0x2C, 0x64, 0x01, 0x19};
-static u_char oid_CN[] = {0x55, 0x04, 0x03};
-static u_char oid_S[] = {0x55, 0x04, 0x04};
-static u_char oid_SN[] = {0x55, 0x04, 0x05};
-static u_char oid_C[] = {0x55, 0x04, 0x06};
-static u_char oid_L[] = {0x55, 0x04, 0x07};
-static u_char oid_ST[] = {0x55, 0x04, 0x08};
-static u_char oid_O[] = {0x55, 0x04, 0x0A};
-static u_char oid_OU[] = {0x55, 0x04, 0x0B};
-static u_char oid_T[] = {0x55, 0x04, 0x0C};
-static u_char oid_D[] = {0x55, 0x04, 0x0D};
-static u_char oid_N[] = {0x55, 0x04, 0x29};
-static u_char oid_G[] = {0x55, 0x04, 0x2A};
-static u_char oid_I[] = {0x55, 0x04, 0x2B};
-static u_char oid_ID[] = {0x55, 0x04, 0x2D};
-static u_char oid_EN[] = {0x60, 0x86, 0x48, 0x01, 0x86,
- 0xF8, 0x42, 0x03, 0x01, 0x03};
-static u_char oid_E[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
- 0x0D, 0x01, 0x09, 0x01};
-static u_char oid_UN[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
- 0x0D, 0x01, 0x09, 0x02};
-static u_char oid_TCGID[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
- 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
-
-static const x501rdn_t x501rdns[] = {
- {"ND" , {oid_ND, 7}, ASN1_PRINTABLESTRING},
- {"UID" , {oid_UID, 10}, ASN1_PRINTABLESTRING},
- {"DC" , {oid_DC, 10}, ASN1_PRINTABLESTRING},
- {"CN" , {oid_CN, 3}, ASN1_PRINTABLESTRING},
- {"S" , {oid_S, 3}, ASN1_PRINTABLESTRING},
- {"SN" , {oid_SN, 3}, ASN1_PRINTABLESTRING},
- {"serialNumber" , {oid_SN, 3}, ASN1_PRINTABLESTRING},
- {"C" , {oid_C, 3}, ASN1_PRINTABLESTRING},
- {"L" , {oid_L, 3}, ASN1_PRINTABLESTRING},
- {"ST" , {oid_ST, 3}, ASN1_PRINTABLESTRING},
- {"O" , {oid_O, 3}, ASN1_PRINTABLESTRING},
- {"OU" , {oid_OU, 3}, ASN1_PRINTABLESTRING},
- {"T" , {oid_T, 3}, ASN1_PRINTABLESTRING},
- {"D" , {oid_D, 3}, ASN1_PRINTABLESTRING},
- {"N" , {oid_N, 3}, ASN1_PRINTABLESTRING},
- {"G" , {oid_G, 3}, ASN1_PRINTABLESTRING},
- {"I" , {oid_I, 3}, ASN1_PRINTABLESTRING},
- {"ID" , {oid_ID, 3}, ASN1_PRINTABLESTRING},
- {"EN" , {oid_EN, 10}, ASN1_PRINTABLESTRING},
- {"employeeNumber" , {oid_EN, 10}, ASN1_PRINTABLESTRING},
- {"E" , {oid_E, 9}, ASN1_IA5STRING},
- {"Email" , {oid_E, 9}, ASN1_IA5STRING},
- {"emailAddress" , {oid_E, 9}, ASN1_IA5STRING},
- {"UN" , {oid_UN, 9}, ASN1_IA5STRING},
- {"unstructuredName", {oid_UN, 9}, ASN1_IA5STRING},
- {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
-};
-
-#define X501_RDN_ROOF 26
-
-static u_char ASN1_subjectAltName_oid_str[] = {
- 0x06, 0x03, 0x55, 0x1D, 0x11
-};
-
-static const chunk_t ASN1_subjectAltName_oid = strchunk(ASN1_subjectAltName_oid_str);
-
-static void
-update_chunk(chunk_t *ch, int n)
-{
- n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
- ch->ptr += n; ch->len -= n;
-}
-
-
-/*
- * Pointer is set to the first RDN in a DN
- */
-static err_t
-init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
-{
- *rdn = empty_chunk;
- *attribute = empty_chunk;
-
- /* a DN is a SEQUENCE OF RDNs */
-
- if (*dn.ptr != ASN1_SEQUENCE)
- {
- return "DN is not a SEQUENCE";
- }
-
- rdn->len = asn1_length(&dn);
-
- if (rdn->len == ASN1_INVALID_LENGTH)
- return "Invalid RDN length";
-
- rdn->ptr = dn.ptr;
-
- /* are there any RDNs ? */
- *next = rdn->len > 0;
-
- return NULL;
-}
-
-/*
- * Fetches the next RDN in a DN
- */
-static err_t
-get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
-, asn1_t *type, bool *next)
-{
- chunk_t body;
-
- /* initialize return values */
- *oid = empty_chunk;
- *value = empty_chunk;
-
- /* if all attributes have been parsed, get next rdn */
- if (attribute->len <= 0)
- {
- /* an RDN is a SET OF attributeTypeAndValue */
- if (*rdn->ptr != ASN1_SET)
- return "RDN is not a SET";
-
- attribute->len = asn1_length(rdn);
-
- if (attribute->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute length";
-
- attribute->ptr = rdn->ptr;
-
- /* advance to start of next RDN */
- rdn->ptr += attribute->len;
- rdn->len -= attribute->len;
- }
-
- /* an attributeTypeAndValue is a SEQUENCE */
- if (*attribute->ptr != ASN1_SEQUENCE)
- return "attributeTypeAndValue is not a SEQUENCE";
-
- /* extract the attribute body */
- body.len = asn1_length(attribute);
-
- if (body.len == ASN1_INVALID_LENGTH)
- return "Invalid attribute body length";
-
- body.ptr = attribute->ptr;
-
- /* advance to start of next attribute */
- attribute->ptr += body.len;
- attribute->len -= body.len;
-
- /* attribute type is an OID */
- if (*body.ptr != ASN1_OID)
- return "attributeType is not an OID";
-
- /* extract OID */
- oid->len = asn1_length(&body);
-
- if (oid->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute OID length";
-
- oid->ptr = body.ptr;
-
- /* advance to the attribute value */
- body.ptr += oid->len;
- body.len -= oid->len;
-
- /* extract string type */
- *type = *body.ptr;
-
- /* extract string value */
- value->len = asn1_length(&body);
-
- if (value->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute string length";
-
- value->ptr = body.ptr;
-
- /* are there any RDNs left? */
- *next = rdn->len > 0 || attribute->len > 0;
-
- return NULL;
-}
-
-/*
- * Parses an ASN.1 distinguished name int its OID/value pairs
- */
-static err_t
-dn_parse(chunk_t dn, chunk_t *str)
-{
- chunk_t rdn, oid, attribute, value;
- asn1_t type;
- int oid_code;
- bool next;
- bool first = TRUE;
-
- err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
-
- if (ugh != NULL) /* a parsing error has occured */
- return ugh;
-
- while (next)
- {
- ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
-
- if (ugh != NULL) /* a parsing error has occured */
- return ugh;
-
- if (first) /* first OID/value pair */
- first = FALSE;
- else /* separate OID/value pair by a comma */
- update_chunk(str, snprintf(str->ptr,str->len,", "));
-
- /* print OID */
- oid_code = known_oid(oid);
- if (oid_code == OID_UNKNOWN) /* OID not found in list */
- hex_str(oid, str);
- else
- update_chunk(str, snprintf(str->ptr,str->len,"%s",
- oid_names[oid_code].name));
-
- /* print value */
- update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
- (int)value.len,value.ptr));
- }
- return NULL;
-}
-
-/*
- * Count the number of wildcard RDNs in a distinguished name
- */
-int
-dn_count_wildcards(chunk_t dn)
-{
- chunk_t rdn, attribute, oid, value;
- asn1_t type;
- bool next;
- int wildcards = 0;
-
- err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
-
- if (ugh != NULL) /* a parsing error has occured */
- return -1;
-
- while (next)
- {
- ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
-
- if (ugh != NULL) /* a parsing error has occured */
- return -1;
- if (value.len == 1 && *value.ptr == '*')
- wildcards++; /* we have found a wildcard RDN */
- }
- return wildcards;
-}
-
-/*
- * Prints a binary string in hexadecimal form
- */
-void
-hex_str(chunk_t bin, chunk_t *str)
-{
- u_int i;
- update_chunk(str, snprintf(str->ptr,str->len,"0x"));
- for (i=0; i < bin.len; i++)
- update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
-}
-
-
-/* Converts a binary DER-encoded ASN.1 distinguished name
- * into LDAP-style human-readable ASCII format
- */
-int
-dntoa(char *dst, size_t dstlen, chunk_t dn)
-{
- err_t ugh = NULL;
- chunk_t str;
-
- str.ptr = dst;
- str.len = dstlen;
- ugh = dn_parse(dn, &str);
-
- if (ugh != NULL) /* error, print DN as hex string */
- {
- DBG(DBG_PARSING,
- DBG_log("error in DN parsing: %s", ugh)
- )
- str.ptr = dst;
- str.len = dstlen;
- hex_str(dn, &str);
- }
- return (int)(dstlen - str.len);
-}
-
-/*
- * Same as dntoa but prints a special string for a null dn
- */
-int
-dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
-{
- if (dn.ptr == NULL)
- return snprintf(dst, dstlen, "%s", null_dn);
- else
- return dntoa(dst, dstlen, dn);
-}
-
-/* Converts an LDAP-style human-readable ASCII-encoded
- * ASN.1 distinguished name into binary DER-encoded format
- */
-err_t
-atodn(char *src, chunk_t *dn)
-{
- /* finite state machine for atodn */
-
- typedef enum {
- SEARCH_OID = 0,
- READ_OID = 1,
- SEARCH_NAME = 2,
- READ_NAME = 3,
- UNKNOWN_OID = 4
- } state_t;
-
- u_char oid_len_buf[3];
- u_char name_len_buf[3];
- u_char rdn_seq_len_buf[3];
- u_char rdn_set_len_buf[3];
- u_char dn_seq_len_buf[3];
-
- chunk_t asn1_oid_len = { oid_len_buf, 0 };
- chunk_t asn1_name_len = { name_len_buf, 0 };
- chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
- chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
- chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
- chunk_t oid = empty_chunk;
- chunk_t name = empty_chunk;
-
- int whitespace = 0;
- int rdn_seq_len = 0;
- int rdn_set_len = 0;
- int dn_seq_len = 0;
- int pos = 0;
-
- err_t ugh = NULL;
-
- u_char *dn_ptr = dn->ptr + 4;
-
- state_t state = SEARCH_OID;
-
- do
- {
- switch (state)
- {
- case SEARCH_OID:
- if (*src != ' ' && *src != '/' && *src != ',')
- {
- oid.ptr = src;
- oid.len = 1;
- state = READ_OID;
- }
- break;
- case READ_OID:
- if (*src != ' ' && *src != '=')
- oid.len++;
- else
- {
- for (pos = 0; pos < X501_RDN_ROOF; pos++)
- {
- if (strlen(x501rdns[pos].name) == oid.len &&
- strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
- break; /* found a valid OID */
- }
- if (pos == X501_RDN_ROOF)
- {
- ugh = "unknown OID in distinguished name";
- state = UNKNOWN_OID;
- break;
- }
- code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
-
- /* reset oid and change state */
- oid = empty_chunk;
- state = SEARCH_NAME;
- }
- break;
- case SEARCH_NAME:
- if (*src != ' ' && *src != '=')
- {
- name.ptr = src;
- name.len = 1;
- whitespace = 0;
- state = READ_NAME;
- }
- break;
- case READ_NAME:
- if (*src != ',' && *src != '/' && *src != '\0')
- {
- name.len++;
- if (*src == ' ')
- whitespace++;
- else
- whitespace = 0;
- }
- else
- {
- name.len -= whitespace;
- code_asn1_length(name.len, &asn1_name_len);
-
- /* compute the length of the relative distinguished name sequence */
- rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
- 1 + asn1_name_len.len + name.len;
- code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
-
- /* compute the length of the relative distinguished name set */
- rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
- code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
-
- /* encode the relative distinguished name */
- *dn_ptr++ = ASN1_SET;
- chunkcpy(dn_ptr, asn1_rdn_set_len);
- *dn_ptr++ = ASN1_SEQUENCE;
- chunkcpy(dn_ptr, asn1_rdn_seq_len);
- *dn_ptr++ = ASN1_OID;
- chunkcpy(dn_ptr, asn1_oid_len);
- chunkcpy(dn_ptr, x501rdns[pos].oid);
- /* encode the ASN.1 character string type of the name */
- *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
- chunkcpy(dn_ptr, asn1_name_len);
- chunkcpy(dn_ptr, name);
-
- /* accumulate the length of the distinguished name sequence */
- dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
-
- /* reset name and change state */
- name = empty_chunk;
- state = SEARCH_OID;
- }
- break;
- case UNKNOWN_OID:
- break;
- }
- } while (*src++ != '\0');
-
- /* complete the distinguished name sequence*/
- code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
- dn->ptr += 3 - asn1_dn_seq_len.len;
- dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
- dn_ptr = dn->ptr;
- *dn_ptr++ = ASN1_SEQUENCE;
- chunkcpy(dn_ptr, asn1_dn_seq_len);
- return ugh;
-}
-
-/* compare two distinguished names by
- * comparing the individual RDNs
- */
-bool
-same_dn(chunk_t a, chunk_t b)
-{
- chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
- chunk_t oid_a, oid_b, value_a, value_b;
- asn1_t type_a, type_b;
- bool next_a, next_b;
-
- /* same lengths for the DNs */
- if (a.len != b.len)
- return FALSE;
-
- /* try a binary comparison first */
- if (memcmp(a.ptr, b.ptr, b.len) == 0)
- return TRUE;
-
- /* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
- return FALSE;
-
- /* fetch next RDN pair */
- while (next_a && next_b)
- {
- /* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
- {
- return FALSE;
- }
-
- /* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
- return FALSE;
-
- /* same lengths for values */
- if (value_a.len != value_b.len)
- return FALSE;
-
- /* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
- (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
- {
- if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
- }
- else
- {
- if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
- }
- }
- /* both DNs must have same number of RDNs */
- if (next_a || next_b)
- return FALSE;
-
- /* the two DNs are equal! */
- return TRUE;
-}
-
-
-/* compare two distinguished names by comparing the individual RDNs.
- * A single'*' character designates a wildcard RDN in DN b.
- */
-bool
-match_dn(chunk_t a, chunk_t b, int *wildcards)
-{
- chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
- chunk_t oid_a, oid_b, value_a, value_b;
- asn1_t type_a, type_b;
- bool next_a, next_b;
-
- /* initialize wildcard counter */
- *wildcards = 0;
-
- /* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
- return FALSE;
-
- /* fetch next RDN pair */
- while (next_a && next_b)
- {
- /* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
- {
- return FALSE;
- }
-
- /* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
- return FALSE;
-
- /* does rdn_b contain a wildcard? */
- if (value_b.len == 1 && *value_b.ptr == '*')
- {
- (*wildcards)++;
- continue;
- }
-
- /* same lengths for values */
- if (value_a.len != value_b.len)
- return FALSE;
-
- /* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
- (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
- {
- if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
- }
- else
- {
- if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
- }
- }
- /* both DNs must have same number of RDNs */
- if (next_a || next_b)
- return FALSE;
-
- /* the two DNs match! */
- return TRUE;
-}
-
-/*
- * compare two X.509 certificates by comparing their signatures
- */
-bool
-same_x509cert(const x509cert_t *a, const x509cert_t *b)
-{
- return same_chunk(a->signature, b->signature);
-}
-
-/* for each link pointing to the certificate
- " increase the count by one
- */
-void
-share_x509cert(x509cert_t *cert)
-{
- if (cert != NULL)
- cert->count++;
-}
-
-/*
- * add a X.509 user/host certificate to the chained list
- */
-x509cert_t*
-add_x509cert(x509cert_t *cert)
-{
- x509cert_t *c = x509certs;
-
- while (c != NULL)
- {
- if (same_x509cert(c, cert)) /* already in chain, free cert */
- {
- free_x509cert(cert);
- return c;
- }
- c = c->next;
- }
-
- /* insert new cert at the root of the chain */
- lock_certs_and_keys("add_x509cert");
- cert->next = x509certs;
- x509certs = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" x509 cert inserted")
- )
- unlock_certs_and_keys("add_x509cert");
- return cert;
-}
-
-/*
- * choose either subject DN or a subjectAltName as connection end ID
- */
-void
-select_x509cert_id(x509cert_t *cert, struct id *end_id)
-{
- bool copy_subject_dn = TRUE; /* ID is subject DN */
-
- if (end_id->kind != ID_NONE) /* check for matching subjectAltName */
- {
- generalName_t *gn = cert->subjectAltName;
-
- while (gn != NULL)
- {
- struct id id = empty_id;
-
- gntoid(&id, gn);
- if (same_id(&id, end_id))
- {
- copy_subject_dn = FALSE; /* take subjectAltName instead */
- break;
- }
- gn = gn->next;
- }
- }
-
- if (copy_subject_dn)
- {
- if (end_id->kind != ID_NONE && end_id->kind != ID_DER_ASN1_DN)
- {
- char buf[BUF_LEN];
-
- idtoa(end_id, buf, BUF_LEN);
- plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf);
- }
- end_id->kind = ID_DER_ASN1_DN;
- end_id->name.len = cert->subject.len;
- end_id->name.ptr = temporary_cyclic_buffer();
- memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);
- }
-}
-
-/*
- * check for equality between two key identifiers
- */
-bool
-same_keyid(chunk_t a, chunk_t b)
-{
- if (a.ptr == NULL || b.ptr == NULL)
- return FALSE;
-
- return same_chunk(a, b);
-}
-
-/*
- * check for equality between two serial numbers
- */
-bool
-same_serial(chunk_t a, chunk_t b)
-{
- /* do not compare serial numbers if one of them is not defined */
- if (a.ptr == NULL || b.ptr == NULL)
- return TRUE;
-
- return same_chunk(a, b);
-}
-
-/*
- * get a X.509 certificate with a given issuer found at a certain position
- */
-x509cert_t*
-get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid, x509cert_t *chain)
-{
- x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
-
- while (cert != NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)
- : (same_dn(issuer, cert->issuer)
- && same_serial(serial, cert->authKeySerialNumber)))
- {
- return cert;
- }
- cert = cert->next;
- }
- return NULL;
-}
-
-/*
- * encode a linked list of subjectAltNames
- */
-chunk_t
-build_subjectAltNames(generalName_t *subjectAltNames)
-{
- u_char *pos;
- chunk_t names;
- size_t len = 0;
- generalName_t *gn = subjectAltNames;
-
- /* compute the total size of the ASN.1 attributes object */
- while (gn != NULL)
- {
- len += gn->name.len;
- gn = gn->next;
- }
-
- pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
-
- gn = subjectAltNames;
- while (gn != NULL)
- {
- chunkcpy(pos, gn->name);
- gn = gn->next;
- }
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_subjectAltName_oid
- , asn1_wrap(ASN1_OCTET_STRING, "m", names));
-}
-
-/*
- * build a to-be-signed X.509 certificate body
- */
-static chunk_t
-build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
-{
- /* version is always X.509v3 */
- chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
-
- chunk_t extensions = empty_chunk;
-
- if (cert->subjectAltName != NULL)
- {
- extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m"
- , asn1_wrap(ASN1_SEQUENCE, "m"
- , build_subjectAltNames(cert->subjectAltName)));
- }
-
- return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm"
- , version
- , asn1_simple_object(ASN1_INTEGER, cert->serialNumber)
- , asn1_algorithmIdentifier(cert->sigAlg)
- , cert->issuer
- , asn1_wrap(ASN1_SEQUENCE, "mm"
- , timetoasn1(&cert->notBefore, ASN1_UTCTIME)
- , timetoasn1(&cert->notAfter, ASN1_UTCTIME)
- )
- , cert->subject
- , pkcs1_build_publicKeyInfo(rsa)
- , extensions
- );
-}
-
-/*
- * build a DER-encoded X.509 certificate
- */
-void
-build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
-, const RSA_private_key_t *signer_key)
-{
- chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
-
- chunk_t signature = pkcs1_build_signature(tbs_cert, cert->sigAlg
- , signer_key, TRUE);
-
- cert->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm"
- , tbs_cert
- , asn1_algorithmIdentifier(cert->sigAlg)
- , signature);
-}
-
-/*
- * free the dynamic memory used to store generalNames
- */
-void
-free_generalNames(generalName_t* gn, bool free_name)
-{
- while (gn != NULL)
- {
- generalName_t *gn_top = gn;
- if (free_name)
- {
- pfree(gn->name.ptr);
- }
- gn = gn->next;
- pfree(gn_top);
- }
-}
-
-/*
- * free a X.509 certificate
- */
-void
-free_x509cert(x509cert_t *cert)
-{
- if (cert != NULL)
- {
- free_generalNames(cert->subjectAltName, FALSE);
- free_generalNames(cert->crlDistributionPoints, FALSE);
- pfreeany(cert->certificate.ptr);
- pfree(cert);
- cert = NULL;
- }
-}
-
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
- */
-void
-release_x509cert(x509cert_t *cert)
-{
- if (cert != NULL && --cert->count == 0)
- {
- x509cert_t **pp = &x509certs;
- while (*pp != cert)
- pp = &(*pp)->next;
- *pp = cert->next;
- free_x509cert(cert);
- }
-}
-
-
-/*
- * stores a chained list of end certs and CA certs
- */
-void
-store_x509certs(x509cert_t **firstcert, bool strict)
-{
- x509cert_t *cacerts = NULL;
- x509cert_t **pp = firstcert;
-
- /* first extract CA certs, discarding root CA certs */
-
- while (*pp != NULL)
- {
- x509cert_t *cert = *pp;
-
- if (cert->isCA)
- {
- *pp = cert->next;
-
- /* we don't accept self-signed CA certs */
- if (same_dn(cert->issuer, cert->subject))
- {
- plog("self-signed cacert rejected");
- free_x509cert(cert);
- }
- else
- {
- /* insertion into temporary chain of candidate CA certs */
- cert->next = cacerts;
- cacerts = cert;
- }
- }
- else
- pp = &cert->next;
- }
-
- /* now verify the candidate CA certs */
-
- while (cacerts != NULL)
- {
- x509cert_t *cert = cacerts;
-
- cacerts = cacerts->next;
-
- if (trust_authcert_candidate(cert, cacerts))
- {
- add_authcert(cert, AUTH_CA);
- }
- else
- {
- plog("intermediate cacert rejected");
- free_x509cert(cert);
- }
- }
-
- /* now verify the end certificates */
-
- pp = firstcert;
-
- while (*pp != NULL)
- {
- time_t valid_until;
- x509cert_t *cert = *pp;
-
- if (verify_x509cert(cert, strict, &valid_until))
- {
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("public key validated")
- )
- add_x509_public_key(cert, valid_until, DAL_SIGNED);
- }
- else
- {
- plog("X.509 certificate rejected");
- }
- *pp = cert->next;
- free_x509cert(cert);
- }
-}
-
-/*
- * decrypts an RSA signature using the issuer's certificate
- */
-static bool
-decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
- chunk_t *digest)
-{
- switch (alg)
- {
- chunk_t decrypted;
-
- case OID_RSA_ENCRYPTION:
- case OID_MD2_WITH_RSA:
- case OID_MD5_WITH_RSA:
- case OID_SHA1_WITH_RSA:
- case OID_SHA1_WITH_RSA_OIW:
- case OID_SHA256_WITH_RSA:
- case OID_SHA384_WITH_RSA:
- case OID_SHA512_WITH_RSA:
- {
- mpz_t s;
- RSA_public_key_t rsa;
-
- init_RSA_public_key(&rsa, issuer_cert->publicExponent
- , issuer_cert->modulus);
-
- /* decrypt the signature s = s^e mod n */
- n_to_mpz(s, sig.ptr, sig.len);
- mpz_powm(s, s, &rsa.e, &rsa.n);
-
- /* convert back to bytes */
- decrypted = mpz_to_n(s, rsa.k);
- DBG(DBG_PARSING,
- DBG_dump_chunk(" decrypted signature: ", decrypted)
- )
-
- /* copy the least significant bits of decrypted signature
- * into the digest string
- */
- memcpy(digest->ptr, decrypted.ptr + decrypted.len - digest->len,
- digest->len);
-
- /* free memory */
- free_RSA_public_content(&rsa);
- pfree(decrypted.ptr);
- mpz_clear(s);
- return TRUE;
- }
- default:
- digest->len = 0;
- return FALSE;
- }
-}
-
-/*
- * Check if a signature over binary blob is genuine
- */
-bool
-check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
-, const x509cert_t *issuer_cert)
-{
- u_char digest_buf[MAX_DIGEST_LEN];
- u_char decrypted_buf[MAX_DIGEST_LEN];
- chunk_t digest = {digest_buf, MAX_DIGEST_LEN};
- chunk_t decrypted = {decrypted_buf, MAX_DIGEST_LEN};
-
- DBG(DBG_PARSING,
- if (digest_alg != OID_UNKNOWN)
- DBG_log("signature digest algorithm: '%s'",oid_names[digest_alg].name);
- else
- DBG_log("unknown signature digest algorithm");
- )
-
- if (!compute_digest(tbs, digest_alg, &digest))
- {
- plog(" digest algorithm not supported");
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_dump_chunk(" digest:", digest)
- )
-
- decrypted.len = digest.len; /* we want the same digest length */
-
- DBG(DBG_PARSING,
- if (enc_alg != OID_UNKNOWN)
- DBG_log("signature encryption algorithm: '%s'",oid_names[enc_alg].name);
- else
- DBG_log("unknown signature encryption algorithm");
- )
-
- if (!decrypt_sig(sig, enc_alg, issuer_cert, &decrypted))
- {
- plog(" decryption algorithm not supported");
- return FALSE;
- }
-
- /* check if digests are equal */
- return !memcmp(decrypted.ptr, digest.ptr, digest.len);
-}
-
-/*
- * extracts the basicConstraints extension
- */
-static bool
-parse_basicConstraints(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- bool isCA = FALSE;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < BASIC_CONSTRAINTS_ROOF) {
-
- if (!extract_object(basicConstraintsObjects, &objectID,
- &object,&level, &ctx))
- break;
-
- if (objectID == BASIC_CONSTRAINTS_CA)
- {
- isCA = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(isCA)?"TRUE":"FALSE");
- )
- }
- objectID++;
- }
- return isCA;
-}
-
-/*
- * Converts a X.500 generalName into an ID
- */
-void
-gntoid(struct id *id, const generalName_t *gn)
-{
- switch(gn->kind)
- {
- case GN_DNS_NAME: /* ID type: ID_FQDN */
- id->kind = ID_FQDN;
- id->name = gn->name;
- break;
- case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
- {
- const struct af_info *afi = &af_inet4_info;
- err_t ugh = NULL;
-
- id->kind = afi->id_addr;
- ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
- }
- break;
- case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
- id->kind = ID_USER_FQDN;
- id->name = gn->name;
- break;
- default:
- id->kind = ID_NONE;
- id->name = empty_chunk;
- }
-}
-
-/* compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
- * as the 160 bit SHA-1 hash of the public key
- */
-void
-compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
-{
- SHA1_CTX context;
-
- SHA1Init(&context);
- SHA1Update(&context
- , cert->subjectPublicKey.ptr
- , cert->subjectPublicKey.len);
- SHA1Final(subjectKeyID.ptr, &context);
- subjectKeyID.len = SHA1_DIGEST_SIZE;
-}
-
-/*
- * extracts an otherName
- */
-static bool
-parse_otherName(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
- int oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < ON_OBJ_ROOF)
- {
- if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case ON_OBJ_ID_TYPE:
- oid = known_oid(object);
- break;
- case ON_OBJ_VALUE:
- if (oid == OID_XMPP_ADDR)
- {
- if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING
- , level + 1, "xmppAddr"))
- {
- return FALSE;
- }
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-
-/*
- * extracts a generalName
- */
-static generalName_t*
-parse_generalName(chunk_t blob, int level0)
-{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < GN_OBJ_ROOF)
- {
- bool valid_gn = FALSE;
-
- if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- switch (objectID) {
- case GN_OBJ_RFC822_NAME:
- case GN_OBJ_DNS_NAME:
- case GN_OBJ_URI:
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", (int)object.len, object.ptr);
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_DIRECTORY_NAME:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'", buf)
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_IP_ADDRESS:
- DBG(DBG_PARSING,
- DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
- *(object.ptr+2), *(object.ptr+3));
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_OTHER_NAME:
- if (!parse_otherName(object, level + 1))
- return NULL;
- break;
- case GN_OBJ_X400_ADDRESS:
- case GN_OBJ_EDI_PARTY_NAME:
- case GN_OBJ_REGISTERED_ID:
- break;
- default:
- break;
- }
-
- if (valid_gn)
- {
- generalName_t *gn = alloc_thing(generalName_t, "generalName");
- gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
- gn->name = object;
- gn->next = NULL;
- return gn;
- }
- objectID++;
- }
- return NULL;
-}
-
-
-/*
- * extracts one or several GNs and puts them into a chained list
- */
-static generalName_t*
-parse_generalNames(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- generalName_t *top_gn = NULL;
-
- asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
-
- while (objectID < GENERAL_NAMES_ROOF)
- {
- if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- if (objectID == GENERAL_NAMES_GN)
- {
- generalName_t *gn = parse_generalName(object, level+1);
- if (gn != NULL)
- {
- gn->next = top_gn;
- top_gn = gn;
- }
- }
- objectID++;
- }
- return top_gn;
-}
-
-/*
- * returns a directoryName
- */
-chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
-{
- chunk_t name = empty_chunk;
- generalName_t * gn = parse_generalNames(blob, level, implicit);
-
- if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
- name= gn->name;
-
- free_generalNames(gn, FALSE);
-
- return name;
-}
-
-/*
- * extracts and converts a UTCTIME or GENERALIZEDTIME object
- */
-time_t
-parse_time(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < TIME_ROOF)
- {
- if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
- return UNDEFINED_TIME;
-
- if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
- {
- return asn1totime(&object, (objectID == TIME_UTC)
- ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
- }
- objectID++;
- }
- return UNDEFINED_TIME;
- }
-
-/*
- * extracts a keyIdentifier
- */
-static chunk_t
-parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
-
- extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
- return object;
-}
-
-/*
- * extracts an authoritykeyIdentifier
- */
-void
-parse_authorityKeyIdentifier(chunk_t blob, int level0
- , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < AUTH_KEY_ID_ROOF)
- {
- if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- case AUTH_KEY_ID_KEY_ID:
- *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
- break;
- case AUTH_KEY_ID_CERT_ISSUER:
- {
- generalName_t * gn = parse_generalNames(object, level+1, TRUE);
-
- free_generalNames(gn, FALSE);
- }
- break;
- case AUTH_KEY_ID_CERT_SERIAL:
- *authKeySerialNumber = object;
- break;
- default:
- break;
- }
- objectID++;
- }
-}
-
-/*
- * extracts an authorityInfoAcess location
- */
-static void
-parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- u_int accessMethod = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < AUTH_INFO_ACCESS_ROOF)
- {
- if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- case AUTH_INFO_ACCESS_METHOD:
- accessMethod = known_oid(object);
- break;
- case AUTH_INFO_ACCESS_LOCATION:
- {
- switch (accessMethod)
- {
- case OID_OCSP:
- if (*object.ptr == ASN1_CONTEXT_S_6)
- {
- if (asn1_length(&object) == ASN1_INVALID_LENGTH)
- return;
-
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'",(int)object.len, object.ptr)
- )
-
- /* only HTTP(S) URIs accepted */
- if (strncasecmp(object.ptr, "http", 4) == 0)
- {
- *accessLocation = object;
- return;
- }
- }
- plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
- break;
- default:
- /* unkown accessMethod, ignoring */
- break;
- }
- }
- break;
- default:
- break;
- }
- objectID++;
- }
-
-}
-
-/*
- * extracts extendedKeyUsage OIDs
- */
-static bool
-parse_extendedKeyUsage(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < EXT_KEY_USAGE_ROOF)
- {
- if (!extract_object(extendedKeyUsageObjects, &objectID
- , &object, &level, &ctx))
- return FALSE;
-
- if (objectID == EXT_KEY_USAGE_PURPOSE_ID
- && known_oid(object) == OID_OCSP_SIGNING)
- return TRUE;
- objectID++;
- }
- return FALSE;
-}
-
-/* extracts one or several crlDistributionPoints and puts them into
- * a chained list
- */
-static generalName_t*
-parse_crlDistributionPoints(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- generalName_t *top_gn = NULL; /* top of the chained list */
- generalName_t **tail_gn = &top_gn; /* tail of the chained list */
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < CRL_DIST_POINTS_ROOF)
- {
- if (!extract_object(crlDistributionPointsObjects, &objectID,
- &object, &level, &ctx))
- return NULL;
-
- if (objectID == CRL_DIST_POINTS_FULLNAME)
- {
- generalName_t *gn = parse_generalNames(object, level+1, TRUE);
- /* append extracted generalNames to existing chained list */
- *tail_gn = gn;
- /* find new tail of the chained list */
- while (gn != NULL)
- {
- tail_gn = &gn->next; gn = gn->next;
- }
- }
- objectID++;
- }
- return top_gn;
-}
-
-
-/*
- * Parses an X.509v3 certificate
- */
-bool
-parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
-{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- u_int extn_oid = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < X509_OBJ_ROOF)
- {
- if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID) {
- case X509_OBJ_CERTIFICATE:
- cert->certificate = object;
- break;
- case X509_OBJ_TBS_CERTIFICATE:
- cert->tbsCertificate = object;
- break;
- case X509_OBJ_VERSION:
- cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", cert->version);
- )
- break;
- case X509_OBJ_SERIAL_NUMBER:
- cert->serialNumber = object;
- break;
- case X509_OBJ_SIG_ALG:
- cert->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_ISSUER:
- cert->issuer = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case X509_OBJ_NOT_BEFORE:
- cert->notBefore = parse_time(object, level);
- break;
- case X509_OBJ_NOT_AFTER:
- cert->notAfter = parse_time(object, level);
- break;
- case X509_OBJ_SUBJECT:
- cert->subject = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
- if (parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
- cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
- else
- {
- plog(" unsupported public key algorithm");
- return FALSE;
- }
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY:
- if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
- {
- /* skip initial bit string octet defining 0 unused bits */
- ctx.blobs[4].ptr++; ctx.blobs[4].len--;
- }
- else
- {
- plog(" invalid RSA public key format");
- return FALSE;
- }
- break;
- case X509_OBJ_RSA_PUBLIC_KEY:
- cert->subjectPublicKey = object;
- break;
- case X509_OBJ_MODULUS:
- if (object.len < RSA_MIN_OCTETS + 1)
- {
- plog(" " RSA_MIN_OCTETS_UGH);
- return FALSE;
- }
- if (object.len > RSA_MAX_OCTETS + (size_t)(*object.ptr == 0x00))
- {
- plog(" " RSA_MAX_OCTETS_UGH);
- return FALSE;
- }
- cert->modulus = object;
- break;
- case X509_OBJ_PUBLIC_EXPONENT:
- cert->publicExponent = object;
- break;
- case X509_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case X509_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case X509_OBJ_EXTN_VALUE:
- {
- switch (extn_oid) {
- case OID_SUBJECT_KEY_ID:
- cert->subjectKeyID =
- parse_keyIdentifier(object, level, FALSE);
- break;
- case OID_SUBJECT_ALT_NAME:
- cert->subjectAltName =
- parse_generalNames(object, level, FALSE);
- break;
- case OID_BASIC_CONSTRAINTS:
- cert->isCA =
- parse_basicConstraints(object, level);
- break;
- case OID_CRL_DISTRIBUTION_POINTS:
- cert->crlDistributionPoints =
- parse_crlDistributionPoints(object, level);
- break;
- case OID_AUTHORITY_KEY_ID:
- parse_authorityKeyIdentifier(object, level
- , &cert->authKeyID, &cert->authKeySerialNumber);
- break;
- case OID_AUTHORITY_INFO_ACCESS:
- parse_authorityInfoAccess(object, level, &cert->accessLocation);
- break;
- case OID_EXTENDED_KEY_USAGE:
- cert->isOcspSigner = parse_extendedKeyUsage(object, level);
- break;
- case OID_NS_REVOCATION_URL:
- case OID_NS_CA_REVOCATION_URL:
- case OID_NS_CA_POLICY_URL:
- case OID_NS_COMMENT:
- if (!parse_asn1_simple_object(&object, ASN1_IA5STRING
- , level, oid_names[extn_oid].name))
- {
- return FALSE;
- }
- break;
- default:
- break;
- }
- }
- break;
- case X509_OBJ_ALGORITHM:
- cert->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_SIGNATURE:
- cert->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- time(&cert->installed);
- return TRUE;
-}
-
-/* verify the validity of a certificate by
- * checking the notBefore and notAfter dates
- */
-err_t
-check_validity(const x509cert_t *cert, time_t *until)
-{
- time_t current_time;
-
- time(&current_time);
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" not before : %s", timetoa(&cert->notBefore, TRUE));
- DBG_log(" current time: %s", timetoa(&current_time, TRUE));
- DBG_log(" not after : %s", timetoa(&cert->notAfter, TRUE));
- )
-
- if (cert->notAfter < *until) *until = cert->notAfter;
-
- if (current_time < cert->notBefore)
- return "certificate is not valid yet";
- if (current_time > cert->notAfter)
- return "certificate has expired";
- else
- return NULL;
-}
-
-/*
- * verifies a X.509 certificate
- */
-bool
-verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
-{
- int pathlen;
-
- *until = cert->notAfter;
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- x509cert_t *issuer_cert;
- u_char buf[BUF_LEN];
- err_t ugh = NULL;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
-
- ugh = check_validity(cert, until);
-
- if (ugh != NULL)
- {
- plog("%s", ugh);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
-
- lock_authcert_list("verify_x509cert");
- issuer_cert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
-
- if (issuer_cert == NULL)
- {
- plog("issuer cacert not found");
- unlock_authcert_list("verify_x509cert");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
- )
-
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, issuer_cert))
- {
- plog("certificate signature is invalid");
- unlock_authcert_list("verify_x509cert");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
- )
- unlock_authcert_list("verify_x509cert");
-
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
- {
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- return TRUE;
- }
- else
- {
- time_t nextUpdate = *until;
- time_t revocationDate = UNDEFINED_TIME;
- crl_reason_t revocationReason = REASON_UNSPECIFIED;
-
- /* first check certificate revocation using ocsp */
- cert_status_t status = verify_by_ocsp(cert, &nextUpdate
- , &revocationDate, &revocationReason);
-
- /* if ocsp service is not available then fall back to crl */
- if ((status == CERT_UNDEFINED)
- || (status == CERT_UNKNOWN && strict))
- {
- status = verify_by_crl(cert, &nextUpdate, &revocationDate
- , &revocationReason);
- }
-
- switch (status)
- {
- case CERT_GOOD:
- /* if status information is stale */
- if (strict && nextUpdate < time(NULL))
- {
- DBG(DBG_CONTROL,
- DBG_log("certificate is good but status is stale")
- )
- remove_x509_public_key(cert);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate is good")
- )
-
- /* with strict crl policy the public key must have the same
- * lifetime as the validity of the ocsp status or crl lifetime
- */
- if (strict && nextUpdate < *until)
- *until = nextUpdate;
- break;
- case CERT_REVOKED:
- plog("certificate was revoked on %s, reason: %s"
- , timetoa(&revocationDate, TRUE)
- , enum_name(&crl_reason_names, revocationReason));
- remove_x509_public_key(cert);
- return FALSE;
- case CERT_UNKNOWN:
- case CERT_UNDEFINED:
- default:
- plog("certificate status unknown");
- if (strict)
- {
- remove_x509_public_key(cert);
- return FALSE;
- }
- break;
- }
- }
-
- /* go up one step in the trust chain */
- cert = issuer_cert;
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- return FALSE;
-}
-
-/*
- * list all X.509 certs in a chained list
- */
-void
-list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
- , bool utc)
-{
- bool first = TRUE;
- time_t now;
-
- /* determine the current time */
- time(&now);
-
- while (cert != NULL)
- {
- if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
- {
- unsigned keysize;
- char keyid[KEYID_BUF];
- u_char buf[BUF_LEN];
- cert_t c;
-
- c.type = CERT_X509_SIGNATURE;
- c.u.x509 = cert;
-
- if (first)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 %s Certificates:", caption);
- whack_log(RC_COMMENT, " ");
- first = FALSE;
- }
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc),
- cert->count);
- dntoa(buf, BUF_LEN, cert->subject);
- whack_log(RC_COMMENT, " subject: '%s'", buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s", buf);
- form_keyid(cert->publicExponent, cert->modulus, keyid, &keysize);
- whack_log(RC_COMMENT, " pubkey: %4d RSA Key %s%s"
- , 8*keysize, keyid
- , cert->smartcard ? ", on smartcard" :
- (has_private_key(c)? ", has private key" : ""));
- whack_log(RC_COMMENT, " validity: not before %s %s",
- timetoa(&cert->notBefore, utc),
- (cert->notBefore < now)?"ok":"fatal (not valid yet)");
- whack_log(RC_COMMENT, " not after %s %s",
- timetoa(&cert->notAfter, utc),
- check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
- if (cert->subjectKeyID.ptr != NULL)
- {
- datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " subjkey: %s", buf);
- }
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (cert->authKeySerialNumber.ptr != NULL)
- {
- datatot(cert->authKeySerialNumber.ptr, cert->authKeySerialNumber.len
- , ':', buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
- }
- cert = cert->next;
- }
-}
-
-/*
- * list all X.509 end certificates in a chained list
- */
-void
-list_x509_end_certs(bool utc)
-{
- list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
-}
diff --git a/programs/pluto/x509.h b/programs/pluto/x509.h
deleted file mode 100644
index d15b3da53..000000000
--- a/programs/pluto/x509.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Support of X.509 certificates
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: x509.h,v 1.10 2005/12/06 22:52:44 as Exp $
- */
-
-#ifndef _X509_H
-#define _X509_H
-
-#include "pkcs1.h"
-#include "id.h"
-
-/* Definition of generalNames kinds */
-
-typedef enum {
- GN_OTHER_NAME = 0,
- GN_RFC822_NAME = 1,
- GN_DNS_NAME = 2,
- GN_X400_ADDRESS = 3,
- GN_DIRECTORY_NAME = 4,
- GN_EDI_PARTY_NAME = 5,
- GN_URI = 6,
- GN_IP_ADDRESS = 7,
- GN_REGISTERED_ID = 8
-} generalNames_t;
-
-/* access structure for a GeneralName */
-
-typedef struct generalName generalName_t;
-
-struct generalName {
- generalName_t *next;
- generalNames_t kind;
- chunk_t name;
-};
-
-/* access structure for an X.509v3 certificate */
-
-typedef struct x509cert x509cert_t;
-
-struct x509cert {
- x509cert_t *next;
- time_t installed;
- int count;
- bool smartcard;
- u_char authority_flags;
- chunk_t certificate;
- chunk_t tbsCertificate;
- u_int version;
- chunk_t serialNumber;
- /* signature */
- int sigAlg;
- chunk_t issuer;
- /* validity */
- time_t notBefore;
- time_t notAfter;
- chunk_t subject;
- /* subjectPublicKeyInfo */
- enum pubkey_alg subjectPublicKeyAlgorithm;
- chunk_t subjectPublicKey;
- chunk_t modulus;
- chunk_t publicExponent;
- /* issuerUniqueID */
- /* subjectUniqueID */
- /* v3 extensions */
- /* extension */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- bool isCA;
- bool isOcspSigner; /* ocsp */
- chunk_t subjectKeyID;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- chunk_t accessLocation; /* ocsp */
- generalName_t *subjectAltName;
- generalName_t *crlDistributionPoints;
- /* signatureAlgorithm */
- int algorithm;
- chunk_t signature;
-};
-
-/* used for initialization */
-extern const x509cert_t empty_x509cert;
-
-extern bool same_serial(chunk_t a, chunk_t b);
-extern bool same_keyid(chunk_t a, chunk_t b);
-extern bool same_dn(chunk_t a, chunk_t b);
-extern bool match_dn(chunk_t a, chunk_t b, int *wildcards);
-extern bool same_x509cert(const x509cert_t *a, const x509cert_t *b);
-extern void hex_str(chunk_t bin, chunk_t *str);
-extern int dn_count_wildcards(chunk_t dn);
-extern int dntoa(char *dst, size_t dstlen, chunk_t dn);
-extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn
- , const char* null_dn);
-extern err_t atodn(char *src, chunk_t *dn);
-extern void gntoid(struct id *id, const generalName_t *gn);
-extern void compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
-extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
-extern bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert);
-extern time_t parse_time(chunk_t blob, int level0);
-extern void parse_authorityKeyIdentifier(chunk_t blob, int level0
- , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
-extern chunk_t get_directoryName(chunk_t blob, int level, bool implicit);
-extern err_t check_validity(const x509cert_t *cert, time_t *until);
-extern bool check_signature(chunk_t tbs, chunk_t sig, int digest_alg
- , int enc_alg, const x509cert_t *issuer_cert);
-extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until);
-extern x509cert_t* add_x509cert(x509cert_t *cert);
-extern x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid
- , x509cert_t* chain);
-extern void build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
- , const RSA_private_key_t *signer_key);
-extern chunk_t build_subjectAltNames(generalName_t *subjectAltNames);
-extern void share_x509cert(x509cert_t *cert);
-extern void release_x509cert(x509cert_t *cert);
-extern void free_x509cert(x509cert_t *cert);
-extern void store_x509certs(x509cert_t **firstcert, bool strict);
-extern void list_x509cert_chain(const char *caption, x509cert_t* cert
- , u_char auth_flags, bool utc);
-extern void list_x509_end_certs(bool utc);
-extern void free_generalNames(generalName_t* gn, bool free_name);
-
-#endif /* _X509_H */
diff --git a/programs/pluto/xauth.c b/programs/pluto/xauth.c
deleted file mode 100644
index c33ad9b3d..000000000
--- a/programs/pluto/xauth.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Initialization and finalization of the dynamic XAUTH module
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: xauth.c,v 1.1 2007/01/11 21:48:41 as Exp $
- */
-
-#include <dlfcn.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "xauth.h"
-#include "keys.h"
-#include "log.h"
-
-void
-xauth_init(void)
-{
-#ifdef XAUTH_DEFAULT_LIB
- xauth_module.handle = dlopen(XAUTH_DEFAULT_LIB, RTLD_NOW);
-
- if (xauth_module.handle != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module '%s' loading'", XAUTH_DEFAULT_LIB)
- )
- xauth_module.get_secret = (bool (*) (const xauth_t*))
- dlsym(xauth_module.handle, "get_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.get_secret != NULL)
- {
- DBG_log("xauth module: found get_secret() function");
- }
- )
- xauth_module.verify_secret = (bool (*) (const xauth_t*))
- dlsym(xauth_module.handle, "verify_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.verify_secret != NULL)
- {
- DBG_log("xauth module: found verify_secret() function");
- }
- )
- }
-#endif
- /* any null function pointers will be filled in by default functions */
- xauth_defaults();
-}
-
-void
-xauth_finalize(void)
-{
- if (xauth_module.handle != NULL)
- {
- if (dlclose(xauth_module.handle))
- {
- plog("failed to unload xauth module");
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module unloaded")
- )
- }
- }
-}
diff --git a/programs/pluto/xauth.h b/programs/pluto/xauth.h
deleted file mode 100644
index 371e443ef..000000000
--- a/programs/pluto/xauth.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Interface definition of the XAUTH server and|or client module
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: xauth.h,v 1.1 2007/01/11 21:48:41 as Exp $
- */
-
-#ifndef _XAUTH_H
-#define _XAUTH_H
-
-/* XAUTH credentials */
-
-struct chunk_t;
-
-typedef struct {
- chunk_t user_name;
- chunk_t user_password;
-} xauth_t;
-
-typedef struct {
- void *handle;
- bool (*get_secret) (xauth_t *xauth_secret);
- bool (*verify_secret) (const xauth_t *xauth_secret);
-} xauth_module_t;
-
-extern xauth_module_t xauth_module;
-
-extern void xauth_init(void);
-extern void xauth_finalize(void);
-
-#endif /* _XAUTH_H */
diff --git a/programs/proc/Makefile b/programs/proc/Makefile
deleted file mode 100644
index 023356440..000000000
--- a/programs/proc/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:30 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-EXTRA5PROC:=version.5 trap_count.5 trap_sendcount.5
-
-LIBS:=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:30 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.5 2003/06/20 02:56:20 mcr
-# added documentation for /proc/net/ipsec/stats/trap_* and
-# amendments to test cases.
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/05/05 23:09:49 mcr
-# EXTRA35MAN should have the extensions on it.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/proc/trap_count.5 b/programs/proc/trap_count.5
deleted file mode 100644
index e4cfd5871..000000000
--- a/programs/proc/trap_count.5
+++ /dev/null
@@ -1,35 +0,0 @@
-.TH IPSEC_TRAP_COUNT 5 "19 Jun 2003"
-.\"
-.\" RCSID $Id: trap_count.5,v 1.1 2004/03/15 20:35:30 as Exp $
-.\"
-.SH NAME
-trap_count \- KLIPS statistic on number of ACQUIREs
-.SH SYNOPSIS
-.B cat
-.B /proc/net/ipsec/stats/trap_count
-.SH DESCRIPTION
-.I /proc/net/ipsec/stats/trap_count
-is a read-only file. It contains a hexadecimal number which records the
-number of attempts to send PF_ACQUIRE messages. Only those recorded by
-trap_sendcount were actually successfully passed to userland. Note that the
-userland may still have lost them on its own.
-.LP
-.SH "FILES"
-/proc/net/ipsec/stats/trap_sendcount
-.SH "SEE ALSO"
-ipsec(8), ipsec_pf_key(5), trap_sendcount(5), pluto(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Michael C. Richardson <mcr@freeswan.org>
-.\"
-.\" $Log: trap_count.5,v $
-.\" Revision 1.1 2004/03/15 20:35:30 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.1 2003/06/20 02:56:20 mcr
-.\" added documentation for /proc/net/ipsec/stats/trap_* and
-.\" amendments to test cases.
-.\"
-.\"
-.\"
diff --git a/programs/proc/trap_sendcount.5 b/programs/proc/trap_sendcount.5
deleted file mode 100644
index 27090b52b..000000000
--- a/programs/proc/trap_sendcount.5
+++ /dev/null
@@ -1,33 +0,0 @@
-.TH IPSEC_TRAP_SENDCOUNT 5 "19 Jun 2003"
-.\"
-.\" RCSID $Id: trap_sendcount.5,v 1.1 2004/03/15 20:35:30 as Exp $
-.\"
-.SH NAME
-trap_sendcount \- KLIPS statistic on number of successful ACQUIREs
-.SH SYNOPSIS
-.B cat
-.B /proc/net/ipsec/stats/trap_sendcount
-.SH DESCRIPTION
-.I /proc/net/ipsec/stats/trap_sendcount
-is a read-only file. It contains a hexadecimal number which records the
-number of successful PF_ACQUIRE messages that were sent.
-.LP
-.SH "FILES"
-/proc/net/ipsec/stats/trap_sendcount
-.SH "SEE ALSO"
-ipsec(8), ipsec_pf_key(5), trap_count(5), pluto(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Michael C. Richardson <mcr@freeswan.org>
-.\"
-.\" $Log: trap_sendcount.5,v $
-.\" Revision 1.1 2004/03/15 20:35:30 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.1 2003/06/20 02:56:20 mcr
-.\" added documentation for /proc/net/ipsec/stats/trap_* and
-.\" amendments to test cases.
-.\"
-.\"
-.\"
diff --git a/programs/proc/version.5 b/programs/proc/version.5
deleted file mode 100644
index c763d6d17..000000000
--- a/programs/proc/version.5
+++ /dev/null
@@ -1,54 +0,0 @@
-.TH IPSEC_VERSION 5 "29 Jun 2000"
-.\"
-.\" RCSID $Id: version.5,v 1.1 2004/03/15 20:35:30 as Exp $
-.\"
-.SH NAME
-ipsec_version \- lists KLIPS version information
-.SH SYNOPSIS
-.B cat
-.B /proc/net/ipsec_version
-.SH DESCRIPTION
-.I /proc/net/ipsec_version
-is a read-only file which lists the currently running KLIPS version
-information.
-.PP
-.SH EXAMPLES
-.TP
-.B FreeS/WAN version: 1.4
-.LP
-shows that the currently loaded
-.B KLIPS
-is from
-.B FreeS/WAN 1.4.
-.LP
-.SH "FILES"
-/proc/net/ipsec_version
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_eroute(5), ipsec_spi(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_tncfg(8), ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: version.5,v $
-.\" Revision 1.1 2004/03/15 20:35:30 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.4 2002/04/24 07:35:41 mcr
-.\" Moved from ./klips/utils/version.5,v
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/30 06:22:22 rgb
-.\" Fix SYNOPSIS since there is no 'ipsec version' command.
-.\"
-.\" Revision 1.1 2000/06/30 06:19:26 rgb
-.\" manpages for the last two /proc/net/ipsec* files that don't have a
-.\" corresponding utility.
-.\"
-.\"
-.\"
diff --git a/programs/ranbits/.cvsignore b/programs/ranbits/.cvsignore
deleted file mode 100644
index 910103faa..000000000
--- a/programs/ranbits/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-ranbits
diff --git a/programs/ranbits/Makefile b/programs/ranbits/Makefile
deleted file mode 100644
index 558318e8e..000000000
--- a/programs/ranbits/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:30 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=ranbits
-LIBS=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:30 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/ranbits/ranbits.8 b/programs/ranbits/ranbits.8
deleted file mode 100644
index 5a99a088f..000000000
--- a/programs/ranbits/ranbits.8
+++ /dev/null
@@ -1,77 +0,0 @@
-.TH IPSEC_RANBITS 8 "22 Aug 2000"
-.\" RCSID $Id: ranbits.8,v 1.1 2004/03/15 20:35:30 as Exp $
-.SH NAME
-ipsec ranbits \- generate random bits in ASCII form
-.SH SYNOPSIS
-.B ipsec
-.B ranbits
-[
-.B \-\-quick
-] [
-.B \-\-continuous
-] [
-.B \-\-bytes
-] nbits
-.SH DESCRIPTION
-.I Ranbits
-obtains
-.I nbits
-(rounded up to the nearest byte)
-high-quality random bits from
-.IR random (4),
-and emits them on standard output as an ASCII string.
-The default output format is
-.IR datatot (3)
-.B h
-format:
-lowercase hexadecimal with a
-.B 0x
-prefix and an underscore every 32 bits.
-.PP
-The
-.B \-\-quick
-option produces quick-and-dirty random bits:
-instead of using the high-quality random bits from
-.IR /dev/random ,
-which may take some time to supply the necessary bits if
-.I nbits
-is large,
-.I ranbits
-uses
-.IR /dev/urandom ,
-which yields prompt results but lower-quality randomness.
-.PP
-The
-.B \-\-continuous
-option uses
-.IR datatot (3)
-.B x
-output format, like
-.B h
-but without the underscores.
-.PP
-The
-.B \-\-bytes
-option causes
-.I nbits
-to be interpreted as a byte count rather than a bit count.
-.SH FILES
-/dev/random, /dev/urandom
-.SH SEE ALSO
-ipsec_datatot(3), random(4)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-.SH BUGS
-There is an internal limit on
-.IR nbits ,
-currently 20000.
-.PP
-Without
-.BR \-\-quick ,
-.IR ranbits 's
-run time is difficult to predict.
-A request for a large number of bits,
-at a time when the system's entropy pool is low on randomness,
-may take quite a while to satisfy.
diff --git a/programs/ranbits/ranbits.c b/programs/ranbits/ranbits.c
deleted file mode 100644
index 7b9a0f76e..000000000
--- a/programs/ranbits/ranbits.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * random bit generation for scripts, control files, etc.
- * Copyright (C) 1998, 1999, 2000 Henry Spencer.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ranbits.c,v 1.1 2004/03/15 20:35:30 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <limits.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <freeswan.h>
-
-#ifndef DEVICE
-#define DEVICE "/dev/random"
-#endif
-#ifndef QDEVICE
-#define QDEVICE "/dev/urandom"
-#endif
-#ifndef MAXBITS
-#define MAXBITS 20000
-#endif
-
-char usage[] = "Usage: ranbits [--quick] [--continuous] [--bytes] nbits";
-struct option opts[] = {
- {"quick", 0, NULL, 'q',},
- {"continuous", 0, NULL, 'c',},
- {"bytes", 0, NULL, 'b',},
- {"help", 0, NULL, 'h',},
- {"version", 0, NULL, 'v',},
- {0, 0, NULL, 0,}
-};
-int quick = 0; /* quick and dirty? */
-char format = 'h'; /* datatot() format code */
-int isbytes = 0; /* byte count rather than bits? */
-
-char me[] = "ipsec ranbits"; /* for messages */
-
-char buf[MAXBITS/CHAR_BIT];
-char outbuf[3*sizeof(buf)];
-
-int main(int argc, char *argv[])
-{
- int opt;
- extern int optind;
- int errflg = 0;
- int nbits;
- size_t nbytes;
- char *devname;
- int dev;
- size_t ndone;
- size_t nneeded;
- ssize_t got;
-
- while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
- switch (opt) {
- case 'q': /* quick and dirty randomness */
- quick = 1;
- break;
- case 'c': /* continuous hex, no underscores */
- format = 'x';
- break;
- case 'b': /* byte count, not bit count */
- isbytes = 1;
- break;
- case 'h': /* help */
- printf("%s\n", usage);
- exit(0);
- break;
- case 'v': /* version */
- printf("%s %s\n", me, ipsec_version_code());
- exit(0);
- break;
- case '?':
- default:
- errflg = 1;
- break;
- }
- if (errflg || optind != argc-1) {
- fprintf(stderr, "%s\n", usage);
- exit(2);
- }
-
- nbits = atoi(argv[optind]);
- if (isbytes)
- nbits *= CHAR_BIT;
- if (nbits <= 0) {
- fprintf(stderr, "%s: invalid bit count (%d)\n", me, nbits);
- exit(1);
- }
- if (nbits > MAXBITS) {
- fprintf(stderr, "%s: overlarge bit count (max %d)\n", me,
- MAXBITS);
- exit(1);
- }
- nbytes = (size_t)(nbits + CHAR_BIT - 1) / CHAR_BIT;
-
- devname = (quick) ? QDEVICE : DEVICE;
- dev = open(devname, 0);
- if (dev < 0) {
- fprintf(stderr, "%s: could not open %s (%s)\n", me,
- devname, strerror(errno));
- exit(1);
- }
-
- ndone = 0;
- while (ndone < nbytes) {
- got = read(dev, buf + ndone, nbytes - ndone);
- if (got < 0) {
- fprintf(stderr, "%s: read error on %s (%s)\n", me,
- devname, strerror(errno));
- exit(1);
- }
- if (got == 0) {
- fprintf(stderr, "%s: eof on %s!?!\n", me, devname);
- exit(1);
- }
- ndone += got;
- }
-
- nneeded = datatot(buf, nbytes, format, outbuf, sizeof(outbuf));
- if (nneeded > sizeof(outbuf)) {
- fprintf(stderr, "%s: buffer overflow (need %ld bytes)?!?\n",
- me, (long)nneeded);
- exit(1);
- }
- printf("%s\n", outbuf);
- exit(0);
-}
diff --git a/programs/rsasigkey/.cvsignore b/programs/rsasigkey/.cvsignore
deleted file mode 100644
index f9e610b4d..000000000
--- a/programs/rsasigkey/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-rsasigkey
diff --git a/programs/rsasigkey/Makefile b/programs/rsasigkey/Makefile
deleted file mode 100644
index c2b82e5c8..000000000
--- a/programs/rsasigkey/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:30 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=rsasigkey
-LIBS=${FREESWANLIB} -lgmp
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:30 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/rsasigkey/rsasigkey.8 b/programs/rsasigkey/rsasigkey.8
deleted file mode 100644
index c64dd46bd..000000000
--- a/programs/rsasigkey/rsasigkey.8
+++ /dev/null
@@ -1,259 +0,0 @@
-.TH IPSEC_RSASIGKEY 8 "22 July 2001"
-.\" RCSID $Id: rsasigkey.8,v 1.1 2004/03/15 20:35:30 as Exp $
-.SH NAME
-ipsec rsasigkey \- generate RSA signature key
-.SH SYNOPSIS
-.B ipsec
-.B rsasigkey
-[
-.B \-\-verbose
-] [
-.B \-\-random
-filename
-]
-.B \e
-.br
-\ \ \ [
-.B \-\-rounds
-nr
-] [
-.B \-\-hostname
-host ] [
-.B \-\-noopt
-] nbits
-.br
-.B ipsec
-.B rsasigkey
-[
-.B \-\-verbose
-] [
-.B \-\-hostname
-host ]
-.B \e
-.br
-\ \ \
-[
-.B \-\-noopt
-]
-.B \-\-oldkey
-file
-.SH DESCRIPTION
-.I Rsasigkey
-generates an RSA public/private key pair,
-suitable for digital signatures,
-of (exactly)
-.I nbits
-bits (that is, two primes each of exactly
-.IR nbits /2
-bits,
-and related numbers)
-and emits it on standard output as ASCII (mostly hex) data.
-.I nbits
-must be a multiple of 16.
-.PP
-The public exponent is forced to the value
-.BR 3 ,
-which has important speed advantages for signature checking.
-Beware that the resulting keys have known weaknesses as encryption keys
-\fIand should not be used for that purpose\fR.
-.PP
-The
-.B \-\-verbose
-option makes
-.I rsasigkey
-give a running commentary on standard error.
-By default, it works in silence until it is ready to generate output.
-.PP
-The
-.B \-\-random
-option specifies a source for random bits.
-The default is
-.I /dev/random
-(see
-.IR random (4)).
-Normally,
-.I rsasigkey
-reads exactly
-.I nbits
-random bits from the source;
-in extremely-rare circumstances it may need more.
-.PP
-The
-.B \-\-rounds
-option specifies the number of rounds to be done by the
-.I mpz_probab_prime_p
-probabilistic primality checker.
-The default, 30, is fairly rigorous and should not normally
-have to be overridden.
-.PP
-The
-.B \-\-hostname
-option specifies what host name to use in
-the first line of the output (see below);
-the default is what
-.IR gethostname (2)
-returns.
-.PP
-The
-.B \-\-noopt
-option suppresses an optimization of the private key
-(to be precise, setting of the decryption exponent to
-.B lcm(p\-1,q\-1)
-rather than
-.BR (p\-1)*(q\-1) )
-which speeds up operations on it slightly
-but can cause it to flunk a validity check in old RSA implementations
-(notably, obsolete versions of
-.IR ipsec_pluto (8)).
-.PP
-The
-.B \-\-oldkey
-option specifies that rather than generate a new key,
-.I rsasigkey
-should read an old key from the
-.I file
-(the name
-.B \-
-means ``standard input'')
-and use that to generate its output.
-Input lines which do not look like
-.I rsasigkey
-output are silently ignored.
-This permits updating old keys to the current format.
-.PP
-The output format looks like this (with long numbers trimmed down
-for clarity):
-.PP
-.ne 15
-.nf
- # RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000
- # for signatures only, UNSAFE FOR ENCRYPTION
- #pubkey=0sAQOF8tZ2NZt...Y1P+buFuFn/
- Modulus: 0xcc2a86fcf440...cf1011abb82d1
- PublicExponent: 0x03
- # everything after this point is secret
- PrivateExponent: 0x881c59fdf8...ab05c8c77d23
- Prime1: 0xf49fd1f779...46504c7bf3
- Prime2: 0xd5a9108453...321d43cb2b
- Exponent1: 0xa31536a4fb...536d98adda7f7
- Exponent2: 0x8e70b5ad8d...9142168d7dcc7
- Coefficient: 0xafb761d001...0c13e98d98
-.fi
-.PP
-The first (comment) line,
-indicating the nature and date of the key,
-and giving a host name,
-is used by
-.IR ipsec_showhostkey (8)
-when generating some forms of key output.
-.PP
-The commented-out
-.B pubkey=
-line contains the public key\(emthe public exponent and the modulus\(emcombined
-in approximately RFC 2537 format
-(the one deviation is that the combined value is given with a
-.B 0s
-prefix, rather than in unadorned base-64),
-suitable for use in the
-.I ipsec.conf
-file.
-.PP
-The
-.BR Modulus ,
-.BR PublicExponent ,
-and
-.B PrivateExponent
-lines give the basic signing and verification data.
-.PP
-The
-.B Prime1
-and
-.B Prime2
-lines give the primes themselves (aka
-.I p
-and
-.IR q ),
-largest first.
-The
-.B Exponent1
-and
-.B Exponent2
-lines give
-the private exponent mod
-.IR p\-1
-and
-.IR q\-1
-respectively.
-The
-.B Coefficient
-line gives the Chinese Remainder Theorem coefficient,
-which is the inverse of
-.IR q ,
-mod
-.IR p .
-These additional numbers (which must all be kept as secret as the
-private exponent) are precomputed aids to rapid signature generation.
-.PP
-No attempt is made to break long lines.
-.PP
-The US patent on the RSA algorithm expired 20 Sept 2000.
-.SH EXAMPLES
-.TP
-.B "ipsec rsasigkey \-\-verbose 2192 >mykey"
-generates a 2192-bit signature key and puts it in the file
-.IR mykey ,
-with running commentary on standard error.
-The file contents can be inserted verbatim into a suitable entry in the
-.I ipsec.secrets
-file (see
-.IR ipsec.secrets (5)),
-and the public key can then be extracted and edited into the
-.I ipsec.conf
-file (see
-.IR ipsec.conf (5)).
-.TP
-.B "ipsec rsasigkey \-\-verbose \-\-oldkey oldie >latest"
-takes the old signature key from file
-.I oldie
-and puts a version in the current format into the file
-.IR latest ,
-with running commentary on standard error.
-.SH FILES
-/dev/random
-.SH SEE ALSO
-random(4), ipsec_showhostkey(8)
-.br
-\fIApplied Cryptography\fR, 2nd. ed., by Bruce Schneier, Wiley 1996.
-.br
-RFCs 2537, 2313.
-.br
-\fIGNU MP, the GNU multiple precision arithmetic library, edition 2.0.2\fR,
-by Torbj Granlund.
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-.SH BUGS
-There is an internal limit on
-.IR nbits ,
-currently 20000.
-.PP
-.IR Rsasigkey 's
-run time is difficult to predict,
-since
-.I /dev/random
-output can be arbitrarily delayed if
-the system's entropy pool is low on randomness,
-and the time taken by the search for primes is also somewhat unpredictable.
-A reasonably typical time for a 1024-bit key on a quiet 200MHz Pentium MMX
-with plenty of randomness available is 20 seconds,
-almost all of it in the prime searches.
-Generating a 2192-bit key on the same system usually takes several minutes.
-A 4096-bit key took an hour and a half of CPU time.
-.PP
-The
-.B \-\-oldkey
-option does not check its input format as rigorously as it might.
-Corrupted
-.I rsasigkey
-output may confuse it.
diff --git a/programs/rsasigkey/rsasigkey.c b/programs/rsasigkey/rsasigkey.c
deleted file mode 100644
index b55dbb889..000000000
--- a/programs/rsasigkey/rsasigkey.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * RSA signature key generation
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rsasigkey.c,v 1.2 2005/08/11 10:35:58 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <time.h>
-#include <limits.h>
-#include <errno.h>
-#include <string.h>
-#include <assert.h>
-#include <getopt.h>
-#include <freeswan.h>
-#include "gmp.h"
-
-#ifndef DEVICE
-#define DEVICE "/dev/random"
-#endif
-#ifndef MAXBITS
-#define MAXBITS 20000
-#endif
-
-/* the code in getoldkey() knows about this */
-#define E 3 /* standard public exponent */
-
-char usage[] = "rsasigkey [--verbose] [--random device] nbits";
-char usage2[] = "rsasigkey [--verbose] --oldkey filename";
-struct option opts[] = {
- {"verbose", 0, NULL, 'v',},
- {"random", 1, NULL, 'r',},
- {"rounds", 1, NULL, 'p',},
- {"oldkey", 1, NULL, 'o',},
- {"hostname", 1, NULL, 'H',},
- {"noopt", 0, NULL, 'n',},
- {"help", 0, NULL, 'h',},
- {"version", 0, NULL, 'V',},
- {0, 0, NULL, 0,}
-};
-int verbose = 0; /* narrate the action? */
-char *device = DEVICE; /* where to get randomness */
-int nrounds = 30; /* rounds of prime checking; 25 is good */
-mpz_t prime1; /* old key's prime1 */
-mpz_t prime2; /* old key's prime2 */
-char outputhostname[1024]; /* hostname for output */
-int do_lcm = 1; /* use lcm(p-1, q-1), not (p-1)*(q-1) */
-
-char me[] = "ipsec rsasigkey"; /* for messages */
-
-/* forwards */
-int getoldkey(char *filename);
-void rsasigkey(int nbits, int useoldkey);
-void initprime(mpz_t var, int nbits, int eval);
-void initrandom(mpz_t var, int nbits);
-void getrandom(size_t nbytes, char *buf);
-char *bundle(int e, mpz_t n, size_t *sizep);
-char *conv(char *bits, size_t nbytes, int format);
-char *hexout(mpz_t var);
-void report(char *msg);
-
-/*
- - main - mostly argument parsing
- */
-int main(int argc, char *argv[])
-{
- int opt;
- extern int optind;
- extern char *optarg;
- int errflg = 0;
- int i;
- int nbits;
- char *oldkeyfile = NULL;
-
- while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
- switch (opt) {
- case 'v': /* verbose description */
- verbose = 1;
- break;
- case 'r': /* nonstandard /dev/random */
- device = optarg;
- break;
- case 'p': /* number of prime-check rounds */
- nrounds = atoi(optarg);
- if (nrounds <= 0) {
- fprintf(stderr, "%s: rounds must be > 0\n", me);
- exit(2);
- }
- break;
- case 'o': /* reformat old key */
- oldkeyfile = optarg;
- break;
- case 'H': /* set hostname for output */
- strcpy(outputhostname, optarg);
- break;
- case 'n': /* don't optimize the private key */
- do_lcm = 0;
- break;
- case 'h': /* help */
- printf("Usage:\t%s\n", usage);
- printf("\tor\n");
- printf("\t%s\n", usage2);
- exit(0);
- break;
- case 'V': /* version */
- printf("%s %s\n", me, ipsec_version_code());
- exit(0);
- break;
- case '?':
- default:
- errflg = 1;
- break;
- }
- if (errflg || optind != ((oldkeyfile != NULL) ? argc : argc-1)) {
- printf("Usage:\t%s\n", usage);
- printf("\tor\n");
- printf("\t%s\n", usage2);
- exit(2);
- }
-
- if (outputhostname[0] == '\0') {
- i = gethostname(outputhostname, sizeof(outputhostname));
- if (i < 0) {
- fprintf(stderr, "%s: gethostname failed (%s)\n",
- me,
- strerror(errno));
- exit(1);
- }
- }
-
- if (oldkeyfile == NULL) {
- assert(argv[optind] != NULL);
- nbits = atoi(argv[optind]);
- } else
- nbits = getoldkey(oldkeyfile);
-
- if (nbits <= 0) {
- fprintf(stderr, "%s: invalid bit count (%d)\n", me, nbits);
- exit(1);
- } else if (nbits > MAXBITS) {
- fprintf(stderr, "%s: overlarge bit count (max %d)\n", me,
- MAXBITS);
- exit(1);
- } else if (nbits % (CHAR_BIT*2) != 0) { /* *2 for nbits/2-bit primes */
- fprintf(stderr, "%s: bit count (%d) not multiple of %d\n", me,
- nbits, (int)CHAR_BIT*2);
- exit(1);
- }
-
- rsasigkey(nbits, (oldkeyfile == NULL) ? 0 : 1);
- exit(0);
-}
-
-/*
- - getoldkey - fetch an old key's primes
- */
-int /* nbits */
-getoldkey(filename)
-char *filename;
-{
- FILE *f;
- char line[MAXBITS/2];
- char *p;
- char *value;
- static char pube[] = "PublicExponent:";
- static char pubevalue[] = "0x03";
- static char pr1[] = "Prime1:";
- static char pr2[] = "Prime2:";
-# define STREQ(a, b) (strcmp(a, b) == 0)
- int sawpube = 0;
- int sawpr1 = 0;
- int sawpr2 = 0;
- int nbits;
-
- nbits = 0;
-
- if (STREQ(filename, "-"))
- f = stdin;
- else
- f = fopen(filename, "r");
- if (f == NULL) {
- fprintf(stderr, "%s: unable to open file `%s' (%s)\n", me,
- filename, strerror(errno));
- exit(1);
- }
- if (verbose)
- fprintf(stderr, "getting old key from %s...\n", filename);
-
- while (fgets(line, sizeof(line), f) != NULL) {
- p = line + strlen(line) - 1;
- if (*p != '\n') {
- fprintf(stderr, "%s: over-long line in file `%s'\n",
- me, filename);
- exit(1);
- }
- *p = '\0';
-
- p = line + strspn(line, " \t"); /* p -> first word */
- value = strpbrk(p, " \t"); /* value -> after it */
- if (value != NULL) {
- *value++ = '\0';
- value += strspn(value, " \t");
- /* value -> second word if any */
- }
-
- if (value == NULL || *value == '\0') {
- /* wrong format */
- } else if (STREQ(p, pube)) {
- sawpube = 1;
- if (!STREQ(value, pubevalue)) {
- fprintf(stderr, "%s: wrong public exponent (`%s') in old key\n",
- me, value);
- exit(1);
- }
- } else if (STREQ(p, pr1)) {
- if (sawpr1) {
- fprintf(stderr, "%s: duplicate `%s' lines in `%s'\n",
- me, pr1, filename);
- exit(1);
- }
- sawpr1 = 1;
- nbits = (strlen(value) - 2) * 4 * 2;
- if (mpz_init_set_str(prime1, value, 0) < 0) {
- fprintf(stderr, "%s: conversion error in reading old prime1\n",
- me);
- exit(1);
- }
- } else if (STREQ(p, pr2)) {
- if (sawpr2) {
- fprintf(stderr, "%s: duplicate `%s' lines in `%s'\n",
- me, pr2, filename);
- exit(1);
- }
- sawpr2 = 1;
- if (mpz_init_set_str(prime2, value, 0) < 0) {
- fprintf(stderr, "%s: conversion error in reading old prime2\n",
- me);
- exit(1);
- }
- }
- }
-
- if (f != stdin)
- fclose(f);
-
- if (!sawpube || !sawpr1 || !sawpr2) {
- fprintf(stderr, "%s: old key missing or incomplete\n", me);
- exit(1);
- }
-
- assert(sawpr1); /* and thus nbits is known */
- return(nbits);
-}
-
-/*
- - rsasigkey - generate an RSA signature key
- * e is fixed at 3, without discussion. That would not be wise if these
- * keys were to be used for encryption, but for signatures there are some
- * real speed advantages.
- */
-void
-rsasigkey(nbits, useoldkey)
-int nbits;
-int useoldkey; /* take primes from old key? */
-{
- mpz_t p;
- mpz_t q;
- mpz_t n;
- mpz_t e;
- mpz_t d;
- mpz_t q1; /* temporary */
- mpz_t m; /* internal modulus, (p-1)*(q-1) */
- mpz_t t; /* temporary */
- mpz_t exp1;
- mpz_t exp2;
- mpz_t coeff;
- char *bundp;
- size_t bs;
- int success;
- time_t now = time((time_t *)NULL);
-
- /* the easy stuff */
- if (useoldkey) {
- mpz_init_set(p, prime1);
- mpz_init_set(q, prime2);
- } else {
- initprime(p, nbits/2, E);
- initprime(q, nbits/2, E);
- }
- mpz_init(t);
- if (mpz_cmp(p, q) < 0) {
- report("swapping primes so p is the larger...");
- mpz_set(t, p);
- mpz_set(p, q);
- mpz_set(q, t);
- }
- report("computing modulus...");
- mpz_init(n);
- mpz_mul(n, p, q); /* n = p*q */
- mpz_init_set_ui(e, E);
-
- /* internal modulus */
- report("computing lcm(p-1, q-1)...");
- mpz_init_set(m, p);
- mpz_sub_ui(m, m, 1);
- mpz_init_set(q1, q);
- mpz_sub_ui(q1, q1, 1);
- mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
- mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
- if (do_lcm)
- mpz_divexact(m, m, t); /* m = lcm(p-1, q-1) */
- mpz_gcd(t, m, e);
- assert(mpz_cmp_ui(t, 1) == 0); /* m and e relatively prime */
-
- /* decryption key */
- report("computing d...");
- mpz_init(d);
- success = mpz_invert(d, e, m);
- assert(success); /* e has an inverse mod m */
- if (mpz_cmp_ui(d, 0) < 0)
- mpz_add(d, d, m);
- assert(mpz_cmp(d, m) < 0);
-
- /* the speedup hacks */
- report("computing exp1, exp1, coeff...");
- mpz_init(exp1);
- mpz_sub_ui(t, p, 1);
- mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
- mpz_init(exp2);
- mpz_sub_ui(t, q, 1);
- mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
- mpz_init(coeff);
- mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
- if (mpz_cmp_ui(coeff, 0) < 0)
- mpz_add(coeff, coeff, p);
- assert(mpz_cmp(coeff, p) < 0);
-
- /* and the output */
- /* note, getoldkey() knows about some of this */
- report("output...\n"); /* deliberate extra newline */
- printf("\t# RSA %d bits %s %s", nbits, outputhostname, ctime(&now));
- /* ctime provides \n */
- printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");
- bundp = bundle(E, n, &bs);
- printf("\t#pubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */
- printf("\tModulus: %s\n", hexout(n));
- printf("\tPublicExponent: %s\n", hexout(e));
- printf("\t# everything after this point is secret\n");
- printf("\tPrivateExponent: %s\n", hexout(d));
- printf("\tPrime1: %s\n", hexout(p));
- printf("\tPrime2: %s\n", hexout(q));
- printf("\tExponent1: %s\n", hexout(exp1));
- printf("\tExponent2: %s\n", hexout(exp2));
- printf("\tCoefficient: %s\n", hexout(coeff));
-}
-
-/*
- - initprime - initialize an mpz_t to a random prime of specified size
- * Efficiency tweak: we reject candidates that are 1 higher than a multiple
- * of e, since they will make the internal modulus not relatively prime to e.
- */
-void
-initprime(var, nbits, eval)
-mpz_t var;
-int nbits; /* known to be a multiple of CHAR_BIT */
-int eval; /* value of e; 0 means don't bother w. tweak */
-{
- unsigned long tries;
- size_t len;
-# define OKAY(p) (eval == 0 || mpz_fdiv_ui(p, eval) != 1)
-
- initrandom(var, nbits);
- assert(mpz_fdiv_ui(var, 2) == 1); /* odd number */
-
- report("looking for a prime starting there (can take a while)...");
- tries = 1;
- while (!( OKAY(var) && mpz_probab_prime_p(var, nrounds) )) {
- mpz_add_ui(var, var, 2);
- tries++;
- }
-
- len = mpz_sizeinbase(var, 2);
- assert(len == (size_t)nbits || len == (size_t)(nbits+1));
- if (len == (size_t)(nbits+1)) {
- report("carry out occurred (!), retrying...");
- mpz_clear(var);
- initprime(var, nbits, eval);
- return;
- }
- if (verbose)
- fprintf(stderr, "found it after %lu tries.\n", tries);
-}
-
-/*
- - initrandom - initialize an mpz_t to a random number, specified bit count
- * Converting via hex is a bit weird, but it's the best route GMP gives us.
- * Note that highmost and lowmost bits are forced on -- highmost to give a
- * number of exactly the specified length, lowmost so it is an odd number.
- */
-void
-initrandom(var, nbits)
-mpz_t var;
-int nbits; /* known to be a multiple of CHAR_BIT */
-{
- size_t nbytes = (size_t)(nbits / CHAR_BIT);
- static char bitbuf[MAXBITS/CHAR_BIT];
- static char hexbuf[2 + MAXBITS/4 + 1];
- size_t hsize = sizeof(hexbuf);
-
- assert(nbytes <= sizeof(bitbuf));
- getrandom(nbytes, bitbuf);
- bitbuf[0] |= 01 << (CHAR_BIT-1); /* force high bit on */
- bitbuf[nbytes-1] |= 01; /* force low bit on */
- if (datatot(bitbuf, nbytes, 'x', hexbuf, hsize) > hsize) {
- fprintf(stderr, "%s: can't-happen buffer overflow\n", me);
- exit(1);
- }
- if (mpz_init_set_str(var, hexbuf, 0) < 0) {
- fprintf(stderr, "%s: can't-happen hex conversion error\n", me);
- exit(1);
- }
-}
-
-/*
- - getrandom - get some random bytes from /dev/random (or wherever)
- */
-void
-getrandom(nbytes, buf)
-size_t nbytes;
-char *buf; /* known to be big enough */
-{
- size_t ndone;
- int dev;
- size_t got;
-
- dev = open(device, 0);
- if (dev < 0) {
- fprintf(stderr, "%s: could not open %s (%s)\n", me,
- device, strerror(errno));
- exit(1);
- }
-
- ndone = 0;
- if (verbose)
- fprintf(stderr, "getting %d random bytes from %s...\n", (int) nbytes,
- device);
- while (ndone < nbytes) {
- got = read(dev, buf + ndone, nbytes - ndone);
- if (got < 0) {
- fprintf(stderr, "%s: read error on %s (%s)\n", me,
- device, strerror(errno));
- exit(1);
- }
- if (got == 0) {
- fprintf(stderr, "%s: eof on %s!?!\n", me, device);
- exit(1);
- }
- ndone += got;
- }
-
- close(dev);
-}
-
-/*
- - hexout - prepare hex output, guaranteeing even number of digits
- * (The current FreeS/WAN conversion routines want an even digit count,
- * but mpz_get_str doesn't promise one.)
- */
-char * /* pointer to static buffer (ick) */
-hexout(var)
-mpz_t var;
-{
- static char hexbuf[3 + MAXBITS/4 + 1];
- char *hexp;
-
- mpz_get_str(hexbuf+3, 16, var);
- if (strlen(hexbuf+3)%2 == 0) /* even number of hex digits */
- hexp = hexbuf+1;
- else { /* odd, must pad */
- hexp = hexbuf;
- hexp[2] = '0';
- }
- hexp[0] = '0';
- hexp[1] = 'x';
-
- return hexp;
-}
-
-/*
- - bundle - bundle e and n into an RFC2537-format lump
- * Note, calls hexout.
- */
-char * /* pointer to static buffer (ick) */
-bundle(e, n, sizep)
-int e;
-mpz_t n;
-size_t *sizep;
-{
- char *hexp = hexout(n);
- static char bundbuf[2 + MAXBITS/8];
- const char *er;
- size_t size;
-
- assert(e <= 255);
- bundbuf[0] = 1;
- bundbuf[1] = e;
- er = ttodata(hexp, 0, 0, bundbuf+2, sizeof(bundbuf)-2, &size);
- if (er != NULL) {
- fprintf(stderr, "%s: can't-happen bundle convert error `%s'\n",
- me, er);
- exit(1);
- }
- if (size > sizeof(bundbuf)-2) {
- fprintf(stderr, "%s: can't-happen bundle overflow (need %d)\n",
- me, (int) size);
- exit(1);
- }
- if (sizep != NULL)
- *sizep = size + 2;
- return bundbuf;
-}
-
-/*
- - conv - convert bits to output in specified format
- */
-char * /* pointer to static buffer (ick) */
-conv(bits, nbytes, format)
-char *bits;
-size_t nbytes;
-int format; /* datatot() code */
-{
- static char convbuf[MAXBITS/4 + 50]; /* enough for hex */
- size_t n;
-
- n = datatot(bits, nbytes, format, convbuf, sizeof(convbuf));
- if (n == 0) {
- fprintf(stderr, "%s: can't-happen convert error\n", me);
- exit(1);
- }
- if (n > sizeof(convbuf)) {
- fprintf(stderr, "%s: can't-happen convert overflow (need %d)\n",
- me, (int) n);
- exit(1);
- }
- return convbuf;
-}
-
-/*
- - report - report progress, if indicated
- */
-void
-report(msg)
-char *msg;
-{
- if (!verbose)
- return;
- fprintf(stderr, "%s\n", msg);
-}
diff --git a/programs/scepclient/Makefile b/programs/scepclient/Makefile
deleted file mode 100644
index d42320236..000000000
--- a/programs/scepclient/Makefile
+++ /dev/null
@@ -1,192 +0,0 @@
-# Makefile for the scepclient
-# Copyright (C) 2005 Jan Hutter, Martin Willi
-# Hochschule fuer Technik Rapperswil
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PLUTODIR=../pluto
-OPENACDIR=../openac
-
-PROGRAM=scepclient
-EXTRA8PROC=${PROGRAM}.8
-
-# where to find sha2.h
-LIBCRYPTO=$(FREESWANSRCDIR)/lib/libcrypto
-LIBSHA2=$(LIBCRYPTO)/libsha2
-CFLAGS+= -I$(LIBCRYPTO)
-
-LIBS=${FREESWANLIB} $(LIBDESLITE) -lgmp
-CFLAGS+= -DDEBUG -DNO_PLUTO
-
-# This compile option activates the leak detective
-ifeq ($(USE_LEAK_DETECTIVE),true)
- CFLAGS+= -DLEAK_DETECTIVE
-endif
-
-# This compile option activates dynamic URL fetching using libcurl
-ifeq ($(USE_LIBCURL),true)
- CFLAGS+= -DLIBCURL
- LIBS+= -lcurl
-endif
-
-X509_OBJS= asn1.o ca.o certs.o constants.o crl.o defs.o fetch.o id.o keys.o \
- lex.o md2.o md5.o mp_defs.o ocsp.o oid.o pem.o pgp.o pkcs1.o pkcs7.o \
- rnd.o sha1.o sha2.o smartcard.o x509.o
-
-OBJS= rsakey.o pkcs10.o loglite.o scep.o ${X509_OBJS}
-
-include ../Makefile.program
-
-loglite.o : $(OPENACDIR)/loglite.c $(PLUTODIR)/log.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-rsakey.o : rsakey.c rsakey.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pkcs10.o : pkcs10.c pkcs10.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-scep.o : scep.c scep.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-# X.509 library
-
-asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-crl.o : $(PLUTODIR)/crl.c $(PLUTODIR)/crl.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-certs.o : $(PLUTODIR)/certs.c $(PLUTODIR)/certs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-constants.o : $(PLUTODIR)/constants.c $(PLUTODIR)/constants.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-fetch.o : $(PLUTODIR)/fetch.c $(PLUTODIR)/fetch.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-id.o : $(PLUTODIR)/id.c $(PLUTODIR)/id.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-keys.o : $(PLUTODIR)/keys.c $(PLUTODIR)/keys.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-lex.o : $(PLUTODIR)/lex.c $(PLUTODIR)/lex.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-md2.o : $(PLUTODIR)/md2.c $(PLUTODIR)/md2.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-md5.o : $(PLUTODIR)/md5.c $(PLUTODIR)/md5.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-mp_defs.o : $(PLUTODIR)/mp_defs.c $(PLUTODIR)/mp_defs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-ocsp.o : $(PLUTODIR)/ocsp.c $(PLUTODIR)/ocsp.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-oid.o : $(PLUTODIR)/oid.c $(PLUTODIR)/oid.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pem.o : $(PLUTODIR)/pem.c $(PLUTODIR)/pem.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pgp.o : $(PLUTODIR)/pgp.c $(PLUTODIR)/pgp.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-pkcs7.o : $(PLUTODIR)/pkcs7.c $(PLUTODIR)/pkcs7.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-sha2.o : $(LIBSHA2)/sha2.c $(LIBSHA2)/sha2.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-smartcard.o : $(PLUTODIR)/smartcard.c $(PLUTODIR)/smartcard.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-x509.o : $(PLUTODIR)/x509.c $(PLUTODIR)/x509.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-doxygen :
- doxygen doxyconfig.DoxyFile
-
-# Stolen from pluto/Makefile
-
-gatherdeps:
- @ls | grep '\.c$$' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
- @echo
- @ls | grep '\.c$$' | xargs grep '^#[ ]*include[ ]*"' | \
- sed -e 's/\.c:#[ ]*include[ ]*"/.o: /' -e 's/".*//'
-
-# Dependencies generated by "make gatherdeps":
-
-pkcs10.o: pkcs10.c
-rsakey.o: rsakey.c
-scep.o: scep.c
-scepclient.o: scepclient.c
-
-pkcs10.o: ../pluto/constants.h
-pkcs10.o: ../pluto/defs.h
-pkcs10.o: ../pluto/oid.h
-pkcs10.o: ../pluto/asn1.h
-pkcs10.o: ../pluto/pkcs1.h
-pkcs10.o: ../pluto/log.h
-pkcs10.o: ../pluto/x509.h
-pkcs10.o: pkcs10.h
-rsakey.o: ../pluto/constants.h
-rsakey.o: ../pluto/defs.h
-rsakey.o: ../pluto/mp_defs.h
-rsakey.o: ../pluto/log.h
-rsakey.o: ../pluto/asn1.h
-rsakey.o: ../pluto/pkcs1.h
-rsakey.o: rsakey.h
-scep.o: ../pluto/constants.h
-scep.o: ../pluto/defs.h
-scep.o: ../pluto/rnd.h
-scep.o: ../pluto/oid.h
-scep.o: ../pluto/asn1.h
-scep.o: ../pluto/pkcs1.h
-scep.o: ../pluto/fetch.h
-scep.o: ../pluto/log.h
-scep.o: scep.h
-scepclient.o: ../pluto/constants.h
-scepclient.o: ../pluto/defs.h
-scepclient.o: ../pluto/log.h
-scepclient.o: ../pluto/oid.h
-scepclient.o: ../pluto/asn1.h
-scepclient.o: ../pluto/pkcs1.h
-scepclient.o: ../pluto/pkcs7.h
-scepclient.o: ../pluto/certs.h
-scepclient.o: ../pluto/fetch.h
-scepclient.o: ../pluto/rnd.h
-scepclient.o: rsakey.h
-scepclient.o: pkcs10.h
-scepclient.o: scep.h
diff --git a/programs/scepclient/pkcs10.c b/programs/scepclient/pkcs10.c
deleted file mode 100644
index de3f06e18..000000000
--- a/programs/scepclient/pkcs10.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * @file pkcs10.c
- * @brief Functions to build PKCS#10 requests
- *
- * Contains functions to build DER encoded pkcs#10 certificate requests
- */
-
-/* Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/oid.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
-#include "../pluto/log.h"
-#include "../pluto/x509.h"
-
-#include "pkcs10.h"
-
-/* some pre-coded OIDs */
-
-static u_char ASN1_challengePassword_oid_str[] = {
- 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x07
-};
-
-static const chunk_t ASN1_challengePassword_oid = strchunk(ASN1_challengePassword_oid_str);
-
-static u_char ASN1_extensionRequest_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x0E
-};
-
-static const chunk_t ASN1_extensionRequest_oid = strchunk(ASN1_extensionRequest_oid_str);
-
-/**
- * @brief Adds a subjectAltName in DER-coded form to a linked list
- *
- * @param[in,out] subjectAltNames head of the linked list of subjectAltNames
- * @param[in] kind type of the subjectAltName (which is a generalName)
- * @param[in] value value of the subjectAltName as an ASCII string
- */
-void
-pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
-, char *value)
-{
- generalName_t *gn;
- asn1_t asn1_type = ASN1_EOC;
- chunk_t name = { value, strlen(value) };
-
- switch (kind)
- {
- case GN_RFC822_NAME:
- asn1_type = ASN1_CONTEXT_S_1;
- break;
- case GN_DNS_NAME:
- asn1_type = ASN1_CONTEXT_S_2;
- break;
- case GN_IP_ADDRESS:
- {
- struct in_addr addr;
-
- /* convert an ASCII dotted IPv4 address (e.g. 123.456.78.90)
- * to a byte representation in network order
- */
- if (!inet_aton(value, &addr))
- {
- fprintf(stderr, "error in IPv4 subjectAltName\n");
- return;
- }
- asn1_type = ASN1_CONTEXT_S_7;
- name.ptr = (u_char *) &addr.s_addr;
- name.len = sizeof(addr.s_addr);
- break;
- }
- default:
- break;
- }
-
- gn = alloc_thing(generalName_t, "subjectAltName");
- gn->kind = kind;
- gn->name = asn1_simple_object(asn1_type, name);
- gn->next = *subjectAltNames;
- *subjectAltNames = gn;
-}
-
-/**
- * @brief Builds the requestInfoAttributes of the certificationRequestInfo-field
- *
- * challenge password ans subjectAltNames are only included,
- * when avaiable in given #pkcs10_t structure
- *
- * @param[in] pkcs10 Pointer to a #pkcs10_t structure
- * @return 1 if succeeded, 0 otherwise
- */
-static chunk_t
-build_req_info_attributes(pkcs10_t* pkcs10)
-{
-
- chunk_t subjectAltNames = empty_chunk;
- chunk_t challengePassword = empty_chunk;
-
- if (pkcs10->subjectAltNames != NULL)
- {
-
- subjectAltNames = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_extensionRequest_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_wrap(ASN1_SEQUENCE, "m"
- , build_subjectAltNames(pkcs10->subjectAltNames)
- )
- )
- );
- }
-
- if (pkcs10->challengePassword.len > 0)
- {
- asn1_t type = is_printablestring(pkcs10->challengePassword)
- ? ASN1_PRINTABLESTRING : ASN1_T61STRING;
-
- challengePassword = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_challengePassword_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(type, pkcs10->challengePassword)
- )
- );
- }
-
- return asn1_wrap(ASN1_CONTEXT_C_0, "mm"
- , subjectAltNames
- , challengePassword);
-}
-
-/**
- * @brief Builds a DER-code pkcs#10 certificate request
- *
- * @param[in] pkcs10 pointer to a pkcs10_t struct
- * @return DER-code pkcs10 request
- */
-static chunk_t
-pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
-{
- RSA_public_key_t *rsak = (RSA_public_key_t *) pkcs10->private_key;
-
- chunk_t cert_req_info = asn1_wrap(ASN1_SEQUENCE, "ccmm"
- , ASN1_INTEGER_0
- , pkcs10->subject
- , pkcs1_build_publicKeyInfo(rsak)
- , build_req_info_attributes(pkcs10));
-
- chunk_t signature = pkcs1_build_signature(cert_req_info
- , signature_alg, pkcs10->private_key, TRUE);
-
- return asn1_wrap(ASN1_SEQUENCE, "mcm"
- , cert_req_info
- , asn1_algorithmIdentifier(signature_alg)
- , signature);
-}
-
-/**
- * @brief Creates a pkcs#10 certificate request object
- *
- * To create a certificate request, the RSA key and the
- * names to be included as subject in the certificate request
- * (e.g. commonName, organization) are needed. An optional challenge
- * password or some subjectAltNames may be included.
- *
- * @param[in] key rsakey of type #rsakey_t
- * @param[in] subject DER-coded subject distinguished name
- * @param[in] challengePassword challenge password or empty_chunk
- * @param[in] subjectAltNames linked list of subjectAltNames or NULL
- * @return pointer to a #pkcs10_t object
- */
-pkcs10_t*
-pkcs10_build(RSA_private_key_t *key, chunk_t subject, chunk_t challengePassword
-, generalName_t *subjectAltNames, int signature_alg)
-{
- pkcs10_t *pkcs10 = alloc_thing(pkcs10_t, "pkcs10_t");
-
- pkcs10->subject = subject;
- pkcs10->private_key = key;
- pkcs10->challengePassword = challengePassword;
- pkcs10->subjectAltNames = subjectAltNames;
-
- pkcs10->request = pkcs10_build_request(pkcs10, signature_alg);
- return pkcs10;
-}
-
-/**
- * @brief Frees the resources used by an #pkcs10_t object
- *
- * @param[in] pkcs10 #pkcs10_t to free
- */
-void
-pkcs10_free(pkcs10_t *pkcs10)
-{
- if (pkcs10 != NULL)
- {
- freeanychunk(pkcs10->request);
- pfree(pkcs10);
- }
-}
diff --git a/programs/scepclient/pkcs10.h b/programs/scepclient/pkcs10.h
deleted file mode 100644
index c2a4c1b92..000000000
--- a/programs/scepclient/pkcs10.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file pkcs10.h
- * @brief Functions to build PKCS#10 Request's
- *
- * Contains functions to build DER encoded pkcs#10 certificate requests
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef _PKCS10_H
-#define _PKCS10_H
-
-#include "../pluto/defs.h"
-#include "../pluto/pkcs1.h"
-#include "../pluto/x509.h"
-
-typedef struct pkcs10_struct pkcs10_t;
-
-/**
- * @brief type representating a pkcs#10 request.
- *
- * A pkcs#10 request contains a distinguished name, an optional
- * challenge password, a public key and optional subjectAltNames.
- *
- * The RSA private key is needed to compute the signature of the given request
- */
-struct pkcs10_struct {
- RSA_private_key_t *private_key;
- chunk_t request;
- chunk_t subject;
- chunk_t challengePassword;
- generalName_t *subjectAltNames;
-};
-
-extern const pkcs10_t empty_pkcs10;
-
-extern void pkcs10_add_subjectAltName(generalName_t **subjectAltNames
- , generalNames_t kind, char *value);
-extern pkcs10_t* pkcs10_build(RSA_private_key_t *key, chunk_t subject
- , chunk_t challengePassword, generalName_t *subjectAltNames
- , int signature_alg);
-extern void pkcs10_free(pkcs10_t *pkcs10);
-
-#endif /* _PKCS10_H */
diff --git a/programs/scepclient/rsakey.c b/programs/scepclient/rsakey.c
deleted file mode 100644
index c4f26b286..000000000
--- a/programs/scepclient/rsakey.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * @file rsakey.c
- * @brief Functions for RSA key generation
- */
-
-/*
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * $Id: rsakey.c,v 1.5 2006/01/04 21:16:30 as Exp $
- */
-
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <gmp.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/mp_defs.h"
-#include "../pluto/log.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
-
-#include "rsakey.h"
-
-/* Number of times the probabilistic primality test is applied */
-#define PRIMECHECK_ROUNDS 30
-
-/* Public exponent used for signature key generation */
-#define PUBLIC_EXPONENT 0x10001
-
-#ifndef RANDOM_DEVICE
-#define RANDOM_DEVICE "/dev/random"
-#endif
-
-
-/**
- * @brief Reads a specific number of bytes from a given device/file
- *
- * @param[in] nbytes number of bytes to read from random device
- * @param[out] buf pointer to buffer where to write the data in.
- * size of buffer has to be at least nbytes.
- * @return TRUE, if succeeded, FALSE otherwise
- */
-
-static bool
-get_true_random_bytes(size_t nbytes, char *buf)
-{
- size_t ndone;
- size_t got;
- char *device = RANDOM_DEVICE;
-
- int dev = open(RANDOM_DEVICE, 0);
-
- if (dev < 0)
- {
- fprintf(stderr, "could not open random device %s", device);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("getting %d bytes from %s...", (int) nbytes, device)
- )
-
- ndone = 0;
- while (ndone < nbytes)
- {
- got = read(dev, buf + ndone, nbytes - ndone);
- if (got < 0)
- {
- fprintf(stderr, "read error on %s", device);
- return FALSE;
- }
- if (got == 0)
- {
- fprintf(stderr, "eof on %s", device);
- return FALSE;
- }
- ndone += got;
- }
- close(dev);
- return TRUE;
-}
-
-/**
- * @brief initialize an mpz_t to a random number, specified bit count
- *
- * Converting the random value in a value of type mpz_t is done
- * by creating a hexbuffer.
- * Converting via hex is a bit weird, but it's the best route GMP gives us.
- * Note that highmost and lowmost bits are forced on -- highmost to give a
- * number of exactly the specified length, lowmost so it is an odd number.
- *
- * @param[out] var uninitialized mpz_t to store th random number in
- * @param[in] nbits length of var in bits (known to be a multiple of BITS_PER_BYTE)
- * @return TRUE on success, FALSE otherwise
- */
-static bool
-init_random(mpz_t var, int nbits)
-{
- size_t nbytes = (size_t)(nbits/BITS_PER_BYTE);
- char random_buf[RSA_MAX_OCTETS/2];
-
- assert(nbytes <= sizeof(random_buf));
-
- if (!get_true_random_bytes(nbytes, random_buf))
- return FALSE;
-
- random_buf[0] |= 01 << (BITS_PER_BYTE-1); /* force high bit on */
- random_buf[nbytes-1] |= 01; /* force low bit on */
- n_to_mpz(var, random_buf, nbytes);
- return TRUE;
-}
-
-/**
- * @brief initialize an mpz_t to a random prime of specified size
- *
- * Efficiency tweak: we reject candidates that are 1 higher than a multiple
- * of e, since they will make the internal modulus not relatively prime to e.
- *
- * @param[out] var mpz_t variable to initialize
- * @param[in] nbits length of given prime in bits (known to be a multiple of BITS_PER_BYTE)
- * @param[in] eval E-Value, 0 means don't bother w. tweak
- * @return 1 on success, 0 otherwise
- */
-static bool
-init_prime(mpz_t var, int nbits, int eval)
-{
- unsigned long tries;
- size_t len;
-
- /* get a random value of nbits length */
- if (!init_random(var, nbits))
- return FALSE;
-
- /* check if odd number */
- assert(mpz_fdiv_ui(var, 2) == 1);
- DBG(DBG_CONTROLMORE,
- DBG_log("looking for a prime starting there (can take a while)...")
- )
-
- tries = 1;
- while (mpz_fdiv_ui(var, eval) == 1
- || !mpz_probab_prime_p(var, PRIMECHECK_ROUNDS))
- {
- /* not a prime, increase by 2 */
- mpz_add_ui(var, var, 2);
- tries++;
- }
-
- len = mpz_sizeinbase(var, 2);
-
- /* check bit length of primee */
- assert(len == (size_t)nbits || len == (size_t)(nbits+1));
-
- if (len == (size_t)(nbits+1))
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("carry out occurred (!), retrying...")
- )
- mpz_clear(var);
- /* recursive call */
- return init_prime(var, nbits, eval);
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("found it after %lu tries.",tries)
- )
- return TRUE;
-}
-
-/**
- * @brief Generate a RSA key usable for encryption
- *
- * Generate an RSA key usable for encryption. All the
- * values of the RSA key are filled into mpz_t parameters.
- * These mpz_t parameters must not be initialized and have
- * to be cleared with mpz_clear after using.
- *
- * @param[in] nbits size of rsa key in bits
- * @return RSA_public_key_t containing the generated RSA key
- */
-err_t
-generate_rsa_private_key(int nbits, RSA_private_key_t *key)
-{
- mpz_t p, q, n, e, d, exp1, exp2, coeff;
- mpz_t m, q1, t; /* temporary variables*/
-
- DBG(DBG_CONTROL,
- DBG_log("generating %d bit RSA key:", nbits)
- )
-
- if (nbits <= 0)
- return "negative rsa key length!";
-
- /* Get values of primes p and q */
- DBG(DBG_CONTROLMORE,
- DBG_log("initialize prime p")
- )
- if (!init_prime(p, nbits/2, PUBLIC_EXPONENT))
- return "could not generate prime p";
-
- DBG(DBG_CONTROLMORE,
- DBG_log("initialize prime q")
- )
- if (!init_prime(q, nbits/2, PUBLIC_EXPONENT))
- return "could not generate prime q";
-
- mpz_init(t);
-
- /* Swapping primes so p is larger then q */
- if (mpz_cmp(p, q) < 0)
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("swapping primes so p is the larger...")
- );
- mpz_set(t, p);
- mpz_set(p, q);
- mpz_set(q, t);
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log("computing modulus...")
- )
- mpz_init(n);
- /* n = p*q */
- mpz_mul(n, p, q);
-
- /* Assign e the value of defined PUBLIC_EXPONENT */
- mpz_init_set_ui(e, PUBLIC_EXPONENT);
-
- DBG(DBG_CONTROLMORE,
- DBG_log("computing lcm(p-1, q-1)...")
- )
- /* m = p */
- mpz_init_set(m, p);
- /* m = m-1 */
- mpz_sub_ui(m, m, 1);
- /* q1 = q */
- mpz_init_set(q1, q);
- /* q1 = q1-1 */
- mpz_sub_ui(q1, q1, 1);
- /* t = gcd(p-1, q-1) */
- mpz_gcd(t, m, q1);
- /* m = (p-1)*(q-1) */
- mpz_mul(m, m, q1);
- /* m = m / t */
- mpz_divexact(m, m, t);
- /* t = gcd(m, e) (greatest common divisor) */
- mpz_gcd(t, m, e);
- /* m and e relatively prime */
- assert(mpz_cmp_ui(t, 1) == 0);
-
- /* decryption key */
- DBG(DBG_CONTROLMORE,
- DBG_log("computing d...")
- )
- mpz_init(d);
- /* e has an inverse mod m */
- assert(mpz_invert(d, e, m));
-
- /* make sure d is positive */
- if (mpz_cmp_ui(d, 0) < 0)
- mpz_add(d, d, m);
-
- /* d has to be positive */
- assert(mpz_cmp(d, m) < 0);
-
- /* the speedup hacks */
- DBG(DBG_CONTROLMORE,
- DBG_log("computing exp1, exp1, coeff...")
- )
- mpz_init(exp1);
- /* t = p-1 */
- mpz_sub_ui(t, p, 1);
- /* exp1 = d mod p-1 */
- mpz_mod(exp1, d, t);
-
- mpz_init(exp2);
- /* t = q-1 */
- mpz_sub_ui(t, q, 1);
- /* exp2 = d mod q-1 */
- mpz_mod(exp2, d, t);
-
- mpz_init(coeff);
- /* coeff = q^-1 mod p */
- mpz_invert(coeff, q, p);
-
- /* make sure coeff is positive */
- if (mpz_cmp_ui(coeff, 0) < 0)
- mpz_add(coeff, coeff, p);
-
- /* coeff has to be positive */
- assert(mpz_cmp(coeff, p) < 0);
-
- /* Clear temporary variables */
- mpz_clear(q1);
- mpz_clear(m);
- mpz_clear(t);
-
- /* form FreeS/WAN keyid */
- {
- size_t e_len = (mpz_sizeinbase(e,2)+BITS_PER_BYTE-1)/BITS_PER_BYTE;
- size_t n_len = (mpz_sizeinbase(n,2)+BITS_PER_BYTE-1)/BITS_PER_BYTE;
- chunk_t e_ch = mpz_to_n(e, e_len);
- chunk_t n_ch = mpz_to_n(n, n_len);
- form_keyid(e_ch, n_ch, key->pub.keyid, &key->pub.k);
- freeanychunk(e_ch);
- freeanychunk(n_ch);
- }
- /* fill in the elements of the RSA private key */
- key->p = *p;
- key->q = *q;
- key->pub.n = *n;
- key->pub.e = *e;
- key->d = *d;
- key->dP = *exp1;
- key->dQ = *exp2;
- key->qInv = *coeff;
-
- DBG(DBG_CONTROL,
- DBG_log("RSA key *%s generated with %d bits", key->pub.keyid
- , (int)mpz_sizeinbase(n,2))
- )
-
-#ifdef DEBUG
- DBG(DBG_PRIVATE,
- RSA_show_private_key(key)
- )
-#endif
- return NULL;
-}
diff --git a/programs/scepclient/rsakey.h b/programs/scepclient/rsakey.h
deleted file mode 100644
index 3e3156d81..000000000
--- a/programs/scepclient/rsakey.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @file rsakey.h
- * @brief Functions for RSA key generation
- */
-
-/*
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * $Id: rsakey.h,v 1.2 2005/08/11 21:52:56 as Exp $
- */
-
-#ifndef RSAKEY_H_
-#define RSAKEY_H_
-
-#include "../pluto/pkcs1.h"
-
-extern err_t generate_rsa_private_key(int nbits, RSA_private_key_t *key);
-
-#endif // RSAKEY_H_
diff --git a/programs/scepclient/scep.c b/programs/scepclient/scep.c
deleted file mode 100644
index 577191787..000000000
--- a/programs/scepclient/scep.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/**
- * @file scep.c
- * @brief SCEP specific functions
- *
- * Contains functions to build SCEP request's and to parse SCEP reply's.
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <freeswan.h>
-
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/rnd.h"
-#include "../pluto/oid.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
-#include "../pluto/fetch.h"
-#include "../pluto/log.h"
-
-#include "scep.h"
-
-static char ASN1_messageType_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02
-};
-
-static char ASN1_senderNonce_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05
-};
-
-static char ASN1_transId_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07
-};
-
-static const chunk_t ASN1_messageType_oid =
- strchunk(ASN1_messageType_oid_str);
-static const chunk_t ASN1_senderNonce_oid =
- strchunk(ASN1_senderNonce_oid_str);
-static const chunk_t ASN1_transId_oid =
- strchunk(ASN1_transId_oid_str);
-
-static const char *pkiStatus_values[] = { "0", "2", "3" };
-
-static const char *pkiStatus_names[] = {
- "SUCCESS",
- "FAILURE",
- "PENDING",
- "UNKNOWN"
-};
-
-static const char *msgType_values[] = { "3", "19", "20", "21", "22" };
-
-static const char *msgType_names[] = {
- "CertRep",
- "PKCSReq",
- "GetCertInitial",
- "GetCert",
- "GetCRL",
- "Unknown"
-};
-
-static const char *failInfo_reasons[] = {
- "badAlg - unrecognized or unsupported algorithm identifier",
- "badMessageCheck - integrity check failed",
- "badRequest - transaction not permitted or supported",
- "badTime - Message time field was not sufficiently close to the system time",
- "badCertId - No certificate could be identified matching the provided criteria"
-};
-
-const scep_attributes_t empty_scep_attributes = {
- SCEP_Unknown_MSG , /* msgType */
- SCEP_UNKNOWN , /* pkiStatus */
- SCEP_unknown_REASON, /* failInfo */
- { NULL, 0 } , /* transID */
- { NULL, 0 } , /* senderNonce */
- { NULL, 0 } , /* recipientNonce */
-};
-
-/* ASN.1 definition of the X.501 atttribute type */
-
-static const asn1Object_t attributesObjects[] = {
- { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
- { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
- { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
-};
-
-#define ATTRIBUTE_OBJ_TYPE 2
-#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_ROOF 7
-
-/*
- * extract and store an attribute
- */
-static bool
-extract_attribute(int oid, chunk_t object, u_int level
-, scep_attributes_t *attrs)
-{
- asn1_t type = ASN1_EOC;
- const char *name = "none";
-
- switch (oid)
- {
- case OID_PKCS9_CONTENT_TYPE:
- type = ASN1_OID;
- name = "contentType";
- break;
- case OID_PKCS9_SIGNING_TIME:
- type = ASN1_UTCTIME;
- name = "signingTime";
- break;
- case OID_PKCS9_MESSAGE_DIGEST:
- type = ASN1_OCTET_STRING;
- name = "messageDigest";
- break;
- case OID_PKI_MESSAGE_TYPE:
- type = ASN1_PRINTABLESTRING;
- name = "messageType";
- break;
- case OID_PKI_STATUS:
- type = ASN1_PRINTABLESTRING;
- name = "pkiStatus";
- break;
- case OID_PKI_FAIL_INFO:
- type = ASN1_PRINTABLESTRING;
- name = "failInfo";
- break;
- case OID_PKI_SENDER_NONCE:
- type = ASN1_OCTET_STRING;
- name = "senderNonce";
- break;
- case OID_PKI_RECIPIENT_NONCE:
- type = ASN1_OCTET_STRING;
- name = "recipientNonce";
- break;
- case OID_PKI_TRANS_ID:
- type = ASN1_PRINTABLESTRING;
- name = "transID";
- break;
- default:
- break;
- }
-
- if (type == ASN1_EOC)
- return TRUE;
-
- if (!parse_asn1_simple_object(&object, type, level+1, name))
- return FALSE;
-
- switch (oid)
- {
- case OID_PKCS9_CONTENT_TYPE:
- break;
- case OID_PKCS9_SIGNING_TIME:
- break;
- case OID_PKCS9_MESSAGE_DIGEST:
- break;
- case OID_PKI_MESSAGE_TYPE:
- {
- scep_msg_t m;
-
- for (m = SCEP_CertRep_MSG; m < SCEP_Unknown_MSG; m++)
- {
- if (strncmp(msgType_values[m], object.ptr, object.len) == 0)
- attrs->msgType = m;
- }
- DBG(DBG_CONTROL,
- DBG_log("messageType: %s", msgType_names[attrs->msgType])
- )
- }
- break;
- case OID_PKI_STATUS:
- {
- pkiStatus_t s;
-
- for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
- {
- if (strncmp(pkiStatus_values[s], object.ptr, object.len) == 0)
- attrs->pkiStatus = s;
- }
- DBG(DBG_CONTROL,
- DBG_log("pkiStatus: %s", pkiStatus_names[attrs->pkiStatus])
- )
- }
- break;
- case OID_PKI_FAIL_INFO:
- if (object.len == 1
- && *object.ptr >= '0' && *object.ptr <= '4')
- {
- attrs->failInfo = (failInfo_t)(*object.ptr - '0');
- }
- if (attrs->failInfo != SCEP_unknown_REASON)
- plog("failInfo: %s", failInfo_reasons[attrs->failInfo]);
- break;
- case OID_PKI_SENDER_NONCE:
- attrs->senderNonce = object;
- break;
- case OID_PKI_RECIPIENT_NONCE:
- attrs->recipientNonce = object;
- break;
- case OID_PKI_TRANS_ID:
- attrs->transID = object;
- }
- return TRUE;
-}
-
-/*
- * parse X.501 attributes
- */
-bool
-parse_attributes(chunk_t blob, scep_attributes_t *attrs)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int oid = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("parsing attributes")
- )
- while (objectID < ATTRIBUTE_OBJ_ROOF)
- {
- if (!extract_object(attributesObjects, &objectID
- , &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case ATTRIBUTE_OBJ_TYPE:
- oid = known_oid(object);
- break;
- case ATTRIBUTE_OBJ_VALUE:
- if (!extract_attribute(oid, object, level, attrs))
- return FALSE;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/* generates a unique fingerprint of the pkcs10 request
- * by computing an MD5 hash over it
- */
-void
-scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
-{
- char buf[MD5_DIGEST_SIZE];
- chunk_t digest = { buf, sizeof(buf) };
-
- /* the fingerprint is the MD5 hash in hexadecimal format */
- compute_digest(pkcs10, OID_MD5, &digest);
- fingerprint->len = 2*digest.len;
- fingerprint->ptr = alloc_bytes(fingerprint->len + 1, "fingerprint");
- datatot(digest.ptr, digest.len, 16, fingerprint->ptr, fingerprint->len + 1);
-}
-
-/* generate a transaction id as the MD5 hash of an public key
- * the transaction id is also used as a unique serial number
- */
-void
-scep_generate_transaction_id(const RSA_public_key_t *rsak
-, chunk_t *transID, chunk_t *serialNumber)
-{
- char buf[MD5_DIGEST_SIZE];
-
- chunk_t digest = { buf, sizeof(buf) };
- chunk_t public_key = pkcs1_build_publicKeyInfo(rsak);
-
- bool msb_set;
- u_char *pos;
-
- compute_digest(public_key, OID_MD5, &digest);
- pfree(public_key.ptr);
-
- /* is the most significant bit of the digest set? */
- msb_set = (*digest.ptr & 0x80) == 0x80;
-
- /* allocate space for the serialNumber */
- serialNumber->len = msb_set + digest.len;
- serialNumber->ptr = alloc_bytes(serialNumber->len, "serialNumber");
-
- /* the serial number as the two's complement of the digest */
- pos = serialNumber->ptr;
- if (msb_set)
- {
- *pos++ = 0x00;
- }
- memcpy(pos, digest.ptr, digest.len);
-
- /* the transaction id is the serial number in hex format */
- transID->len = 2*digest.len;
- transID->ptr = alloc_bytes(transID->len + 1, "transID");
- datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
-}
-
-/*
- * builds a transId attribute
- */
-chunk_t
-scep_transId_attribute(chunk_t transID)
-{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_transId_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_PRINTABLESTRING, transID)
- )
- );
-}
-
-/*
- * builds a messageType attribute
- */
-chunk_t
-scep_messageType_attribute(scep_msg_t m)
-{
- chunk_t msgType = {
- msgType_values[m],
- strlen(msgType_values[m])
- };
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_messageType_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_PRINTABLESTRING, msgType)
- )
- );
-}
-
-/*
- * builds a senderNonce attribute
- */
-chunk_t
-scep_senderNonce_attribute(void)
-{
- const size_t nonce_len = 16;
- u_char nonce_buf[nonce_len];
- chunk_t senderNonce = { nonce_buf, nonce_len };
-
- get_rnd_bytes(nonce_buf, nonce_len);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_senderNonce_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_OCTET_STRING, senderNonce)
- )
- );
-}
-
-/*
- * builds a pkcs7 enveloped and signed scep request
- */
-chunk_t
-scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
-, const x509cert_t *enc_cert, int enc_alg
-, const x509cert_t *signer_cert, int digest_alg
-, const RSA_private_key_t *private_key)
-{
- chunk_t envelopedData, attributes, request;
-
- envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);
-
- attributes = asn1_wrap(ASN1_SET, "mmmmm"
- , pkcs7_contentType_attribute()
- , pkcs7_messageDigest_attribute(envelopedData
- , digest_alg)
- , scep_transId_attribute(transID)
- , scep_messageType_attribute(msg)
- , scep_senderNonce_attribute());
-
- request = pkcs7_build_signedData(envelopedData, attributes
- , signer_cert, digest_alg, private_key);
- freeanychunk(envelopedData);
- freeanychunk(attributes);
- return request;
-}
-
-#ifdef LIBCURL
-/* converts a binary request to base64 with 64 characters per line
- * newline and '+' characters are escaped by %0A and %2B, respectively
- */
-static char*
-escape_http_request(chunk_t req)
-{
- char *escaped_req = NULL;
- char *p1, *p2;
- int lines = 0;
- int plus = 0;
- int n = 0;
-
- /* compute and allocate the size of the base64-encoded request */
- int len = 1 + 4*((req.len + 2)/3);
- char *encoded_req = alloc_bytes(len, "encoded request");
-
- /* do the base64 conversion */
- len = datatot(req.ptr, req.len, 64, encoded_req, len);
-
- /* compute newline characters to be inserted every 64 characters */
- lines = (len - 2) / 64;
-
- /* count number of + characters to be escaped */
- p1 = encoded_req;
- while (*p1 != '\0')
- {
- if (*p1++ == '+')
- plus++;
- }
-
- escaped_req = alloc_bytes(len + 3*(lines + plus), "escaped request");
-
- /* escape special characters in the request */
- p1 = encoded_req;
- p2 = escaped_req;
- while (*p1 != '\0')
- {
- if (n == 64)
- {
- memcpy(p2, "%0A", 3);
- p2 += 3;
- n = 0;
- }
- if (*p1 == '+')
- {
- memcpy(p2, "%2B", 3);
- p2 += 3;
- }
- else
- {
- *p2++ = *p1;
- }
- p1++;
- n++;
- }
- *p2 = '\0';
- pfreeany(encoded_req);
- return escaped_req;
-}
-#endif
-
-/*
- * send a SCEP request via HTTP and wait for a response
- */
-bool
-scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
-, fetch_request_t req_type, chunk_t *response)
-{
-#ifdef LIBCURL
- char errorbuffer[CURL_ERROR_SIZE] = "";
- char *complete_url = NULL;
- struct curl_slist *headers = NULL;
- CURL *curl;
- CURLcode res;
-
- /* initialize response */
- *response = empty_chunk;
-
- /* initialize curl context */
- curl = curl_easy_init();
- if (curl == NULL)
- {
- plog("could not initialize curl context");
- return FALSE;
- }
-
- if (op == SCEP_PKI_OPERATION)
- {
- const char operation[] = "PKIOperation";
-
- if (req_type == FETCH_GET)
- {
- char *escaped_req = escape_http_request(pkcs7);
-
- /* form complete url */
- int len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s&message=%s"
- , url, operation, escaped_req);
- pfreeany(escaped_req);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
- headers = curl_slist_append(headers, "Pragma:");
- headers = curl_slist_append(headers, "Host:");
- headers = curl_slist_append(headers, "Accept:");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- }
- else /* HTTP_POST */
- {
- /* form complete url */
- int len = strlen(url) + 11 + strlen(operation) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s", url, operation);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, FALSE);
- headers = curl_slist_append(headers, "Content-Type:");
- headers = curl_slist_append(headers, "Expect:");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pkcs7.ptr);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pkcs7.len);
- }
- }
- else /* SCEP_GET_CA_CERT */
- {
- const char operation[] = "GetCACert";
-
- /* form complete url */
- int len = strlen(url) + 32 + strlen(operation) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
- , url, operation);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
- }
-
- curl_easy_setopt(curl, CURLOPT_URL, complete_url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- DBG(DBG_CONTROL,
- DBG_log("sending scep request to '%s'", url)
- )
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("received scep response")
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("SCEP response:\n", *response)
- )
- }
- else
- {
- plog("failed to fetch scep response from '%s': %s", url, errorbuffer);
- }
- curl_slist_free_all(headers);
- curl_easy_cleanup(curl);
- pfreeany(complete_url);
-
- return (res == CURLE_OK);
-#else /* !LIBCURL */
- plog("scep error: pluto wasn't compiled with libcurl support");
- return FALSE;
-#endif /* !LIBCURL */
-}
-
-err_t
-scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data
-, scep_attributes_t *attrs, x509cert_t *signer_cert)
-{
- chunk_t attributes;
-
- if (!pkcs7_parse_signedData(response, data, NULL, &attributes, signer_cert))
- {
- return "error parsing the scep response";
- }
- if (!parse_attributes(attributes, attrs))
- {
- return "error parsing the scep response attributes";
- }
- if (!same_chunk(transID, attrs->transID))
- {
- return "transaction ID of scep response does not match";
- }
- return NULL;
-}
diff --git a/programs/scepclient/scep.h b/programs/scepclient/scep.h
deleted file mode 100644
index 81e5d1a4b..000000000
--- a/programs/scepclient/scep.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @file scep.h
- * @brief SCEP specific functions
- *
- * Contains functions to build and parse SCEP requests and replies
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef _SCEP_H
-#define _SCEP_H
-
-#include "../pluto/defs.h"
-#include "../pluto/pkcs1.h"
-#include "../pluto/pkcs7.h"
-
-/* supported SCEP operation types */
-typedef enum {
- SCEP_PKI_OPERATION,
- SCEP_GET_CA_CERT
-} scep_op_t;
-
-/* SCEP pkiStatus values */
-typedef enum {
- SCEP_SUCCESS,
- SCEP_FAILURE,
- SCEP_PENDING,
- SCEP_UNKNOWN
-} pkiStatus_t;
-
-/* SCEP messageType values */
-typedef enum {
- SCEP_CertRep_MSG,
- SCEP_PKCSReq_MSG,
- SCEP_GetCertInitial_MSG,
- SCEP_GetCert_MSG,
- SCEP_GetCRL_MSG,
- SCEP_Unknown_MSG
-} scep_msg_t;
-
-/* SCEP failure reasons */
-typedef enum {
- SCEP_badAlg_REASON = 0,
- SCEP_badMessageCheck_REASON = 1,
- SCEP_badRequest_REASON = 2,
- SCEP_badTime_REASON = 3,
- SCEP_badCertId_REASON = 4,
- SCEP_unknown_REASON = 5
-} failInfo_t;
-
-/* SCEP attributes */
-typedef struct {
- scep_msg_t msgType;
- pkiStatus_t pkiStatus;
- failInfo_t failInfo;
- chunk_t transID;
- chunk_t senderNonce;
- chunk_t recipientNonce;
-} scep_attributes_t;
-
-extern const scep_attributes_t empty_scep_attributes;
-
-extern bool parse_attributes(chunk_t blob, scep_attributes_t *attrs);
-extern void scep_generate_pkcs10_fingerprint(chunk_t pkcs10
- , chunk_t *fingerprint);
-extern void scep_generate_transaction_id(const RSA_public_key_t *rsak
- , chunk_t *transID, chunk_t *serialNumber);
-extern chunk_t scep_transId_attribute(chunk_t transaction_id);
-extern chunk_t scep_messageType_attribute(scep_msg_t m);
-extern chunk_t scep_senderNonce_attribute(void);
-extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
- , const x509cert_t *enc_cert, int enc_alg
- , const x509cert_t *signer_cert, int digest_alg
- , const RSA_private_key_t *private_key);
-extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
- , fetch_request_t request_type, chunk_t *response);
-extern err_t scep_parse_response(chunk_t response, chunk_t transID
- , contentInfo_t *data, scep_attributes_t *attrs, x509cert_t *signer_cert);
-
-#endif /* _SCEP_H */
diff --git a/programs/scepclient/scepclient.8 b/programs/scepclient/scepclient.8
deleted file mode 100644
index 0d6364ef2..000000000
--- a/programs/scepclient/scepclient.8
+++ /dev/null
@@ -1,288 +0,0 @@
-.\"
-.TH "IPSEC_SCEPCLIENT" "8" "29 September 2005" "Jan Hutter, Martin Willi" ""
-.SH "NAME"
-ipsec scepclient \- Client for the SCEP protocol
-.SH "SYNOPSIS"
-.B ipsec scepclient [argument ...]
-.sp
-.B ipsec scepclient
-.B \-\-help
-.br
-.B ipsec scepclient
-.B \-\-version
-.SH "DESCRIPTION"
-.BR scepclient
-is a client implementation of Cisco System's Simple Certificate Enrollment Protocol (SCEP) written for Linux strongSwan <http://www.strongswan.org>.
-.BR scepclient
-is designed to be used for certificate enrollment on machines using the OpenSource IPsec solution
-.I strongSwan.
-.SH "FEATURES"
-.BR scepclient
-implements the following features of SCEP:
-.br
-.IP "\-" 4
-Automatic enrollment of client certificate using a preshared secret
-.IP "\-" 4
-Manual enrollment of client certificate. Offline fingerprint check required!
-.IP "\-" 4
-Acquisition of CA certificate(s)
-.SH "OPTIONS"
-.SS Basic Startup Options
-.B \-v, \-\-version
-.RS 4
-Display the version of ipsec scepclient.
-.PP
-.RE
-.B \-h, \-\-help
-.RS 4
-Display usage of ipsec scepclient.
-.RE
-
-.SS General Options
-.B \-u, \-\-url \fIurl\fP
-.RS 4
-Full HTTP URL of the SCEP server to be used for certificate enrollment and CA certificate acquisition.
-.RE
-.PP
-.B \-+, \-\-optionsfrom \fIfilename\fP
-.RS 4
-Reads additional options from \fIfilename\fP.
-.RE
-.PP
-.B \-f, \-\-force
-.RS 4
-Overwrite existing output file[s].
-.RE
-.PP
-.B \-q, \-\-quiet
-.RS 4
-Do not write log output to stderr.
-.RE
-
-.SS Options for CA Certificate Acquisition
-.B \-o, \-\-out cacert[=\fIfilename\fP]
-.RS 4
-Output file of acquired CA certificate. If more then one CA certificate is available, \fIfilename\fP is used as prefix for the resulting files.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
-.RE
-
-.SS Options For Certificate Enrollment
-.B \-i, \-\-in \fItype\fP[=\fIfilename\fP]
-.RS 4
-Input file for certificate enrollment. This option can be specified multiple times to specify input files for every \fItype\fP.
-Input files can bei either DER or PEM encoded.
-.PP
-Supported values for \fItype\fP:
-.IP "\fBpkcs1\fP" 12
-RSA private key in PKCS#1 file format. If no input of this type is specified, a RSA key gets generated.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/private/myKey.der.
-.IP "\fBcacert\-enc\fP" 12
-CA certificate to encrypt the SCEP request. Has to be specified for certificate enrollment.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
-.IP "\fBcacert\-sig\fP" 12
-CA certificate to check signature of SCEP reply. Has to be specified for certificate enrollment.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
-.RE
-.PP
-.B \-k, \-\-keylength \fIbits\fP
-.RS 4
-sets the key length for RSA key generation. The default length for a generated rsa key is set to 2048 bit.
-.RE
-.PP
-.B \-D, \-\-days \fIdays\fP
-.RS 4
-Validity of the self-signed X.509 certificate in days. The default is 1825 days (5 years).
-.RE
-.PP
-.B \-S, \-\-startdate \fIYYMMDDHHMMSS\fPZ
-.RS 4
-defines the \fBnotBefore\fP date when the X.509 certificate becomes valid.
-The date has the format \fIYYMMDDHHMMSS\fP and must be specified in UTC (Zulu time).
-If the \fB--startdate\fP option is not specified then the current date is taken as a default.
-.RE
-.PP
-.B \-E, \-\-enddate \fIYYMMDDHHMMSS\fPZ
-.RS 4
-defines the \fBnotAfter\fP date when the X.509 certificate will expire.
-The date has the format \fIYYMMDDHHMMSS\fP and must be specified in UTC (Zulu time).
-If the \fB--enddate\fP option is not specified then the default \fBnotAfter\fP value is computed by
-adding the validity interval specified by the \fB--days\fP option to the \fBnotBefore\fP date.
-.RE
-.PP
-.B \-d, \-\-dn \fIdn\fP
-.RS 4
-Distinguished name as comma separated list of relative distinguished names. Use quotation marks for a distinguished name containing spaces. If the \fB\-\-dn\fP parameter is missing then the default "C=CH, O=Linux strongSwan, CN=\fIhostname\fP"
-is used with \fIhostname\fP being the return value of the \fIgethostname\fP() function.
-.RE
-.PP
-.B \-s, \-\-subjectAltName \fItype\fP=\fIvalue\fP
-.RS 4
-Include subjectAltName in certificate request. This option can be specified multiple times to specify a subjectAltName
-for every \fItype\fP.
-.PP
-Supported values for \fItype\fP:
-.IP "\fBemail\fP" 12
-subjectAltName is a email address.
-.IP "\fBdns\fP" 12
-subjectAltName is a hostname.
-.IP "\fBip\fP" 12
-subjectAltName is a IP address.
-.RE
-.PP
-.B \-p, \-\-password \fIpw\fP
-.RS 4
-Password to be included as a \fIchallenge password\fP in SCEP request.
-If \fIpw\fP is \fB%prompt\fP', the password gets prompted for on the command line.
-.IP
-\- In automatic mode, this password corresponds to the preshared secret for the given enrollment.
-.IP
-\- In manual mode, this password can be used to later revoke the corresponding certificate.
-.RE
-.PP
-.B \-a, \-\-algorithm \fIalgo\fP
-.RS 4
-Change symmetric algorithm to use for encryption of certificate Request.
-The default is \fB3des\-cbc\fP.
-.PP
-Supported values for \fIalgo\fP:
-.IP "\fBdes\-cbc\fP" 12
-DES CBC encryption (key size = 56 bit).
-.IP "\fB3des\-cbc\fP" 12
-Triple DES CBC encryption (key size = 168 bit).
-.RE
-.PP
-.B \-o, \-\-out \fItype\fP[=\fIfilename\fP]
-.RS 4
-Output file for certificate enrollment. This option can be specified multiple times to specify output files for every \fItype\fP.
-.PP
-Supported values for \fItype\fP:
-.IP "\fBpkcs1\fP" 12
-RSA private key in PKCS#1 file format. If specified, the RSA key used for enrollment is stored in file \fIfilename\fP.
-If none of the \fItypes\fP listed below are specified, \fBscepclient\fP will stop after outputting this file.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/private/myKey.der.
-.IP "\fBpkcs10\fP" 12
-PKCS#10 certificate request. If specified, the PKCS#10 request used or certificate enrollment is stored in file \fIfilename\fP.
-If none of the \fItypes\fP listed below are specified, \fBscepclient\fP will stop after outputting this file.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/req/myReq.der.
-.IP "\fBpkcs7\fP" 12
-PKCS#7 SCEP request as it is sent using HTTP to the SCEP server. If specified, this SCEP request is stored in file \fIfilename\fP.
-If none of \fItypes\fP listed below is not specified, \fBscepclient\fP will stop after outputting this file.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/req/pkcs7.der.
-.IP "\fBcert-self\fP" 12
-Self-signed certificate. If specified the self-signed certificate is stored in file \fIfilename\fP.
-.br
-The default \fIfilename\fP is $CONFDIR/ipsec.d/certs/selfCert.der.
-.IP "\fBcert\fP" 12
-Enrolled certificate. This \fItype\fP must be specified for certificate enrollment.
-The enrolled certificate is stored in file \fIfilename\fP.
-.br
-The default \fIfilename\fP is set to $CONFDIR/ipsec.d/certs/myCert.der.
-.RE
-.PP
-.B \-m, \-\-method \fImethod\fP
-.RS 4
-Change HTTP request method for certificate enrollment. Default is \fBget\fP.
-.PP
-Supported values for \fImethod\fP:
-.IP "\fBpost\fP" 12
-Certificate enrollment using HTTP POST. Must be supported by the given SCEP server.
-.IP "\fBget\fP" 12
-Certificate enrollment using HTTP GET.
-.RE
-.PP
-.B \-t, \-\-interval \fIseconds\fP
-.RS 4
-Set interval time in seconds when polling in manual mode.
-The default interval is set to 5 seconds.
-.RE
-.PP
-.B \-x, \-\-maxpolltime \fIseconds\fP
-.RS 4
-Set max time in seconds to poll in manual mode.
-The default max time is set to unlimited.
-.RE
-
-.SS Debugging Output Options:
-.B \-A, \-\-debug\-all
-.RS 4
-Log everything except private data.
-.RE
-.PP
-.B \-P, \-\-debug\-parsing
-.RS 4
-Log parsing relevant stuff.
-.RE
-.PP
-.B \-R, \-\-debug\-raw
-.RS 4
-Log raw hex dumps.
-.RE
-.PP
-.B \-C, \-\-debug\-control
-.RS 4
-Log informations about control flow.
-.RE
-.PP
-.B \-M, \-\-debug\-controlmore
-.RS 4
-Log more detailed informations about control flow.
-.RE
-.PP
-.B \-X, \-\-debug\-private
-.RS 4
-Log sensitive data (e.g. private keys).
-.RE
-.SH "EXAMPLES"
-.B ipsec scepclient \-\-out caCert \-\-url http://scepserver/cgi\-bin/pkiclient.exe \-f
-.RS 4
-Acquire CA certificate from SCEP server and store it in the default file $CONFDIR/ipsec.d/cacerts/caCert.der.
-If more then one CA certificate is returned, store them in files named caCert.der\-1', caCert.der\-2', etc.
-.br
-Existing files are overwritten.
-.RE
-.PP
-.B ipsec scepclient \-\-out pkcs1=joeKey.der \-k 1024
-.RS 4
-Generate RSA private key with key length of 1024 bit and store it in file joeKey.der.
-.RE
-.PP
-.B ipsec scepclient \-\-in pkcs1=joeKey.der \-\-out pkcs10=joeReq.der \e
-.br
-.B \-\-dn \*(rqC=AT, CN=John Doe\*(rq \-s email=john@doe.com \-p mypassword
-.RS 4
-Generate a PKCS#10 request and store it in file joeReq.der. Use the RSA private key joeKey.der
-created earlier to sign the PKCS#10\-Request. In addition to the distinguished name include a
-email\-subjectAltName and a challenge password in the request.
-.RE
-.PP
-.B ipsec scepclient \-\-out pkcs1=joeKey.der \-\-out cert==joeCert.der \e
-.br
-.B \-\-dn \*(rqC=CH, CN=John Doe\*(rq \-k 512 \-p 5xH2pnT7wq \e
-.br
-.B \-\-url http://scep.hsr.ch/cgi\-bin/pkiclient.exe \e
-.br
-.B \-\-in cacert\-enc=caCert.der \-\-in cacert\-sig=caCert.der
-.RS 4
-Generate a new RSA key for the request and store it in joeKey.der. Then enroll a certificate and store as joeCert.der.
-The challenge password is '5xH2pnT7wq'. The encryption and signature check has to be made with the same CA certificate
-caCert.der.
-.RE
-
-
-.SH "BUGS"
-\fB\-\-optionsfrom\fP seems to have parsing problems reading option files containing strings in quotation marks.
-.SH "COPYRIGHT"
-Copyright (C) 2005 Jan Hutter, Martin Willi
-.br
-Hochschule fuer Technik Rapperswil
-.PP
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-.PP
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
diff --git a/programs/scepclient/scepclient.c b/programs/scepclient/scepclient.c
deleted file mode 100644
index bde460844..000000000
--- a/programs/scepclient/scepclient.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @file main.c
- * @brief scepclient main program
- */
-
-/**
- * @mainpage SCEP for Linux strongSwan
- *
- * Documentation of SCEP for Linux StrongSwan
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <time.h>
-#include <gmp.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-#include "../pluto/oid.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
-#include "../pluto/pkcs7.h"
-#include "../pluto/certs.h"
-#include "../pluto/fetch.h"
-#include "../pluto/rnd.h"
-
-#include "rsakey.h"
-#include "pkcs10.h"
-#include "scep.h"
-
-/*
- * definition of some defaults
- */
-
-/* default name of DER-encoded PKCS#1 private key file */
-#define DEFAULT_FILENAME_PKCS1 "myKey.der"
-
-/* default name of DER-encoded PKCS#10 certificate request file */
-#define DEFAULT_FILENAME_PKCS10 "myReq.der"
-
-/* default name of DER-encoded PKCS#7 file */
-#define DEFAULT_FILENAME_PKCS7 "pkcs7.der"
-
-/* default name of DER-encoded self-signed X.509 certificate file */
-#define DEFAULT_FILENAME_CERT_SELF "selfCert.der"
-
-/* default name of DER-encoded X.509 certificate file */
-#define DEFAULT_FILENAME_CERT "myCert.der"
-
-/* default name of DER-encoded CA cert file used for key encipherment */
-#define DEFAULT_FILENAME_CACERT_ENC "caCert.der"
-
-/* default name of the der encoded CA cert file used for signature verification */
-#define DEFAULT_FILENAME_CACERT_SIG "caCert.der"
-
-/* default prefix of the der encoded CA certificates received from the SCEP server */
-#define DEFAULT_FILENAME_PREFIX_CACERT "caCert.der"
-
-/* default certificate validity */
-#define DEFAULT_CERT_VALIDITY 5 * 3600 * 24 * 365 /* seconds */
-
-/* default polling time interval in SCEP manual mode */
-#define DEFAULT_POLL_INTERVAL 20 /* seconds */
-
-/* default key length for self-generated RSA keys */
-#define DEFAULT_RSA_KEY_LENGTH 2048 /* bits */
-
-/* default distinguished name */
-#define DEFAULT_DN "C=CH, O=Linux strongSwan, CN="
-
-/* challenge password buffer size */
-#define MAX_PASSWORD_LENGTH 256
-
-/* Max length of filename for tempfile */
-#define MAX_TEMP_FILENAME_LENGTH 256
-
-
-/* current scepclient version */
-static const char *scepclient_version = "1.0";
-
-/* by default the CRL policy is lenient */
-bool strict_crl_policy = FALSE;
-
-/* by default pluto does not check crls dynamically */
-long crl_check_interval = 0;
-
-/* by default pluto logs out after every smartcard use */
-bool pkcs11_keep_state = FALSE;
-
-
-/*
- * Global variables
- */
-
-RSA_private_key_t *private_key = NULL;
-
-chunk_t pkcs1;
-chunk_t pkcs7;
-chunk_t subject;
-chunk_t challengePassword;
-chunk_t serialNumber;
-chunk_t transID;
-chunk_t fingerprint;
-chunk_t issuerAndSubject;
-chunk_t getCertInitial;
-chunk_t scep_response;
-cert_t cert;
-
-x509cert_t *x509_signer = NULL;
-x509cert_t *x509_ca_enc = NULL;
-x509cert_t *x509_ca_sig = NULL;
-generalName_t *subjectAltNames = NULL;
-pkcs10_t *pkcs10 = NULL;
-
-/**
- * @brief exit scepclient
- *
- * The log is closed and leaks are reported
- * if LEAK_DETECTIVE is activated
- *
- * @param status 0 = OK, 1 = general discomfort
- */
-static void
-exit_scepclient(err_t message, ...)
-{
- if (private_key != NULL)
- {
- free_RSA_private_content(private_key);
- pfree(private_key);
- }
- freeanychunk(pkcs1);
- freeanychunk(pkcs7);
- freeanychunk(subject);
- freeanychunk(serialNumber);
- freeanychunk(transID);
- freeanychunk(fingerprint);
- freeanychunk(issuerAndSubject);
- freeanychunk(getCertInitial);
- if (scep_response.ptr != NULL)
- free(scep_response.ptr);
-
- free_generalNames(subjectAltNames, TRUE);
- if (x509_signer != NULL)
- x509_signer->subjectAltName = NULL;
-
- free_x509cert(x509_signer);
- free_x509cert(x509_ca_enc);
- free_x509cert(x509_ca_sig);
- pkcs10_free(pkcs10);
-
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
-
- /* print any error message to stderr */
- if (message != NULL && *message != '\0')
- {
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- fprintf(stderr, "error: %s\n", m);
- exit(-1);
- }
- exit(0);
-}
-
-/**
- * @brief prints the program version and exits
- *
- */
-static void
-version(void)
-{
- printf("scepclient %s\n", scepclient_version);
- exit_scepclient(NULL);
-}
-
-/**
- * @brief prints the usage of the program to the stderr output
- *
- * If message is set, program is exitet with 1 (error)
- * @param message message in case of an error
- */
-static void
-usage(const char *message)
-{
- fprintf(stderr,
- "Usage: scepclient\n"
- " --help (-h) show usage and exit\n"
- " --version (-v) show version and exit\n"
- " --quiet (-q) do not write log output to stderr\n"
- " --in (-i) <type>[=<filename>] use <filename> of <type> for input \n"
- " <type> = pkcs1 | cacert-enc | cacert-sig\n"
- " - if no pkcs1 input is defined, a \n"
- " RSA key will be generated\n"
- " - if no filename is given, default is used\n"
- " --out (-o) <type>[=<filename>] write output of <type> to <filename>\n"
- " multiple outputs are allowed\n"
- " <type> = pkcs1 | pkcs10 | pkcs7 | cert-self | cert | cacert\n"
- " - type cacert defines filename prefix of\n"
- " received CA certificate(s)\n"
- " - if no filename is given, default is used\n"
- " --optionsfrom (-+) <filename> reads additional options from given file\n"
- " --force (-f) force existing file(s)\n"
- "\n"
- "Options for key generation (pkcs1):\n"
- " --keylength (-k) <bits> key length for RSA key generation\n"
- "(default: 2048 bits)\n"
- "\n"
- "Options for validity:\n"
- " --days (-D) <days> validity in days\n"
- " --startdate (-S) <YYMMDDHHMMSS>Z not valid before date\n"
- " --enddate (-E) <YYMMDDHHMMSS>Z not valid after date\n"
- "\n"
- "Options for request generation (pkcs10):\n"
- " --dn (-d) <dn> comma separated list of distinguished names\n"
- " --subjectAltName (-s) <t>=<v> include subjectAltName in certificate request\n"
- " <t> = email | dns | ip \n"
- " --password (-p) <pw> challenge password\n"
- " - if pw is '%%prompt', password gets prompted for\n"
- " --algorithm (-a) <algo> use specified algorithm for PKCS#7 encryption\n"
- " <algo> = des-cbc | 3des-cbc (default: 3des-cbc)\n"
- "\n"
- "Options for enrollment (cert):\n"
- " --url (-u) <url> url of the SCEP server\n"
- " --method (-m) post | get http request type\n"
- " --interval (-t) <seconds> manual mode poll interval in seconds (default 20s)\n"
- " --maxpolltime (-x) <seconds> max poll time in seconds when in manual mode\n"
- " (default: unlimited)\n"
-#ifdef DEBUG
- "\n"
- "Debugging output:\n"
- " --debug-all (-A) show everything except private\n"
- " --debug-parsing (-P) show parsing relevant stuff\n"
- " --debug-raw (-R) show raw hex dumps\n"
- " --debug-control (-C) show control flow output\n"
- " --debug-controlmore (-M) show more control flow\n"
- " --debug-private (-X) show sensitive data (private keys, etc.)\n"
-#endif
- );
- exit_scepclient(message);
-}
-
-/**
- * @brief main of scepclient
- *
- * @param argc number of arguments
- * @param argv pointer to the argument values
- */
-int main(int argc, char **argv)
-{
- /* external values */
- extern char * optarg;
- extern int optind;
-
- /* type of input and output files */
- typedef enum {
- PKCS1 = 0x01,
- PKCS10 = 0x02,
- PKCS7 = 0x04,
- CERT_SELF = 0x08,
- CERT = 0x10,
- CACERT_ENC = 0x20,
- CACERT_SIG = 0x40
- } scep_filetype_t;
-
- /* filetype to read from, defaults to "generate a key" */
- scep_filetype_t filetype_in = 0;
-
- /* filetype to write to, no default here */
- scep_filetype_t filetype_out = 0;
-
- /* input files */
- char *file_in_pkcs1 = DEFAULT_FILENAME_PKCS1;
- char *file_in_cacert_enc = DEFAULT_FILENAME_CACERT_ENC;
- char *file_in_cacert_sig = DEFAULT_FILENAME_CACERT_SIG;
-
- /* output files */
- char *file_out_pkcs1 = DEFAULT_FILENAME_PKCS1;
- char *file_out_pkcs10 = DEFAULT_FILENAME_PKCS10;
- char *file_out_pkcs7 = DEFAULT_FILENAME_PKCS7;
- char *file_out_cert_self = DEFAULT_FILENAME_CERT_SELF;
- char *file_out_cert = DEFAULT_FILENAME_CERT;
- char *file_out_prefix_cacert = DEFAULT_FILENAME_PREFIX_CACERT;
-
- /* by default user certificate is requested */
- bool request_ca_certificate = FALSE;
-
- /* by default existing files are not overwritten */
- bool force = FALSE;
-
- /* length of RSA key in bits */
- u_int rsa_keylength = DEFAULT_RSA_KEY_LENGTH;
-
- /* validity of self-signed certificate */
- time_t validity = DEFAULT_CERT_VALIDITY;
- time_t notBefore = 0;
- time_t notAfter = 0;
-
- /* distinguished name for requested certificate, ASCII format */
- char *distinguishedName = NULL;
-
- /* challenge password */
- char challenge_password_buffer[MAX_PASSWORD_LENGTH];
-
- /* symmetric encryption algorithm used by pkcs7, default is 3DES */
- int pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
-
- /* digest algorithm used by pkcs7, default is MD5 */
- int pkcs7_digest_alg = OID_MD5;
-
- /* signature algorithm used by pkcs10, default is MD5 with RSA encryption */
- int pkcs10_signature_alg = OID_MD5;
-
- /* URL of the SCEP-Server */
- char *scep_url = NULL;
-
- /* http request method, default is GET */
- fetch_request_t request_type = FETCH_GET;
-
- /* poll interval time in manual mode in seconds */
- u_int poll_interval = DEFAULT_POLL_INTERVAL;
-
- /* maximum poll time */
- u_int max_poll_time = 0;
-
- err_t ugh = NULL;
-
- /* initialize global variables */
- pkcs1 = empty_chunk;
- pkcs7 = empty_chunk;
- serialNumber = empty_chunk;
- transID = empty_chunk;
- fingerprint = empty_chunk;
- issuerAndSubject = empty_chunk;
- challengePassword = empty_chunk;
- getCertInitial = empty_chunk;
- scep_response = empty_chunk;
- log_to_stderr = TRUE;
-
- for (;;)
- {
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "quiet", no_argument, NULL, 'q' },
- { "in", required_argument, NULL, 'i' },
- { "out", required_argument, NULL, 'o' },
- { "force", no_argument, NULL, 'f' },
- { "keylength", required_argument, NULL, 'k' },
- { "dn", required_argument, NULL, 'd' },
- { "days", required_argument, NULL, 'D' },
- { "startdate", required_argument, NULL, 'S' },
- { "enddate", required_argument, NULL, 'E' },
- { "subjectAltName", required_argument, NULL, 's' },
- { "password", required_argument, NULL, 'p' },
- { "algorithm", required_argument, NULL, 'a' },
- { "url", required_argument, NULL, 'u' },
- { "method", required_argument, NULL, 'm' },
- { "interval", required_argument, NULL, 't' },
- { "maxpolltime", required_argument, NULL, 'x' },
-#ifdef DEBUG
- { "debug-all", no_argument, NULL, 'A' },
- { "debug-parsing", no_argument, NULL, 'P'},
- { "debug-raw", no_argument, NULL, 'R'},
- { "debug-control", no_argument, NULL, 'C'},
- { "debug-controlmore", no_argument, NULL, 'M'},
- { "debug-private", no_argument, NULL, 'X'},
-#endif
- { 0,0,0,0 }
- };
-
- /* parse next option */
- int c = getopt_long(argc, argv, "hv+:qi:o:fk:d:s:p:a:u:m:t:x:APRCMS", long_opts, NULL);
-
- switch (c)
- {
- case EOF: /* end of flags */
- break;
-
- case 'h': /* --help */
- usage(NULL);
-
- case 'v': /* --version */
- version();
-
- case 'q': /* --quiet */
- log_to_stderr = FALSE;
- continue;
-
- case 'i': /* --in <type> [= <filename>] */
- {
- char *filename = strstr(optarg, "=");
-
- if (filename)
- {
- /* replace '=' by '\0' */
- *filename = '\0';
- /* set pointer to start of filename */
- filename++;
- }
- if (strcasecmp("pkcs1", optarg) == 0)
- {
- filetype_in |= PKCS1;
- if (filename)
- file_in_pkcs1 = filename;
- }
- else if (strcasecmp("cacert-enc", optarg) == 0)
- {
- filetype_in |= CACERT_ENC;
- if (filename)
- file_in_cacert_enc = filename;
- }
- else if (strcasecmp("cacert-sig", optarg) == 0)
- {
- filetype_in |= CACERT_SIG;
- if (filename)
- file_in_cacert_sig = filename;
- }
- else
- {
- usage("invalid --in file type");
- }
- continue;
- }
-
- case 'o': /* --out <type> [= <filename>] */
- {
- char *filename = strstr(optarg, "=");
-
- if (filename)
- {
- /* replace '=' by '\0' */
- *filename = '\0';
- /* set pointer to start of filename */
- filename++;
- }
- if (strcasecmp("pkcs1", optarg) == 0)
- {
- filetype_out |= PKCS1;
- if (filename)
- file_out_pkcs1 = filename;
- }
- else if (strcasecmp("pkcs10", optarg) == 0)
- {
- filetype_out |= PKCS10;
- if (filename)
- file_out_pkcs10 = filename;
- }
- else if (strcasecmp("pkcs7", optarg) == 0)
- {
- filetype_out |= PKCS7;
- if (filename)
- file_out_pkcs7 = filename;
- }
- else if (strcasecmp("cert-self", optarg) == 0)
- {
- filetype_out |= CERT_SELF;
- if (filename)
- file_out_cert_self = filename;
- }
- else if (strcasecmp("cert", optarg) == 0)
- {
- filetype_out |= CERT;
- if (filename)
- file_out_cert = filename;
- }
- else if (strcasecmp("cacert", optarg) == 0)
- {
- request_ca_certificate = TRUE;
- if (filename)
- file_out_prefix_cacert = filename;
- }
- else
- {
- usage("invalid --out file type");
- }
- continue;
- }
-
- case 'f': /* --force */
- force = TRUE;
- continue;
-
- case '+': /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- case 'k': /* --keylength <length> */
- {
- div_t q;
-
- rsa_keylength = atoi(optarg);
- if (rsa_keylength == 0)
- usage("invalid keylength");
-
- /* check if key length is a multiple of 8 bits */
- q = div(rsa_keylength, 2*BITS_PER_BYTE);
- if (q.rem != 0)
- {
- exit_scepclient("keylength is not a multiple of %d bits!"
- , 2*BITS_PER_BYTE);
- }
- continue;
- }
-
- case 'D': /* --days */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing number of days");
- {
- char *endptr;
- long days = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || days <= 0)
- usage("<days> must be a positive number");
- validity = 24*3600*days;
- }
- continue;
-
- case 'S': /* --startdate */
- if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
- usage("date format must be YYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 13 };
- notBefore = asn1totime(&date, ASN1_UTCTIME);
- }
- continue;
-
- case 'E': /* --enddate */
- if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
- usage("date format must be YYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 13 };
- notAfter = asn1totime(&date, ASN1_UTCTIME);
- }
- continue;
-
- case 'd': /* --dn */
- if (distinguishedName)
- usage("only one distinguished name allowed");
- distinguishedName = optarg;
- continue;
-
- case 's': /* --subjectAltName */
- {
- generalNames_t kind;
- char *value = strstr(optarg, "=");
-
- if (value)
- {
- /* replace '=' by '\0' */
- *value = '\0';
- /* set pointer to start of value */
- value++;
- }
-
- if (!strcasecmp("email", optarg))
- kind = GN_RFC822_NAME;
- else if (!strcasecmp("dns", optarg))
- kind = GN_DNS_NAME;
- else if (!strcasecmp("ip", optarg))
- kind = GN_IP_ADDRESS;
- else
- {
- usage("invalid --subjectAltName type");
- continue;
- }
- pkcs10_add_subjectAltName(&subjectAltNames, kind, value);
- continue;
- }
-
- case 'p': /* --password */
- if (challengePassword.len > 0)
- usage("only one challenge password allowed");
-
- if (strcasecmp("%prompt", optarg) == 0)
- {
- printf("Challenge password: ");
- if (fgets(challenge_password_buffer, sizeof(challenge_password_buffer)-1, stdin))
- {
- challengePassword.ptr = challenge_password_buffer;
- /* discard the terminating '\n' from the input */
- challengePassword.len = strlen(challenge_password_buffer) - 1;
- }
- else
- {
- usage("challenge password could not be read");
- }
- }
- else
- {
- challengePassword.ptr = optarg;
- challengePassword.len = strlen(optarg);
- }
- continue;
-
- case 'u': /* -- url */
- if (scep_url)
- usage("only one URL argument allowed");
- scep_url = optarg;
- continue;
-
- case 'm': /* --method */
- if (strcasecmp("post", optarg) == 0)
- request_type = FETCH_POST;
- else if (strcasecmp("get", optarg) == 0)
- request_type = FETCH_GET;
- else
- usage("invalid http request method specified");
- continue;
-
- case 't': /* --interval */
- poll_interval = atoi(optarg);
- if (poll_interval <= 0)
- usage("invalid interval specified");
- continue;
-
- case 'x': /* --maxpolltime */
- max_poll_time = atoi(optarg);
- if (max_poll_time < 0)
- usage("invalid maxpolltime specified");
- continue;
-
- case 'a': /*--algorithm */
- if (strcasecmp("des-cbc", optarg) == 0)
- pkcs7_symmetric_cipher = OID_DES_CBC;
- else if (strcasecmp("3des-cbc", optarg) == 0)
- pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
- else
- usage("invalid encryption algorithm specified");
- continue;
-#ifdef DEBUG
- case 'A': /* --debug-all */
- base_debugging |= DBG_ALL;
- continue;
- case 'P': /* debug parsing */
- base_debugging |= DBG_PARSING;
- continue;
- case 'R': /* debug raw */
- base_debugging |= DBG_RAW;
- continue;
- case 'C': /* debug control */
- base_debugging |= DBG_CONTROL;
- continue;
- case 'M': /* debug control more */
- base_debugging |= DBG_CONTROLMORE;
- continue;
- case 'X': /* debug private */
- base_debugging |= DBG_PRIVATE;
- continue;
-#endif
- default:
- usage("unknown option");
- }
- /* break from loop */
- break;
- }
-
- init_log("scepclient");
- cur_debugging = base_debugging;
- init_rnd_pool();
- init_fetch();
-
- if ((filetype_out == 0) && (!request_ca_certificate))
- usage ("--out filetype required");
-
- if (request_ca_certificate && (filetype_out > 0 || filetype_in > 0))
- usage("in CA certificate request, no other --in or --out option allowed");
-
- /* check if url is given, if cert output defined */
- if (((filetype_out & CERT) || request_ca_certificate) && !scep_url)
- usage("URL of SCEP server required");
-
- /* check for sanity of --in/--out */
- if (!filetype_in && (filetype_in > filetype_out))
- usage("cannot generate --out of given --in!");
-
- /*
- * input of PKCS#1 file
- */
- private_key = alloc_thing(RSA_private_key_t, "RSA_private_key_t");
-
- if (filetype_in & PKCS1) /* load an RSA key pair from file */
- {
- prompt_pass_t pass = { "", FALSE, STDIN_FILENO };
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_in_pkcs1);
-
- ugh = load_rsa_private_key(path, &pass, private_key);
- }
- else /* generate an RSA key pair */
- {
- ugh = generate_rsa_private_key(rsa_keylength, private_key);
- }
- if (ugh != NULL)
- exit_scepclient(ugh);
-
- /* check for minimum key length */
- if ((private_key->pub.k) < RSA_MIN_OCTETS)
- {
- exit_scepclient("length of RSA key has to be at least %d bits"
- ,RSA_MIN_OCTETS * BITS_PER_BYTE);
- }
-
- /*
- * input of PKCS#10 file
- */
- if (filetype_in & PKCS10)
- {
- /* user wants to load a pkcs10 request
- * operation is not yet supported
- * would require a PKCS#10 parsing function
-
- pkcs10 = pkcs10_read_from_file(file_in_pkcs10);
-
- */
- }
- else
- {
- char buf[IDTOA_BUF];
- chunk_t dn = empty_chunk;
-
- dn.ptr = buf;
-
- if (distinguishedName == NULL)
- {
- char buf[BUF_LEN];
- int n = sprintf(buf, DEFAULT_DN);
-
- /* set the common name to the hostname */
- if (gethostname(buf + n, BUF_LEN - n) || strlen(buf) == n)
- {
- exit_scepclient("no hostname defined, use "
- "--dn <distinguished name> option");
- }
- distinguishedName = buf;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("dn: '%s'", distinguishedName);
- )
- ugh = atodn(distinguishedName, &dn);
- if (ugh != NULL)
- exit_scepclient(ugh);
-
- clonetochunk(subject, dn.ptr, dn.len, "subject dn");
-
- DBG(DBG_CONTROL,
- DBG_log("building pkcs10 object:")
- )
- pkcs10 = pkcs10_build(private_key, subject, challengePassword
- , subjectAltNames, pkcs10_signature_alg);
- scep_generate_pkcs10_fingerprint(pkcs10->request, &fingerprint);
- plog(" fingerprint: %.*s", (int)fingerprint.len, fingerprint.ptr);
- }
-
- /*
- * output of PKCS#10 file
- */
- if (filetype_out & PKCS10)
- {
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
-
- if (!write_chunk(path, "pkcs10", pkcs10->request, 0022, force))
- exit_scepclient("could not write pkcs10 file '%s'", path);
-
- filetype_out &= ~PKCS10; /* delete PKCS10 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * output of PKCS#1 file
- */
- if (filetype_out & PKCS1)
- {
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_out_pkcs1);
-
- DBG(DBG_CONTROL,
- DBG_log("building pkcs1 object:")
- )
- pkcs1 = pkcs1_build_private_key(private_key);
-
- if (!write_chunk(path, "pkcs1", pkcs1, 0066, force))
- exit_scepclient("could not write pkcs1 file '%s'", path);
-
- filetype_out &= ~PKCS1; /* delete PKCS1 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- scep_generate_transaction_id((const RSA_public_key_t *)private_key
- , &transID, &serialNumber);
- plog(" transaction ID: %.*s", (int)transID.len, transID.ptr);
-
- /* generate a self-signed X.509 certificate */
- x509_signer = alloc_thing(x509cert_t, "signer cert");
- *x509_signer = empty_x509cert;
- x509_signer->serialNumber = serialNumber;
- x509_signer->sigAlg = OID_SHA1_WITH_RSA;
- x509_signer->issuer = subject;
- x509_signer->notBefore = (notBefore)? notBefore
- : time(NULL);
- x509_signer->notAfter = (notAfter)? notAfter
- : x509_signer->notBefore + validity;
- x509_signer->subject = subject;
- x509_signer->subjectAltName = subjectAltNames;
-
- build_x509cert(x509_signer, (const RSA_public_key_t *)private_key
- , private_key);
-
- /*
- * output of self-signed X.509 certificate file
- */
- if (filetype_out & CERT_SELF)
- {
- const char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
-
- if (!write_chunk(path, "self-signed cert", x509_signer->certificate, 0022, force))
- exit_scepclient("could not write self-signed cert file '%s'", path);
-;
- filetype_out &= ~CERT_SELF; /* delete CERT_SELF flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * load ca encryption certificate
- */
- {
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
- cert_t cert;
-
- if (!load_cert(path, "encryption cacert", &cert))
- exit_scepclient("could not load encryption cacert file '%s'", path);
- x509_ca_enc = cert.u.x509;
- }
-
- /*
- * input of PKCS#7 file
- */
- if (filetype_in & PKCS7)
- {
- /* user wants to load a pkcs7 encrypted request
- * operation is not yet supported!
- * would require additional parsing of transaction-id
-
- pkcs7 = pkcs7_read_from_file(file_in_pkcs7);
-
- */
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("building pkcs7 request")
- )
- pkcs7 = scep_build_request(pkcs10->request
- , transID, SCEP_PKCSReq_MSG
- , x509_ca_enc, pkcs7_symmetric_cipher
- , x509_signer, pkcs7_digest_alg, private_key);
- }
-
- /*
- * output pkcs7 encrypted and signed certificate request
- */
- if (filetype_out & PKCS7)
- {
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
-
- if (!write_chunk(path, "pkcs7 encrypted request", pkcs7, 0022, force))
- exit_scepclient("could not write pkcs7 file '%s'", path);
-;
- filetype_out &= ~PKCS7; /* delete PKCS7 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * output certificate fetch from SCEP server
- */
- if (filetype_out & CERT)
- {
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
- cert_t cert;
- time_t poll_start;
-
- x509cert_t *certs = NULL;
- chunk_t envelopedData = empty_chunk;
- chunk_t certData = empty_chunk;
- contentInfo_t data = empty_contentInfo;
- scep_attributes_t attrs = empty_scep_attributes;
-
- if (!load_cert(path, "signature cacert", &cert))
- exit_scepclient("could not load signature cacert file '%s'", path);
- x509_ca_sig = cert.u.x509;
-
- if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION
- , request_type, &scep_response))
- {
- exit_scepclient("did not receive a valid scep response");
- }
- ugh = scep_parse_response(scep_response, transID, &data, &attrs
- , x509_ca_sig);
- if (ugh != NULL)
- exit_scepclient(ugh);
-
- /* in case of manual mode, we are going into a polling loop */
- if (attrs.pkiStatus == SCEP_PENDING)
- {
- plog(" scep request pending, polling every %d seconds"
- , poll_interval);
- time(&poll_start);
- issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
- , x509_ca_sig->subject
- , subject);
- }
- while (attrs.pkiStatus == SCEP_PENDING)
- {
- if (max_poll_time > 0
- && (time(NULL) - poll_start >= max_poll_time))
- {
- exit_scepclient("maximum poll time reached: %d seconds"
- , max_poll_time);
- }
- DBG(DBG_CONTROL,
- DBG_log("going to sleep for %d seconds", poll_interval)
- )
- sleep(poll_interval);
- free(scep_response.ptr);
-
- DBG(DBG_CONTROL,
- DBG_log("fingerprint: %.*s", (int)fingerprint.len, fingerprint.ptr);
- DBG_log("transaction ID: %.*s", (int)transID.len, transID.ptr)
- )
-
- freeanychunk(getCertInitial);
- getCertInitial = scep_build_request(issuerAndSubject
- , transID, SCEP_GetCertInitial_MSG
- , x509_ca_enc, pkcs7_symmetric_cipher
- , x509_signer, pkcs7_digest_alg, private_key);
-
- if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION
- , request_type, &scep_response))
- {
- exit_scepclient("did not receive a valid scep response");
- }
- ugh = scep_parse_response(scep_response, transID, &data, &attrs
- , x509_ca_sig);
- if (ugh != NULL)
- exit_scepclient(ugh);
- }
-
- if (attrs.pkiStatus != SCEP_SUCCESS)
- {
- exit_scepclient("reply status is not 'SUCCESS'");
- }
-
- envelopedData = data.content;
-
- if (data.type != OID_PKCS7_DATA
- || !parse_asn1_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
- {
- exit_scepclient("contentInfo is not of type 'data'");
- }
- if (!pkcs7_parse_envelopedData(envelopedData, &certData
- , serialNumber, private_key))
- {
- exit_scepclient("could not decrypt envelopedData");
- }
- if (!pkcs7_parse_signedData(certData, NULL, &certs, NULL, NULL))
- {
- exit_scepclient("error parsing the scep response");
- }
- freeanychunk(certData);
-
- /* store the end entity certificate */
- path = concatenate_paths(HOST_CERT_PATH, file_out_cert);
- while (certs != NULL)
- {
- bool stored = FALSE;
- x509cert_t *cert = certs;
-
- if (!cert->isCA)
- {
- if (stored)
- exit_scepclient("multiple certs received, only first stored");
- if (!write_chunk(path, "requested cert", cert->certificate, 0022, force))
- exit_scepclient("could not write cert file '%s'", path);
- stored = TRUE;
- }
- certs = certs->next;
- free_x509cert(cert);
- }
- filetype_out &= ~CERT; /* delete CERT flag */
- }
-
- exit_scepclient(NULL);
- return -1; /* should never be reached */
-}
-
-
diff --git a/programs/secrets/Makefile b/programs/secrets/Makefile
deleted file mode 100644
index a853d22f2..000000000
--- a/programs/secrets/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:30 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=secrets
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:30 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 22:02:14 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/secrets/secrets.8 b/programs/secrets/secrets.8
deleted file mode 100644
index 2333a0a3e..000000000
--- a/programs/secrets/secrets.8
+++ /dev/null
@@ -1,20 +0,0 @@
-.TH IPSEC_SECRETS 8 "31 Aug 2003"
-.\" RCSID $Id: secrets.8,v 1.1 2004/03/15 20:35:30 as Exp $
-.SH NAME
-ipsec secrets \- prompt for PIN codes and passphrases
-.SH SYNOPSIS
-.B ipsec
-.B secrets
-.SH DESCRIPTION
-.I Secrets
-is an alias for
-.B ipsec auto --rereadsecrets
-and prompts for PIN codes and passphrases protecting private RSA keys.
-.SH SEE ALSO
-ipsec.secrets(5)
-.SH HISTORY
-Written for the FreeS/WAN project
-<http://www.freeswan.org>
-by Andreas Steffen.
-.SH BUGS
-None
diff --git a/programs/secrets/secrets.in b/programs/secrets/secrets.in
deleted file mode 100644
index b7e486098..000000000
--- a/programs/secrets/secrets.in
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /bin/sh
-# program which prompts for PINs and passphrases
-# alias for ipsec auto --rereadsecrets
-# Copyright (C) 2003 Andreas Steffen
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: secrets.in,v 1.1 2004/03/15 20:35:31 as Exp $
-
-ipsec auto --rereadsecrets
diff --git a/programs/send-pr/.cvsignore b/programs/send-pr/.cvsignore
deleted file mode 100644
index 953bfcf5a..000000000
--- a/programs/send-pr/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-send-pr
diff --git a/programs/send-pr/Makefile b/programs/send-pr/Makefile
deleted file mode 100644
index db7d51929..000000000
--- a/programs/send-pr/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=send-pr
-LIBFILES=ipsec_pr.template
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/send-pr/ipsec_pr.template b/programs/send-pr/ipsec_pr.template
deleted file mode 100644
index 3e809a677..000000000
--- a/programs/send-pr/ipsec_pr.template
+++ /dev/null
@@ -1,54 +0,0 @@
-SEND-PR: -*- send-pr -*-
-SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
-SEND-PR: will all comments (text enclosed in `<' and `>').
-SEND-PR:
-SEND-PR: Please consult the send-pr man page `send-pr(1)' or the Texinfo
-SEND-PR: manual if you are not sure how to fill out a problem report.
-SEND-PR: Note that the Synopsis field is mandatory. The Subject (for
-SEND-PR: the mail) will be made the same as Synopsis unless explicitly
-SEND-PR: changed.
-SEND-PR:
-SEND-PR: Choose from the following categories:
-SEND-PR:
-SEND-PR: pluto - Problems with IKE daemon
-SEND-PR: klips - Problems with kernel code
-SEND-PR: startup- Problems with start/configuration code
-SEND-PR: doc - Problems with documentation
-SEND-PR: interop- Problems with interoperability
-SEND-PR: source - source code patches/contributions
-SEND-PR: admin - Problems with freeswan.org machines
-SEND-PR:
-To: gnats-bugs@freeswan.org
-Subject:
-From: <FROM>
-Reply-To: <REPLYTO>
-Cc:
-X-send-pr-version: 4.0-alpha
-X-GNATS-Notify:
-
->Submitter-Id: <SUBMITTER>
->Originator: <DEFAULT_ORIGINATOR>
->Organization:
- unknown
->Synopsis: <One-line summary of the PR (one line)>
->Confidential: <[ yes | no ] (one line)>
->Severity: <[ critical | serious | non-critical ] (one line)>
->Priority: <[ high | medium | low ] (one line)>
->Category: <choose from a category listed above (one line)>
->Class: <[ sw-bug | dos | interop | mtu | log | doc-bug | support | change-request | mistaken | duplicate ] (one line)>
->Release: <DEFAULT_VERSION>
->Environment:
- <DEFAULT_ENVIRONMENT>
-
->IPsec-barf-location: <DEFAULT_BARF>
- <some URL with the output of ipsec barf.>
-
->Description:
- <Precise description of the problem (multiple lines)>
->How-To-Repeat:
- <code/input/activities to reproduce the problem (multiple lines)>
->Fix:
- <How to correct or work around the problem, if known (multiple lines)>
-
->IPsec-look:
-
diff --git a/programs/send-pr/send-pr.8 b/programs/send-pr/send-pr.8
deleted file mode 100644
index 73a5bbf3c..000000000
--- a/programs/send-pr/send-pr.8
+++ /dev/null
@@ -1,291 +0,0 @@
-.\" -*- nroff -*-
-.\" ---------------------------------------------------------------------------
-.\" man page for send-pr (by Heinz G. Seidl, hgs@cygnus.com)
-.\" updated Feb 1993 for GNATS 3.00 by Jeffrey Osier, jeffrey@cygnus.com
-.\"
-.\" This file is part of the Problem Report Management System (GNATS)
-.\" Copyright 1992 Cygnus Support
-.\"
-.\" This program is free software; you can redistribute it and/or
-.\" modify it under the terms of the GNU General Public
-.\" License as published by the Free Software Foundation; either
-.\" version 2 of the License, or (at your option) any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU Library General Public
-.\" License along with this program; if not, write to the Free
-.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-.\"
-.\" ---------------------------------------------------------------------------
-.nh
-.TH SEND-PR 8 xVERSIONx "February 1993"
-.SH NAME
-ipsec send-pr \- send problem report (PR) to a central support site
-.SH SYNOPSIS
-.B ipsec send-pr
-[
-.I site
-]
-[
-.B \-f
-.I problem-report
-]
-[
-.B \-t
-.I mail-address
-]
-.br
-.in +0.8i
-[
-.B \-P
-]
-[
-.B \-L
-]
-[
-.B \-s
-.I severity
-]
-[
-.B \-c
-.I address
-]
-.br
-[
-.B \-\-request-id
-]
-[
-.B \-V
-]
-.SH DESCRIPTION
-.B ipsec send-pr
-is a tool used to submit
-.I problem reports
-.\" SITE ADMINISTRATORS - change this if you use a local default
-(PRs) to a central support site. In most cases the correct
-.I site
-will be the default. This argument indicates the support site which
-is responsible for the category of problem involved. Some sites may
-use a local address as a default.
-.I site
-values are defined by using the
-.BR aliases (5).
-.LP
-.B ipsec send-pr
-invokes an editor on a problem report template (after trying to fill
-in some fields with reasonable default values). When you exit the
-editor,
-.B ipsec send-pr
-sends the completed form to the
-.I Problem Report Management System
-(\fBGNATS\fR) at a central support site. At the support site, the PR
-is assigned a unique number and is stored in the \fBGNATS\fR database
-according to its category and submitter-id. \fBGNATS\fR automatically
-replies with an acknowledgement, citing the category and the PR
-number.
-.LP
-To ensure that a PR is handled promptly, it should contain your (unique)
-\fIsubmitter-id\fR and one of the available \fIcategories\fR to identify the
-problem area. (Use
-.B `ipsec send-pr -L'
-to see a list of categories.)
-.LP
-The
-.B ipsec send-pr
-template at your site should already be customized with your
-submitter-id (running `\|\fBinstall-sid\fP \fIsubmitter-id\fP\|' to
-accomplish this is part of the installation procedures for
-.BR ipsec send-pr ).
-If this hasn't been done, see your system administrator for your
-submitter-id, or request one from your support site by invoking
-.B `ipsec send-pr \-\-request\-id'.
-If your site does not distinguish between different user sites, or if
-you are not affiliated with the support site, use
-.B `net'
-for this field.
-.LP
-The more precise your problem description and the more complete your
-information, the faster your support team can solve your problems.
-.SH OPTIONS
-.TP
-.BI \-f " problem-report"
-specify a file (\fIproblem-report\fR) which already contains a
-complete problem report.
-.B ipsec send-pr
-sends the contents of the file without invoking the editor. If
-the value for
-.I problem-report
-is
-.BR `\|\-\|' ,
-then
-.B ipsec send-pr
-reads from standard input.
-.TP
-.BI \-s " severity"
-Give the problem report the severity
-.IR severity .
-.TP
-.BI \-t " mail-address"
-Change mail address at the support site for problem reports. The
-default
-.I mail-address
-is the address used for the default
-.IR site .
-Use the
-.I site
-argument rather than this option in nearly all cases.
-.TP
-.BI \-c " address"
-Put
-.I address
-in the
-.B Cc:
-header of the message.
-.TP
-.B \-P
-print the form specified by the environment variable
-.B PR_FORM
-on standard output. If
-.B PR_FORM
-is not set, print the standard blank PR template. No mail is sent.
-.TP
-.B -L
-print the list of available categories. No mail is sent.
-.TP
-.B \-\-request\-id
-sends mail to the default support site, or
-.I site
-if specified, with a request for your
-.IR submitter-id .
-If you are
-not affiliated with
-.IR site ,
-use a
-.I submitter-id
-of
-.BR net \|'.
-.TP
-.B \-V
-Display the
-.B ipsec send-pr
-version number.
-.LP
-Note: use
-.B ipsec send-pr
-to submit problem reports rather than mailing them directly. Using
-both the template and
-.B ipsec send-pr
-itself will help ensure all necessary information will reach the
-support site.
-.SH ENVIRONMENT
-The environment variable
-.B EDITOR
-specifies the editor to invoke on the template.
-.br
-default:
-.B vi
-.sp
-If the environment variable
-.B PR_FORM
-is set, then its value is used as the file name of the template for
-your problem-report editing session. You can use this to start with a
-partially completed form (for example, a form with the identification
-fields already completed).
-.SH "HOW TO FILL OUT A PROBLEM REPORT"
-Problem reports have to be in a particular form so that a program can
-easily manage them. Please remember the following guidelines:
-.IP \(bu 3m
-describe only
-.B one problem
-with each problem report.
-.IP \(bu 3m
-For follow-up mail, use the same subject line as the one in the automatic
-acknowledgent. It consists of category, PR number and the original synopsis
-line. This allows the support site to relate several mail messages to a
-particular PR and to record them automatically.
-.IP \(bu 3m
-Please try to be as accurate as possible in the subject and/or synopsis line.
-.IP \(bu 3m
-The subject and the synopsis line are not confidential. This is
-because open-bugs lists are compiled from them. Avoid confidential
-information there.
-.LP
-See the GNU
-.B Info
-file
-.B send-pr.info
-or the document \fIReporting Problems With send-pr\fR\ for detailed
-information on reporting problems
-.SH "HOW TO SUBMIT TEST CASES, CODE, ETC."
-Submit small code samples with the PR. Contact the support site for
-instructions on submitting larger test cases and problematic source
-code.
-.SH FILES
-.ta \w'/tmp/pbad$$ 'u
-/tmp/p$$ copy of PR used in editing session
-.br
-/tmp/pf$$ copy of empty PR form, for testing purposes
-.br
-/tmp/pbad$$ file for rejected PRs
-.br
-@IPSEC_DIR@/send-pr.conf script to customize send-pr.
-.SH EMACS USER INTERFACE
-An Emacs user interface for
-.B send-pr
-with completion of field values is part of the
-.B send-pr
-distribution (invoked with
-.BR "M-x send-pr" ).
-See the file
-.B send-pr.info
-or the ASCII file
-.B INSTALL
-in the top level directory of the distribution for configuration and
-installation information. The Emacs LISP template file is
-.B send-pr-el.in
-and is installed as
-.BR send-pr.el .
-.SH INSTALLATION AND CONFIGURATION
-See
-.B send-pr.info
-or
-.B INSTALL
-for installation instructions.
-.SH SEE ALSO
-.I Reporting Problems Using send-pr
-(also installed as the GNU Info file
-.BR send-pr.info ).
-.LP
-.BR gnats (l),
-.BR query-pr (1),
-.BR edit-pr (1),
-.BR gnats (8),
-.BR queue-pr (8),
-.BR at-pr (8),
-.BR mkcat (8),
-.BR mkdist (8).
-.SH AUTHORS
-Jeffrey Osier, Brendan Kehoe, Jason Merrill, Heinz G. Seidl (Cygnus
-Support)
-.SH COPYING
-Copyright (c) 1992, 1993 Free Software Foundation, Inc.
-.PP
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-.PP
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-.PP
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
-
diff --git a/programs/send-pr/send-pr.in b/programs/send-pr/send-pr.in
deleted file mode 100755
index 6cd202470..000000000
--- a/programs/send-pr/send-pr.in
+++ /dev/null
@@ -1,643 +0,0 @@
-#!/bin/sh
-# Submit a problem report to a GNATS site.
-# Copyright (C) 2001 Milan Zamazal
-# Copyright (C) 1993, 2001 Free Software Foundation, Inc.
-# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
-# version written by Heinz G. Seidl (hgs@cygnus.com).
-# Further edited by Milan Zamazal (pdm@zamazal.org).
-# mktemp support by Yngve Svendsen (yngve.svendsen@clustra.com).
-#
-# This file is part of GNU GNATS.
-#
-# GNU GNATS is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU GNATS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU GNATS; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#
-# $Id: send-pr.in,v 1.1 2004/03/15 20:35:31 as Exp $
-#
-
-# The version of this send-pr.
-VERSION=4.0-alpha
-
-#SWAN_VERSION=
-
-# The submitter-id for your site.
-SUBMITTER=net
-
-# The place where our usual binaries live.
-BINDIR=@IPSEC_DIR@
-
-# The place where the builtin binaries are located.
-LIBDIR=@IPSEC_LIBDIR@
-LIBEXECDIR=@IPSEC_EXECDIR@
-
-# The default release for this host.
-DEFAULT_RELEASE="gnats-4.0-alpha"
-
-# The default organization.
-DEFAULT_ORGANIZATION="net"
-
-# How to read the passwd database.
-PASSWD="cat /etc/passwd"
-
-# Is the mktemp command available?
-MKTEMP="yes"
-
-ECHON=bsd
-
-# By default send-pr connects directly to the database. However, it
-# can be configured to use an existing template file by setting the
-# TEMPLATE variable below to point to a PR template generated from
-# "send-pr -P".
-TEMPLATE="$LIBDIR/ipsec_pr.template"
-
-# send-pr can use mail to submit PRs, instead of connecting to the
-# database directly. MAILPROG needs to point to a compatible mailer
-# (sendmail will work). If MAILPROG needs to have the address that
-# the mail is being sent to specified on the command line, it should
-# be specified here as well (for example, the command
-# MAILPROG="mail bugs@foo.bar.com"
-# should work). If sendmail is used, this should be set to
-# MAILPROG="/usr/lib/sendmail -oi -t"
-MAILPROG="/usr/sbin/sendmail -oi -t"
-
-# The address that PRs are sent to. Normally this can be left as "bugs";
-# however, if using mail to submit PRs, this should be set to the address
-# where PRs should be sent.
-MAILADDR="freeswan-bugs@freeswan.org"
-
-if [ $ECHON = bsd ] ; then
- ECHON1="echo -n"
- ECHON2=
-elif [ $ECHON = sysv ] ; then
- ECHON1=echo
- ECHON2='\c'
-else
- ECHON1=echo
- ECHON2=
-fi
-
-# Configuration file to be read. It must be a shell script that can redefine
-# the variables above to fit a local configuration.
-CONFIGFILE=@IPSEC_DIR@/send-pr.conf
-
-if [ -r $CONFIGFILE ]; then
- . $CONFIGFILE
-fi
-
-#
-
-if [ -z "$TMPDIR" ]; then
- TMPDIR=/tmp
-else
- if [ "`echo $TMPDIR | grep '/$'`" != "" ]; then
- TMPDIR="`echo $TMPDIR | sed -e 's,/$,,'`"
- fi
-fi
-
-# TEMP: Temporary copy of the PR, to be edited by the user.
-# BAD: The PR will end up here if the user aborts.
-# REF: The 'reference' copy of the PR template, used to verify that the user
-# actually did edit the template.
-# FIXFIL: A sed script used to remove comments from the template before
-# processing.
-if [ $MKTEMP = yes ]; then
- TEMP=`mktemp $TMPDIR/pXXXXXX` || exit 1
- BAD=`mktemp $TMPDIR/pbadXXXXXX` || exit 1
- REF=`mktemp $TMPDIR/pfXXXXXX` || exit 1
- FIXFIL=`mktemp $TMPDIR/fixXXXXXX` || exit 1
-else
- TEMP=$TMPDIR/p$$
- BAD=$TMPDIR/pbad$$
- REF=$TMPDIR/pf$$
- FIXFIL=$TMPDIR/fix$$
- bad_temp=0
- : > $TEMP || bad_temp=1
- : > $BAD || bad_temp=1
- : > $REF || bad_temp=1
- : > $FIXFIL || bad_temp=1
- if [ $bad_temp = 1 ]; then
- rm -f $TEMP $BAD $REF $FIXFIL
- exit 1;
- fi
-fi
-REMOVE_TEMP="rm -f $TEMP $BAD $REF"
-
-# find a user name
-if [ "$LOGNAME" = "" ]; then
- if [ "$USER" != "" ]; then
- LOGNAME="$USER"
- else
- LOGNAME="UNKNOWN"
- fi
-fi
-
-FROM="$LOGNAME"
-REPLYTO="${REPLY_TO:-${REPLYTO:-$LOGNAME}}"
-if [ "x$MAILPROG" != "x" ]
-then
- RESP_ALIAS="`query-pr --adm-field responsible --adm-key $LOGNAME --adm-subfield alias 2>/dev/null`"
-else
- RESP_ALIAS=""
-fi
-
-# Find out the name of the originator of this PR.
-if [ -n "$NAME" ]; then
- DEFAULT_ORIGINATOR="$NAME"
-elif [ -f $HOME/.fullname ]; then
- DEFAULT_ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
-else
- # Must use temp file due to incompatibilities in quoting behavior
- # and to protect shell metacharacters in the expansion of $LOGNAME
- $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP
- if [ "x$RESP_ALIAS" != "x" ]
- then
- DEFAULT_ORIGINATOR="$RESP_ALIAS (`cat $TEMP`)"
- else
- DEFAULT_ORIGINATOR="$FROM (`cat $TEMP`)"
- fi
- rm -f $TEMP
-fi
-
-if [ -z "$ORGANIZATION" ]
-then
- ORGANIZATION="$DEFAULT_ORGANIZATION";
-fi
-
-if [ -n "$ORGANIZATION" -a "x$ORGANIZATION" != "xunknown" ]; then
- if [ -f "$ORGANIZATION" ]; then
- ORGANIZATION="`cat $ORGANIZATION`"
- fi
- if [ -n "$ORGANIZATION" ]; then
- ORGANIZATION="$ORGANIZATION"
- elif [ -f $HOME/.organization ]; then
- ORGANIZATION="`cat $HOME/.organization`"
- fi
-fi
-
-if [ "x$ORGANIZATION" = "xunknown" ]; then
- cat <<__EOF__
-It seems that send-pr is not installed with your organization set to a useful
-value. To fix this, you need to edit the configuration file
-$CONFIGFILE
-and fill in the organization with the correct value.
-
-__EOF__
- ORGANIZATION="";
-fi 1>&2
-
-# If they don't have a preferred editor set, then use
-if [ -z "$VISUAL" ]; then
- if [ -z "$EDITOR" ]; then
- EDIT=vi
- else
- EDIT="$EDITOR"
- fi
-else
- EDIT="$VISUAL"
-fi
-
-# Find out some information.
-SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
- ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo "" | sed -e 's,|,\\|,'`
-
-# Our base command name.
-COMMAND=`echo $0 | sed -e 's,.*/,,'`
-USAGE="Usage: $COMMAND [OPTION]...
-
- -b --batch run without printing most messages
- --barf include a full barf inline rather than just look
- -c --cc=LINE put LINE to the CC header
- -d --database=DATABASE submit PR to DATABASE
- -f --file=FILE read the PR template from FILE (\`-' for stdin)
- -p --print just print the template and exit
- --request-id send a request for a user id
- -s --severity=SEVERITY PR severity
-
- -h --help display this help and exit
- -V --version output version information and exit
-"
-REMOVE=
-BATCH=
-CC=
-DEFAULT_SEVERITY=
-BARF=${BARF-false}
-
-if [ "$SYSTEM" != "" ]
-then
- DEFAULT_ENVIRONMENT="System: $SYSTEM"
-fi
-
-if [ "$SWAN_VERSION" != "" ]
-then
- DEFAULT_VERSION="$SWAN_VERSION";
-else
- DEFAULT_VERSION=`ipsec --versioncode`
-fi
-DEFAULT_VERSION=`echo $DEFAULT_VERSION | sed -e 's,\/,\\\/,'`
-
-while [ $# -gt 0 ]; do
- case "$1" in
- -r) ;; # Ignore for backward compat.
- -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
- shift ; IN_FILE="$1"
- if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
- echo "$COMMAND: cannot read $IN_FILE"
- exit 1
- fi
- ;;
- -b | --batch) BATCH=true ;;
- --barf) BARF=true ;;
- -c | --cc) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
- shift ; CC="$1"
- ;;
- -d | --database) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
- shift; GNATSDB="$1"; export GNATSDB
- ;;
- -s | --severity) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
- shift ; DEFAULT_SEVERITY="$1"
- ;;
- -p | -P | --print) PRINT=true ;;
- --request-id) REQUEST_ID=true ;;
- -h | --help) echo "$USAGE"; exit 0 ;;
- -V | --version) echo "$VERSION"; exit 0 ;;
- -*) echo "$USAGE" ; exit 1 ;;
- *) echo "$USAGE" ; exit 1 ;;
- esac
- shift
-done
-
-if [ "x$SUBMITTER" = "x" ]
-then
- SUBMITTER="unknown"
-fi
-
-if [ "x$SUBMITTER" = "xunknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
- cat << '__EOF__'
-It seems that send-pr is not installed with your unique submitter-id.
-You need to run
-
- install-sid YOUR-SID
-
-where YOUR-SID is the identification code you received with `send-pr'.
-`send-pr' will automatically insert this value into the template field
-`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net'
-for this value. If you do not know your id, run `send-pr --request-id' to
-get one from your support site.
-__EOF__
- exit 1
-fi
-
-# So the template generation code finds it.
-DEFAULT_SUBMITTERID=${SUBMITTER}
-
-# Catch some signals. ($xs kludge needed by Sun /bin/sh)
-xs=0
-trap 'rm -f $REF $TEMP $FIXFIL; exit $xs' 0
-trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP $FIXFIL; xs=1; exit' 1 3 13 15
-
-if [ "x$PRINT" = "xtrue" ]; then
- FROM="<FROM>"
- REPLYTO="<REPLYTO>"
- DEFAULT_ORIGINATOR="<DEFAULT_ORIGINATOR>"
- DEFAULT_SUBMITTERID="<SUBMITTER>"
-fi
-
-# If they told us to use a specific file, then do so.
-if [ -n "$IN_FILE" ]; then
- if [ "$IN_FILE" = "-" ]; then
- # The PR is coming from the standard input.
- cat > $TEMP
- else
- # Use the file they named.
- cat $IN_FILE > $TEMP
- fi
-else
- if [ -n "$TEMPLATE" -a -z "$PRINT_INTERN" ]; then
- # If their TEMPLATE points to a bogus entry, then bail.
- if [ ! -f "$TEMPLATE" -o ! -r "$TEMPLATE" -o ! -s "$TEMPLATE" ]; then
- echo "$COMMAND: can't seem to read your template file (\`$TEMPLATE'), ignoring TEMPLATE"
- sleep 1
- PRINT_INTERN=bad_prform
- fi
- fi
-
- if [ -n "$TEMPLATE" -a -z "$PRINT_INTERN" ]; then
- sed "s/<FROM>/$FROM/;s/<REPLYTO>/$REPLYTO/;s/<DEFAULT_ORIGINATOR>/$DEFAULT_ORIGINATOR/;s/<SUBMITTER>/$DEFAULT_SUBMITTERID/;s|<DEFAULT_ENVIRONMENT>|$DEFAULT_ENVIRONMENT|;s/<DEFAULT_BARF>/$DEFAULT_BARF/;s/<DEFAULT_VERSION>/$DEFAULT_VERSION/;" < $TEMPLATE > $TEMP ||
- ( echo "$COMMAND: could not copy $TEMPLATE" ; xs=1; exit )
- else
- # Which genius thought of iterating through this loop twice, when the
- # cp command would suffice?
- for file in $TEMP ; do
- cat > $file << '__EOF__'
-SEND-PR: -*- send-pr -*-
-SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
-SEND-PR: will all comments (text enclosed in `<' and `>').
-SEND-PR:
-SEND-PR: Please consult the send-pr man page `send-pr(1)' or the Texinfo
-SEND-PR: manual if you are not sure how to fill out a problem report.
-SEND-PR: Note that the Synopsis field is mandatory. The Subject (for
-SEND-PR: the mail) will be made the same as Synopsis unless explicitly
-SEND-PR: changed.
-SEND-PR:
-SEND-PR: Choose from the following categories:
-SEND-PR:
-__EOF__
-
- # Format the categories so they fit onto lines.
- CATEGORIES=`${BINDIR}/query-pr --valid-values Category`;
- l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 61 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {printf "SEND-PR: "; i = 0 }
- { printf ("%-'$l'.'$l's", $0);
- if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
- END { printf "\nSEND-PR:\n"; }' >> $file
-
- cat >> $file << __EOF__
-To: $MAILADDR
-Subject:
-From: $FROM
-Reply-To: $REPLYTO
-Cc: $CC
-X-send-pr-version: $VERSION
-X-GNATS-Notify:
-
-
-__EOF__
-
- #
- # Iterate through the list of input fields. fieldname is the
- # name of the field. fmtname is the formatted name of the field,
- # with >, : and extra spaces to cause the field contents to be
- # aligned.
- #
- ${BINDIR}/query-pr --list-input-fields | awk '{a[NR]=$1""; mnr = NR+1; len = length($1) + 2; if (mlen < len) mlen = len; } END { for (x = 1; x < mnr; x++) { b = ">"a[x]":"; printf ("%s %-"mlen"s&\n", a[x], b); } }' | while read fieldname fmtname
- do
- fmtname="`echo "$fmtname" | sed 's/[&]$//;'`"
- upname="`echo $fieldname | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;s/-//g;'`"
- # Grab the default value for this field.
- eval 'default_val="$DEFAULT_'${upname}'"'
- # What's stored in the field?
- type=`${BINDIR}/query-pr --field-type $fieldname | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- case $type in
- enum)
- if [ "$default_val" != "" ]
- then
- desc=$default_val;
- else
- if [ "$fieldname" != "Category" ]
- then
- values=`${BINDIR}/query-pr --valid-values $fieldname | tr '\n' ' ' | sed 's/ *$//g;s/ / | /g;s/^/[ /;s/$/ ]/;'`
- valslen=`echo "$values" | wc -c`
- else
- values="choose from a category listed above"
- valslen=1;
- fi
- if [ "$valslen" -gt 160 ]
- then
- desc="<`${BINDIR}/query-pr --field-description $fieldname` (one line)>";
- else
- desc="<${values} (one line)>";
- fi
- dpat=`echo "$desc" | tr '\]\[*+^$|\()&/' '............'`
- echo "/^>${fieldname}:/ s/${dpat}//" >> $FIXFIL
- fi
- echo "${fmtname}${desc}" >> $file
- ;;
- multitext)
- if [ "$default_val" != "" ]
- then
- desc=" $default_val";
- else
- desc=" <`${BINDIR}/query-pr --field-description $fieldname` (multiple lines)>";
- dpat=`echo "$desc" | tr '\]\[*+^$|\()&/' '............'`
- echo "s/^${dpat}//" >> $FIXFIL
- fi
- echo "${fmtname}" >> $file;
- echo "$desc" >> $file;
- ;;
- *)
- if [ "$default_val" != "" ]
- then
- desc="${default_val}"
- else
- desc="<`${BINDIR}/query-pr --field-description $fieldname` (one line)>"
- dpat=`echo "$desc" | tr '\]\[*+^$|\()&/' '............'`
- echo "/^>${fieldname}:/ s/${dpat}//" >> $FIXFIL
- fi
- echo "${fmtname}${desc}" >> $file
- ;;
- esac
- done
- done
- fi
-
- if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
- cat $TEMP
- xs=0; exit
- fi
-
- if $BARF
- then
- ipsec barf >>$TEMP
- else
- ipsec look >>$TEMP
- fi
-
- cp $TEMP $REF
-
- chmod u+w $TEMP
- if [ -z "$REQUEST_ID" ]; then
- eval $EDIT $TEMP
- else
- ed -s $TEMP << '__EOF__'
-/^Subject/s/^Subject:.*/Subject: request for a customer id/
-/^>Category/s/^>Category:.*/>Category: send-pr/
-w
-q
-__EOF__
- fi
-
- if cmp -s $REF $TEMP ; then
- echo "$COMMAND: problem report not filled out, therefore not sent"
- xs=1; exit
- fi
-fi
-
-# TEMP is the PR that we are editing. When we're done, REF will contain
-# the final PR to be sent.
-
-while [ -z "$REQUEST_ID" ]; do
- CNT=0
-
- #
- # Remove comments.
- #
- echo '/^SEND-PR:/d' >> $FIXFIL
- sed -f $FIXFIL $TEMP > $REF
-
- # REF now has the actual PR that we want to send.
-
- #
- # Check that synopsis is not empty.
- #
- if grep "^>Synopsis:[ ]*$" $REF > /dev/null
- then
- echo "$COMMAND: Synopsis must not be empty."
- CNT=`expr $CNT + 1`
- fi
-
- if [ "x$MAILPROG" = "x" ]
- then
- # Since we're not using mail, use pr-edit to check the PR. We can't
- # do much checking otherwise, sorry.
- $LIBEXECDIR/pr-edit --check-initial < $REF || CNT=`expr $CNT + 1`
- fi
-
- [ $CNT -gt 0 -a -z "$BATCH" ] &&
- echo "Errors were found with the problem report."
-
- while true; do
- if [ -z "$BATCH" ]; then
- $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
- read input
- else
- if [ $CNT -eq 0 ]; then
- input=s
- else
- input=a
- fi
- fi
- case "$input" in
- a*)
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $TEMP $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
- ;;
- e*)
- eval $EDIT $TEMP
- continue 2
- ;;
- s*)
- break 2
- ;;
- esac
- done
-done
-
-#
-# Make sure the mail has got a Subject. If not, use the same as
-# in Synopsis.
-#
-
-if grep '^Subject:[ ]*$' $REF > /dev/null
-then
- SYNOPSIS=`grep '^>Synopsis:' $REF | sed -e 's/^>Synopsis:[ ]*//'`
- ed -s $REF << __EOF__
-/^Subject:/s/:.*\$/: $SYNOPSIS/
-w
-q
-__EOF__
-fi
-
-while :
-do
- if [ "x$MAILPROG" != "x" ]
- then
- # Use mail to send the PR.
- if $MAILPROG < $REF
- then
- echo "$COMMAND: problem report mailed"
- xs=0; exit
- else
- echo "$MAILPROG failed!"
- fi
- else
- if $LIBEXECDIR/pr-edit --submit < $REF; then
- echo "$COMMAND: problem report filed"
- xs=0; exit
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- fi
- while true
- do
- if [ -z "$BATCH" ]; then
- $ECHON1 "a)bort or s)end? (file=$REF) $ECHON2"
- read input
- case "$input" in
- a*)
- break 2 ;;
- s*)
- break ;;
- esac
- else
- break 2;
- fi
- done
-done
-
-if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $TEMP $BAD
-else
- echo "$COMMAND: the problem report is not sent, is in $REF."
-fi
-
-xs=1; exit;
-
-#
-# $Log: send-pr.in,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.10 2003/07/14 12:26:17 mcr
-# use | as delimitor for $DEFAULT_ENVIRONMENT.
-# switch | to \\| when in $DEFAULT_ENVIRONMENT.
-# this is due to PR#236 where the "uname" output
-# says GNU/Linux, screwing up sed.
-#
-# Revision 1.9 2003/02/03 21:51:06 mcr
-# if MAILPROG fails, then offer to try again.
-#
-# Revision 1.8 2002/12/10 02:28:13 mcr
-# adjusted template to use gnats-bugs@freeswan.org
-# fix sed script to deal with version sanitizer.
-#
-# Revision 1.7 2002/12/10 02:17:34 mcr
-# need to init variables first
-#
-# Revision 1.6 2002/12/10 02:16:23 mcr
-# adjusted send-pr to look at LIBDIR, not LIBEXECDIR
-#
-# Revision 1.5 2002/09/30 16:04:05 mcr
-# fix for sed bug in "send-pr"
-#
-# Revision 1.4 2002/04/24 07:36:10 mcr
-# Moved from ./utils/send-pr.sh,v
-#
-# Revision 1.3 2001/11/27 15:02:55 mcr
-# added rcsids.
-# fixed submission address to be freeswan-bugs@freeswan.org
-# use new ipsec --versioncode to get version info.
-#
-#
diff --git a/programs/setup/.cvsignore b/programs/setup/.cvsignore
deleted file mode 100644
index 146f275e0..000000000
--- a/programs/setup/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-setup
diff --git a/programs/setup/Makefile b/programs/setup/Makefile
deleted file mode 100644
index f12d452b2..000000000
--- a/programs/setup/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.3 2006/02/10 11:28:15 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=setup
-EXTRA8MAN=setup.8
-
-include ../Makefile.program
diff --git a/programs/setup/setup.8 b/programs/setup/setup.8
deleted file mode 100644
index e2980ee74..000000000
--- a/programs/setup/setup.8
+++ /dev/null
@@ -1,142 +0,0 @@
-.TH IPSEC_SETUP 8 "23 July 2001"
-.\" RCSID $Id: setup.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.SH NAME
-ipsec setup \- control IPsec subsystem
-.SH SYNOPSIS
-.B ipsec
-.B setup
-[
-.B \-\-show
-|
-.B \-\-showonly
-]
-command
-.SH DESCRIPTION
-.I Setup
-controls the FreeS/WAN IPsec subsystem,
-including both the Klips kernel code and the Pluto key-negotiation daemon.
-(It is a synonym for the ``rc'' script for the subsystem;
-the system runs the equivalent of
-.B "ipsec setup start"
-at boot time,
-and
-.B "ipsec setup stop"
-at shutdown time, more or less.)
-.PP
-The action taken depends on the specific
-.IR command ,
-and on the contents of the
-.B config
-.B setup
-section of the
-IPsec configuration file (\c
-.IR /etc/ipsec.conf ,
-see
-.IR ipsec.conf (5)).
-Current
-.IR command s
-are:
-.TP 10
-.B start
-start Klips and Pluto,
-including setting up Klips to do crypto operations on the
-interface(s) specified in the configuration file,
-and (if the configuration file so specifies)
-setting up manually-keyed connections and/or
-asking Pluto to negotiate automatically-keyed connections
-to other security gateways
-.TP
-.B stop
-shut down Klips and Pluto,
-including tearing down all existing crypto connections
-.TP
-.B restart
-equivalent to
-.B stop
-followed by
-.B start
-.TP
-.B status
-report the status of the subsystem;
-normally just reports
-.B "IPsec running"
-and
-.BR "pluto pid \fInnn\fP" ,
-or
-.BR "IPsec stopped" ,
-and exits with status 0,
-but will go into more detail (and exit with status 1)
-if something strange is found.
-(An ``illicit'' Pluto is one that does not match the process ID in
-Pluto's lock file;
-an ``orphaned'' Pluto is one with no lock file.)
-.PP
-The
-.B stop
-operation tries to clean up properly even if assorted accidents
-have occurred,
-e.g. Pluto having died without removing its lock file.
-If
-.B stop
-discovers that the subsystem is (supposedly) not running,
-it will complain,
-but will do its cleanup anyway before exiting with status 1.
-.PP
-Although a number of configuration-file parameters influence
-.IR setup 's
-operations, the key one is the
-.B interfaces
-parameter, which must be right or chaos will ensue.
-.PP
-The
-.B \-\-show
-and
-.B \-\-showonly
-options cause
-.I setup
-to display the shell commands that it would execute.
-.B \-\-showonly
-suppresses their execution.
-Only
-.BR start ,
-.BR stop ,
-and
-.B restart
-commands recognize these flags.
-.SH FILES
-.ta \w'/proc/sys/net/ipv4/ip_forward'u+2n
-/etc/rc.d/init.d/ipsec the script itself
-.br
-/etc/init.d/ipsec alternate location for the script
-.br
-/etc/ipsec.conf IPsec configuration file
-.br
-/proc/sys/net/ipv4/ip_forward forwarding control
-.br
-/var/run/ipsec.info saved information
-.br
-/var/run/pluto.pid Pluto lock file
-.br
-/var/run/ipsec_setup.pid IPsec lock file
-.SH SEE ALSO
-ipsec.conf(5), ipsec(8), ipsec_manual(8), ipsec_auto(8), route(8)
-.SH DIAGNOSTICS
-All output from the commands
-.B start
-and
-.B stop
-goes both to standard
-output and to
-.IR syslogd (8),
-via
-.IR logger (1).
-Selected additional information is logged only to
-.IR syslogd (8).
-.SH HISTORY
-Written for the FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-.SH BUGS
-Old versions of
-.IR logger (1)
-inject spurious extra newlines onto standard output.
diff --git a/programs/setup/setup.in b/programs/setup/setup.in
deleted file mode 100755
index 1e43d0d67..000000000
--- a/programs/setup/setup.in
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/bin/sh
-# IPsec startup and shutdown script
-# Copyright (C) 1998, 1999, 2001 Henry Spencer.
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: setup.in,v 1.1 2004/03/15 20:35:31 as Exp $
-#
-# ipsec init.d script for starting and stopping
-# the IPsec security subsystem (KLIPS and Pluto).
-#
-# This script becomes /etc/rc.d/init.d/ipsec (or possibly /etc/init.d/ipsec)
-# and is also accessible as "ipsec setup" (the preferred route for human
-# invocation).
-#
-# The startup and shutdown times are a difficult compromise (in particular,
-# it is almost impossible to reconcile them with the insanely early/late
-# times of NFS filesystem startup/shutdown). Startup is after startup of
-# syslog and pcmcia support; shutdown is just before shutdown of syslog.
-#
-# chkconfig: 2345 47 68
-# description: IPsec provides encrypted and authenticated communications; \
-# KLIPS is the kernel half of it, Pluto is the user-level management daemon.
-
-me='ipsec setup' # for messages
-
-
-# where the private directory and the config files are
-IPSEC_EXECDIR="${IPSEC_EXECDIR-@IPSEC_EXECDIR@}"
-IPSEC_LIBDIR="${IPSEC_LIBDIR-@IPSEC_LIBDIR@}"
-IPSEC_SBINDIR="${IPSEC_SBINDIR-@IPSEC_SBINDIR@}"
-IPSEC_CONFS="${IPSEC_CONFS-@IPSEC_CONFS@}"
-
-if test " $IPSEC_DIR" = " " # if we were not called by the ipsec command
-then
- # we must establish a suitable PATH ourselves
- PATH="${IPSEC_SBINDIR}":/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin
- export PATH
-
- IPSEC_DIR="$IPSEC_LIBDIR"
- export IPSEC_DIR IPSEC_CONFS IPSEC_LIBDIR IPSEC_EXECDIR
-fi
-
-# Check that the ipsec command is available.
-found=
-for dir in `echo $PATH | tr ':' ' '`
-do
- if test -f $dir/ipsec -a -x $dir/ipsec
- then
- found=yes
- break # NOTE BREAK OUT
- fi
-done
-if ! test "$found"
-then
- echo "cannot find ipsec command -- \`$1' aborted" |
- logger -s -p daemon.error -t ipsec_setup
- exit 1
-fi
-
-# accept a few flags
-
-export IPSEC_setupflags
-IPSEC_setupflags=""
-
-config=""
-
-for dummy
-do
- case "$1" in
- --showonly|--show) IPSEC_setupflags="$1" ;;
- --config) config="--config $2" ; shift ;;
- *) break ;;
- esac
- shift
-done
-
-
-# Pick up IPsec configuration (until we have done this, successfully, we
-# do not know where errors should go, hence the explicit "daemon.error"s.)
-# Note the "--export", which exports the variables created.
-eval `ipsec _confread $config --optional --varprefix IPSEC --export --type config setup`
-if test " $IPSEC_confreadstatus" != " "
-then
- echo "$IPSEC_confreadstatus -- \`$1' aborted" |
- logger -s -p daemon.error -t ipsec_setup
- exit 1
-fi
-
-IPSEC_confreadsection=${IPSEC_confreadsection:-setup}
-export IPSEC_confreadsection
-
-IPSECsyslog=${IPSECsyslog-daemon.error}
-export IPSECsyslog
-
-# misc setup
-umask 022
-
-
-# do it
-case "$1" in
- start|--start|stop|--stop|_autostop|_autostart)
- if test " `id -u`" != " 0"
- then
- echo "permission denied (must be superuser)" |
- logger -s -p $IPSECsyslog -t ipsec_setup 2>&1
- exit 1
- fi
- tmp=/var/run/ipsec_setup.st
- (
- ipsec _realsetup $1
- echo "$?" >$tmp
- ) 2>&1 | logger -s -p $IPSECsyslog -t ipsec_setup 2>&1
- st=$?
- if test -f $tmp
- then
- st=`cat $tmp`
- rm -f $tmp
- fi
- exit $st
- ;;
-
- restart|--restart|force-reload)
- $0 $IPSEC_setupflags stop
- $0 $IPSEC_setupflags start
- ;;
-
- _autorestart) # for internal use only
- $0 $IPSEC_setupflags _autostop
- $0 $IPSEC_setupflags _autostart
- ;;
-
- status|--status)
- ipsec _realsetup $1
- exit
- ;;
-
- --version)
- echo "$me $IPSEC_VERSION"
- exit 0
- ;;
-
- --help)
- echo "Usage: $me {--start|--stop|--restart|--status}"
- exit 0
- ;;
-
- *)
- echo "Usage: $me {--start|--stop|--restart|--status}" >&2
- exit 2
-esac
-
-exit 0
diff --git a/programs/showdefaults/.cvsignore b/programs/showdefaults/.cvsignore
deleted file mode 100644
index 609b55e81..000000000
--- a/programs/showdefaults/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-showdefaults
diff --git a/programs/showdefaults/Makefile b/programs/showdefaults/Makefile
deleted file mode 100644
index d2c8f9be8..000000000
--- a/programs/showdefaults/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=showdefaults
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/showdefaults/showdefaults.8 b/programs/showdefaults/showdefaults.8
deleted file mode 100644
index 4a8db9c49..000000000
--- a/programs/showdefaults/showdefaults.8
+++ /dev/null
@@ -1,34 +0,0 @@
-.TH IPSEC_SHOWDEFAULTS 8 "23 Jan 2000"
-.\" RCSID $Id: showdefaults.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.SH NAME
-ipsec showdefaults \- show %defaultroute defaults
-.SH SYNOPSIS
-.B ipsec
-.B showdefaults
-.SH DESCRIPTION
-.I Showdefaults
-outputs (on standard output) a terse description of the defaults
-used by the
-.B %defaultroute
-facilities in
-.IR ipsec_auto (8)
-and
-.IR ipsec_manual (8).
-.PP
-Beware that the exact output format is subject to change.
-.SH DIAGNOSTICS
-Normal exit status is 0.
-If no defaults are available,
-i.e. the
-.B interfaces
-parameter in
-.B "config setup"
-is not
-.BR %defaultroute ,
-produces a message on standard error and exits with status 1.
-.SH FILES
-/var/run/ipsec.info
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
diff --git a/programs/showdefaults/showdefaults.in b/programs/showdefaults/showdefaults.in
deleted file mode 100755
index 67daf7fd8..000000000
--- a/programs/showdefaults/showdefaults.in
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /bin/sh
-# show defaults for %defaultroute
-# Copyright (C) 2000 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: showdefaults.in,v 1.1 2004/03/15 20:35:31 as Exp $
-
-info=/var/run/ipsec.info
-me="ipsec showdefaults"
-
-case "$1" in
---help) echo "Usage: ipsec showdefaults" ; exit 0 ;;
---version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
-esac
-
-# Pick up the info.
-if test -s $info
-then
- sed -n '/^defaultroute/s/default//p' $info
- sed -n '/^#dr:/s/dr://p' $info
-else
- echo "$me: cannot find defaults file \`$info'" >&2
- exit 1
-fi
diff --git a/programs/showhostkey/.cvsignore b/programs/showhostkey/.cvsignore
deleted file mode 100644
index 8496cd633..000000000
--- a/programs/showhostkey/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-showhostkey
diff --git a/programs/showhostkey/Makefile b/programs/showhostkey/Makefile
deleted file mode 100644
index db819c906..000000000
--- a/programs/showhostkey/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=showhostkey
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/showhostkey/showhostkey.8 b/programs/showhostkey/showhostkey.8
deleted file mode 100644
index 2c0043fca..000000000
--- a/programs/showhostkey/showhostkey.8
+++ /dev/null
@@ -1,168 +0,0 @@
-.TH IPSEC_SHOWHOSTKEY 8 "5 March 2002"
-.\" RCSID $Id: showhostkey.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.SH NAME
-ipsec showhostkey \- show host's authentication key
-.SH SYNOPSIS
-.B ipsec
-.B showhostkey
-[
-.B \-\-key
-] [
-.B \-\-left
-] [
-.B \-\-right
-] [
-.B \-\-txt
-gateway
-] [
-.B \-\-dhclient
-] [
-.B \-\-file
-secretfile
-] [
-.B \-\-id
-identity
-]
-.SH DESCRIPTION
-.I Showhostkey
-outputs (on standard output) a public key suitable for this host,
-in the format specified,
-using the host key information stored in
-.IR /etc/ipsec.secrets .
-In general only the super-user can run this command,
-since only he can read
-.IR ipsec.secrets .
-.PP
-The
-.B \-\-txt
-option causes the output to be in opportunistic-encryption DNS TXT record
-format,
-with the specified
-.I gateway
-value.
-If information about how the key was generated is available,
-that is provided as a DNS-file comment.
-For example,
-.B "\-\-txt 10.11.12.13"
-might give (with the key data trimmed for clarity):
-.PP
-.nf
- ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000
- IN TXT "X-IPsec-Server(10)=10.11.12.13 AQOF8tZ2...+buFuFn/"
-.fi
-.PP
-No name is supplied in the TXT record
-because there are too many possibilities,
-depending on how it will be used.
-If the text string is longer than 255 bytes,
-it is split up into multiple strings (matching the restrictions of
-the DNS TXT binary format).
-If any split is needed, the first split will be at the start of the key:
-this increases the chances that later hand editing will work.
-.PP
-The
-.B \-\-left
-and
-.B \-\-right
-options cause the output to be in
-.IR ipsec.conf (5)
-format, as a
-.B leftrsasigkey
-or
-.B rightrsasigkey
-parameter respectively.
-Again, generation information is included if available.
-For example,
-.B \-\-left
-might give (with the key data trimmed down for clarity):
-.PP
-.nf
- # RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000
- leftrsasigkey=0sAQOF8tZ2...+buFuFn/
-.fi
-.PP
-The
-.B \-\-dhclient
-option cause the output to be suitable for inclusion in
-.IR dhclient.conf (5)
-as part of configuring WAVEsec.
-See <http://www.wavesec.org>.
-.PP
-If
-.B \-\-key
-is specified,
-the output format is the text form of a DNS KEY record;
-the host name is the one included in the key information
-(or, if that is not available,
-the output of
-.BR "hostname\ \-\-fqdn" ),
-with a
-.B \&.
-appended.
-Again, generation information is included if available.
-For example (with the key data trimmed down for clarity):
-.PP
-.nf
- ; RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000
- xy.example.com. IN KEY 0x4200 4 1 AQOF8tZ2...+buFuFn/
-.fi
-.PP
-Normally, the default key for this host
-(the one with no host identities specified for it) is the one extracted.
-The
-.B \-\-id
-option overrides this,
-causing extraction of the key labeled with the specified
-.IR identity ,
-if any.
-The specified
-.I identity
-must
-.I exactly
-match the identity in the file;
-in particular, the comparison is case-sensitive.
-.PP
-The
-.B \-\-file
-option overrides the default for where the key information should be
-found, and takes it from the specified
-.IR secretfile .
-.SH DIAGNOSTICS
-A complaint about ``no pubkey line found'' indicates that the
-host has a key but it was generated with an old version of FreeS/WAN
-and does not contain the information that
-.I showhostkey
-needs.
-.SH FILES
-/etc/ipsec.secrets
-.SH SEE ALSO
-ipsec.secrets(5), ipsec.conf(5), ipsec_rsasigkey(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org>
-by Henry Spencer.
-.SH BUGS
-Arguably,
-rather than just reporting the no-IN-KEY-line-found problem,
-.I showhostkey
-should be smart enough to run the existing key through
-.I rsasigkey
-with the
-.B \-\-oldkey
-option, to generate a suitable output line.
-.PP
-The need to specify the gateway address (etc.) for
-.B \-\-txt
-is annoying, but there is no good way to determine it automatically.
-.PP
-There should be a way to specify the priority value for TXT records;
-currently it is hardwired to
-.BR 10 .
-.PP
-The
-.B \-\-id
-option assumes that the
-.I identity
-appears on the same line as the
-.B ":\ RSA\ {"
-that begins the key proper.
diff --git a/programs/showhostkey/showhostkey.in b/programs/showhostkey/showhostkey.in
deleted file mode 100755
index 7194363e8..000000000
--- a/programs/showhostkey/showhostkey.in
+++ /dev/null
@@ -1,180 +0,0 @@
-#! /bin/sh
-# show key for this host, in DNS (or other) format
-# Copyright (C) 2000, 2001 Henry Spencer.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: showhostkey.in,v 1.1 2004/03/15 20:35:31 as Exp $
-
-me="ipsec showhostkey"
-usage="Usage: $me [--file secrets] [--left] [--right] [--txt gateway] [--id id]
- [--dhclient]"
-
-file=/etc/ipsec.secrets
-fmt=""
-gw=
-id=
-for dummy
-do
- case "$1" in
- --key) fmt="dns" ;;
- --file) file="$2" ; shift ;;
- --left) fmt="left" ;;
- --right) fmt="right" ;;
- --dhclient) fmt="dhclient" ;;
- --txt) fmt="txt" ; gw="$2" ; shift ;;
- --wavesec) fmt="wavesec" ;;
- --id) id="$2" ; shift ;;
- --version) echo "$me $IPSEC_VERSION" ; exit 0 ;;
- --help) echo "$usage" ; exit 0 ;;
- --) shift ; break ;;
- -*) echo "$me: unknown option \`$1'" >&2 ; exit 2 ;;
- *) break ;;
- esac
- shift
-done
-if test " $fmt" = " "
-then
- echo "$me: must specify a format for the result" >&2
- exit 2
-fi
-if test " $fmt" = " txt" -a " $gw" = " "
-then
- echo "$me: --txt gateway value cannot be empty" >&2
- exit 2
-fi
-
-if test ! -f $file
-then
- echo "$me: file \`$file' does not exist" >&2
- exit 1
-elif test ! -r $file
-then
- echo "$me: permission denied (cannot read \`$file')" >&2
- exit 1
-fi
-
-host="`hostname --fqdn`"
-
-awk ' BEGIN {
- inkey = 0
- seenkey = 0
- nfound = 0
- err = "cat >&2"
- me = "'"$me"'"
- host = "'"$host"'"
- file = "'"$file"'"
- fmt = "'"$fmt"'"
- gw = "'"$gw"'"
- id = "'"$id"'"
- comment = ""
- s = "[ \t]+"
- os = "[ \t]*"
- x = "[^ \t]+"
- oc = "(#.*)?"
- suffix = ":" os "[rR][sS][aA]" os "{" os oc "$"
- if (id == "") {
- pat = "^" suffix
- printid = "default"
- } else {
- pat = "^(" x s ")*" id "(" s x ")*" os suffix
- printid = quote(id)
- }
- paydirt = "^[ \t]+#pubkey=0s"
- status = 0
- }
- $0 ~ pat {
- inkey = 1
- seenkey = 1
- }
- /^[ \t]+}$/ {
- inkey = 0
- }
- inkey && $0 ~ /^[ \t]+# RSA [0-9]+ bits/ {
- comment = $0
- if (fmt == "dns" || fmt == "txt" || fmt == "dhclient")
- sub(/^[ \t]+#/, "#", comment)
- host = $5
- }
- inkey && $0 ~ /^[ \t]+#pubkey=0s/ {
-
- }
- inkey && fmt == "dns" && $0 ~ paydirt {
- out = $0
- sub(paydirt, (host ".\tIN\tKEY\t0x4200 4 1 "), out)
- nfound++
- }
- inkey && fmt == "dhclient" && $0 ~ paydirt {
- # NOT YET ADJUSTED TO KEY RR elimination
- boilerplate = "option oe-key code 159 = string;\n" \
- "option oe-gateway code 160 = ip-address;\n" \
- "send oe-key = "
- out = $0
- sub(paydirt, "0x4200 4 1 ", out)
- out = "option oe-key code 159 = string;\n" \
- "option oe-gateway code 160 = ip-address;\n" \
- "send oe-key = " quote(out) ";"
- nfound++
- }
- inkey && fmt == "txt" && $0 ~ paydirt {
- if (gw !~ /^@/ && gw !~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/ )
- {
- grump("gateway must be @FQDN or IPv4 address, not " quote(gw))
- exit(status)
- }
- out = $0
- gsub(/[ \t]+/, " ", out)
- sub(paydirt, "", out)
- out = " " out
- str = "X-IPsec-Server(10)=" gw
- if (length(str) < 255 && length(str) + length(out) > 255) {
- str = " " quote(str)
- } else {
- out = str out
- str = ""
- }
- while (length(out) > 255) {
- str = str " " quote(substr(out, 1, 255))
- out = substr(out, 256)
- }
- if (length(out) > 0)
- str = str " " quote(out)
- out = "\tIN\tTXT\t" substr(str, 2)
- nfound++
- }
- inkey && (fmt == "left" || fmt == "right") && $0 ~ /^[ \t]+#pubkey=/ {
- out = $0
- sub(/^[ \t]+#pubkey=/, ("\t" fmt "rsasigkey="), out)
- nfound++
- }
- function quote(s) {
- return "\"" s "\""
- }
- function grump(s) {
- print me ": " s |err
- status = 1
- }
- END {
- if (status != 0)
- exit(status)
- if (!seenkey)
- grump("no " printid " key in " quote(file))
- else if (nfound == 0) {
- grump("no pubkey line found -- key information old?")
- } else if (nfound > 1)
- grump("multiple " printid " keys found!?!")
- else {
- if (comment != "")
- print comment
- print out
- }
- exit(status)
- }' $file
diff --git a/programs/showpolicy/.cvsignore b/programs/showpolicy/.cvsignore
deleted file mode 100644
index e4fad4e23..000000000
--- a/programs/showpolicy/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-showpolicy
diff --git a/programs/showpolicy/Makefile b/programs/showpolicy/Makefile
deleted file mode 100644
index b3ea5a0a8..000000000
--- a/programs/showpolicy/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=showpolicy
-EXTRA5PROC=${PROGRAM}.8
-
-LIBS=${POLICYLIB} ${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.2 2003/05/14 02:12:27 mcr
-# addition of CGI-focused interface to policy lookup interface
-#
-# Revision 1.1 2003/05/11 00:45:08 mcr
-# program to interogate ipsec policy of stdin.
-# run this from inetd.
-#
-#
diff --git a/programs/showpolicy/showpolicy.8 b/programs/showpolicy/showpolicy.8
deleted file mode 100644
index 4fbc2e40e..000000000
--- a/programs/showpolicy/showpolicy.8
+++ /dev/null
@@ -1,41 +0,0 @@
-.TH IPSEC_SHOWPOLICY 8 "7 May 2003"
-.\"
-.\" RCSID $Id: showpolicy.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec showpolicy \- dump policy of socket found as stdin
-.SH SYNOPSIS
-.PP
-.B ipsec
-.B showpolicy
-.PP
-.SH DESCRIPTION
-.I showpolicy
-calls the
-.IR ipsec_policy_lookup (3)
-function on the file description which is its stdin.
-.PP
-It then dumps the resulting query in a human readable form.
-.PP
-This is a test program. One might run it from inetd, via:
-.TP
-discard stream tcp nowait nobody /usr/local/libexec/ipsec/showpolicy showpolicy
-.SH FILES
-/var/run/ipsecpolicy.ctl
-.SH "SEE ALSO"
-ipsec(8), ipsec_policy_query(3), ipsec_pluto(8)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Michael Richardson
-.SH BUGS
-.\"
-.\" $Log: showpolicy.8,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.1 2003/05/11 00:45:08 mcr
-.\" program to interogate ipsec policy of stdin.
-.\" run this from inetd.
-.\"
-.\"
diff --git a/programs/showpolicy/showpolicy.c b/programs/showpolicy/showpolicy.c
deleted file mode 100644
index 114cc3936..000000000
--- a/programs/showpolicy/showpolicy.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * A program to dump the IPsec status of the socket found on stdin.
- * Run me from inetd, for instance.
- * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char showpolicy_version[] = "RCSID $Id: showpolicy.c,v 1.1 2004/03/15 20:35:31 as Exp $";
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <getopt.h>
-#include "freeswan.h"
-#include "freeswan/ipsec_policy.h"
-
-char *program_name;
-
-static void
-help(void)
-{
- fprintf(stderr,
- "Usage:\n\n"
- "showpolicy"
- " [--cgi] lookup the particulars from CGI variables.\n"
- " [--socket] lookup the particulars from the socket on stdin.\n"
- " [--textual] dump output in human friendly form\n"
- " [--plaintext X] string to dump if no security\n"
- " [--vpntext X] string to dump if VPN configured tunnel\n"
- " [--privacytext X] string to dump if just plain DNS OE\n"
- " [--dnssectext X] string to dump if just DNSSEC OE\n"
- "\n\n"
- "FreeS/WAN %s\n",
- ipsec_version_code());
-}
-
-static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'V' },
- { "socket", no_argument, NULL, 'i' },
- { "cgi", no_argument, NULL, 'g' },
- { "textual", no_argument, NULL, 't' },
- { "plaintext", required_argument, NULL, 'c' },
- { "vpntext", required_argument, NULL, 'v' },
- { "privacytext", required_argument, NULL, 'p' },
- { "dnssectext", required_argument, NULL, 's' },
- { 0,0,0,0 }
-};
-
-void dump_policyreply(struct ipsec_policy_cmd_query *q)
-{
- char src[ADDRTOT_BUF], dst[ADDRTOT_BUF];
-
- /* now print it! */
- addrtot(&q->query_local, 0, src, sizeof(src));
- addrtot(&q->query_remote, 0, dst, sizeof(dst));
-
- printf("Results of query on %s -> %s with seq %d\n",
- src, dst, q->head.ipm_msg_seq);
-
- printf("Received reply of %d bytes.\n", q->head.ipm_msg_len);
-
- printf("Strength: %d\n", q->strength);
- printf("Bandwidth: %d\n", q->bandwidth);
- printf("authdetail: %d\n", q->auth_detail);
- printf("esp_detail: %d\n", q->esp_detail);
- printf("comp_detail: %d\n",q->comp_detail);
-
- printf("credentials: %d\n", q->credential_count);
- if(q->credential_count > 0) {
- int c;
-
- for(c=0; c<q->credential_count; c++) {
- switch(q->credentials[c].ii_format) {
- case CERT_DNS_SIGNED_KEY:
- printf("\tDNSSEC identity: %s (SIG %s)\n",
- q->credentials[c].ii_credential.ipsec_dns_signed.fqdn,
- q->credentials[c].ii_credential.ipsec_dns_signed.dns_sig);
- break;
-
- case CERT_RAW_RSA:
- printf("\tlocal identity: %s\n",
- q->credentials[c].ii_credential.ipsec_raw_key.id_name);
-
- case CERT_NONE:
- printf("\tDNS identity: %s\n",
- q->credentials[c].ii_credential.ipsec_dns_signed.fqdn);
- break;
-
- default:
- printf("\tUnknown identity type %d", q->credentials[c].ii_format);
- break;
- }
- }
- }
-}
-
-
-int main(int argc, char *argv[])
-{
- struct ipsec_policy_cmd_query q;
- err_t ret;
- int c;
-
- /* set the defaults */
- char lookup_style = 'i';
- char output_style = 's';
-
- char *plaintext = "clear";
- char *vpntext = "vpn";
- char *privacytext = "private";
- char *dnssectext = "secure";
-
- while((c = getopt_long(argc, argv, "hVighc:v:p:s:", long_opts, 0))!=EOF) {
- switch (c) {
- default:
- case 'h': /* --help */
- help();
- return 0; /* GNU coding standards say to stop here */
-
- case 'V': /* --version */
- fprintf(stderr, "FreeS/WAN %s\n", ipsec_version_code());
- return 0; /* GNU coding standards say to stop here */
-
- case 'i':
- if(isatty(0)) {
- printf("please run this connected to a socket\n");
- exit(1);
- }
-
- lookup_style = 'i';
- break;
-
- case 'g':
- lookup_style = 'g';
- break;
-
- case 't':
- output_style = 't';
- break;
-
- case 'c':
- plaintext = optarg;
- break;
-
- case 'v':
- vpntext = optarg;
- break;
-
- case 'p':
- privacytext = optarg;
- break;
-
- case 's':
- dnssectext = optarg;
- break;
- }
- }
-
- if((ret = ipsec_policy_init()) != NULL) {
- perror(ret);
- exit(2);
- }
-
- switch(lookup_style) {
- case 'i':
- if((ret = ipsec_policy_lookup(0, &q)) != NULL) {
- perror(ret);
- exit(3);
- }
- break;
-
- case 'g':
- if((ret = ipsec_policy_cgilookup(&q)) != NULL) {
- perror(ret);
- exit(3);
- }
- break;
-
- default:
- abort();
- break;
- }
-
-
- if(output_style == 't') {
- dump_policyreply(&q);
- } else {
- /* start by seeing if there was any crypto */
- if(q.strength < IPSEC_PRIVACY_PRIVATE) {
- /* no, so say clear */
- puts(plaintext);
- exit(0);
- }
-
- /* we now it is crypto, but authentic is it? */
- if(q.credential_count == 0) {
- puts(vpntext);
- exit(0);
- }
-
- switch(q.credentials[0].ii_format) {
- case CERT_DNS_SIGNED_KEY:
- puts(dnssectext);
- exit(0);
-
- case CERT_RAW_RSA:
- puts(vpntext);
- exit(0);
-
- default:
- puts(privacytext);
- exit(0);
- }
- }
-
- exit(0);
-}
-
-/*
- * $Log: showpolicy.c,v $
- * Revision 1.1 2004/03/15 20:35:31 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.4 2003/05/14 15:46:44 mcr
- * switch statement was missing break statements and was running on.
- *
- * Revision 1.3 2003/05/14 02:12:27 mcr
- * addition of CGI-focused interface to policy lookup interface
- *
- * Revision 1.2 2003/05/13 03:25:34 mcr
- * print credentials, if any were provided.
- *
- * Revision 1.1 2003/05/11 00:45:08 mcr
- * program to interogate ipsec policy of stdin.
- * run this from inetd.
- *
- *
- *
- */
diff --git a/programs/spi/.cvsignore b/programs/spi/.cvsignore
deleted file mode 100644
index c928c4b77..000000000
--- a/programs/spi/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-spi
diff --git a/programs/spi/Makefile b/programs/spi/Makefile
deleted file mode 100644
index 10a1eaa9c..000000000
--- a/programs/spi/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.2 2004/03/22 21:53:21 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=spi
-EXTRA5PROC=${PROGRAM}.5
-
-LIBS=${FREESWANLIB}
-
-OBJS=constants.o alg_info.o kernel_alg.o
-
-include ../Makefile.program
-
-constants.o : ../pluto/constants.c ../pluto/constants.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-alg_info.o : ../pluto/alg_info.c ../pluto/alg_info.h
- $(CC) $(CFLAGS) -DNO_PLUTO -c -o $@ $<
-
-kernel_alg.o : ../pluto/kernel_alg.c ../pluto/kernel_alg.h
- $(CC) $(CFLAGS) -DNO_PLUTO -c -o $@ $<
-
-#
-# $Log: Makefile,v $
-# Revision 1.2 2004/03/22 21:53:21 as
-# merged alg-0.8.1 branch with HEAD
-#
-# Revision 1.1.4.1 2004/03/16 09:48:22 as
-# alg-0.8.1rc12 patch merged
-#
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/spi/spi.5 b/programs/spi/spi.5
deleted file mode 100644
index a8faebee4..000000000
--- a/programs/spi/spi.5
+++ /dev/null
@@ -1,213 +0,0 @@
-.TH IPSEC_SPI 5 "26 Jun 2000"
-.\"
-.\" RCSID $Id: spi.5,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec_spi \- list IPSEC Security Associations
-.SH SYNOPSIS
-.B ipsec
-.B spi
-.PP
-.B cat
-.B /proc/net/ipsec_spi
-.PP
-.SH DESCRIPTION
-.I /proc/net/ipsec_spi
-is a read-only file that lists the current IPSEC Security Associations.
-A Security Association (SA) is a transform through which packet contents
-are to be processed before being forwarded. A transform can be an
-IPv4-in-IPv4 or IPv6-in-IPv6 encapsulation, an IPSEC Authentication Header (authentication
-with no encryption), or an IPSEC Encapsulation Security Payload
-(encryption, possibly including authentication).
-.PP
-When a packet is passed from a higher networking layer through an IPSEC
-virtual interface, a search in the extended routing table (see
-.IR ipsec_eroute (5))
-yields
-a IP protocol number
-,
-a Security Parameters Index (SPI)
-and
-an effective destination address
-.
-When an IPSEC packet arrives from the network,
-its ostensible destination, an SPI and an IP protocol
-specified by its outermost IPSEC header are used.
-The destination/SPI/protocol combination is used to select a relevant SA.
-(See
-.IR ipsec_spigrp (5)
-for discussion of how multiple transforms are combined.)
-.PP
-An
-.I spi ,
-.I proto,
-.I daddr
-and
-.IR address_family
-arguments specify an SAID.
-.I Proto
-is an ASCII string, "ah", "esp", "comp" or "tun", specifying the IP protocol.
-.I Spi
-is a number, preceded by '.' indicating hexadecimal and IPv4 or by ':' indicating hexadecimal and IPv6,
-where each hexadecimal digit represents 4 bits,
-between
-.B 0x100
-and
-.BR 0xffffffff ;
-values from
-.B 0x0
-to
-.B 0xff
-are reserved.
-.I Daddr
-is a dotted-decimal IPv4 destination address or a coloned hex IPv6 destination address.
-.PP
-An
-.I SAID
-combines the three parameters above, such as: "tun.101@1.2.3.4" for IPv4 or "tun:101@3049:1::1" for IPv6
-.PP
-A table entry consists of:
-.IP + 3
-.BR SAID
-.IP +
-<transform name (proto,encalg,authalg)>:
-.IP +
-direction (dir=)
-.IP +
-source address (src=)
-.IP +
-source and destination addresses and masks for inner header policy check
-addresses (policy=), as dotted-quads or coloned hex, separated by '->',
-for IPv4-in-IPv4 or IPv6-in-IPv6 SAs only
-.IP +
-initialisation vector length and value (iv_bits=, iv=) if non-zero
-.IP +
-out-of-order window size, number of out-of-order errors, sequence
-number, recently received packet bitmask, maximum difference between
-sequence numbers (ooowin=, ooo_errs=, seq=, bit=, max_seq_diff=) if SA
-is AH or ESP and if individual items are non-zero
-.IP +
-extra flags (flags=) if any are set
-.IP +
-authenticator length in bits (alen=) if non-zero
-.IP +
-authentication key length in bits (aklen=) if non-zero
-.IP +
-authentication errors (auth_errs=) if non-zero
-.IP +
-encryption key length in bits (eklen=) if non-zero
-.IP +
-encryption size errors (encr_size_errs=) if non-zero
-.IP +
-encryption padding error warnings (encr_pad_errs=) if non-zero
-.IP +
-lifetimes legend, c=Current status, s=Soft limit when exceeded will
-initiate rekeying, h=Hard limit will cause termination of SA (life(c,s,h)=)
-.IP + 6
-number of connections to which the SA is allocated (c), that will cause a
-rekey (s), that will cause an expiry (h) (alloc=), if any value is non-zero
-.IP +
-number of bytes processesd by this SA (c), that will cause a rekey (s), that
-will cause an expiry (h) (bytes=), if any value is non-zero
-.IP +
-time since the SA was added (c), until rekey (s), until expiry (h), in seconds (add=)
-.IP +
-time since the SA was first used (c), until rekey (s), until expiry (h), in seconds (used=),
-if any value is non-zero
-.IP +
-number of packets processesd by this SA (c), that will cause a rekey (s), that
-will cause an expiry (h) (packets=), if any value is non-zero
-.IP + 3
-time since the last packet was processed, in seconds (idle=), if SA has
-been used
-.IP
-average compression ratio (ratio=)
-.SH EXAMPLES
-.B "tun.12a@192.168.43.1 IPIP: dir=out src=192.168.43.2"
-.br
-.B " life(c,s,h)=bytes(14073,0,0)add(269,0,0)"
-.br
-.B " use(149,0,0)packets(14,0,0)"
-.br
-.B " idle=23
-.LP
-is an outbound IPv4-in-IPv4 (protocol 4) tunnel-mode SA set up between machines
-192.168.43.2 and 192.168.43.1 with an SPI of 12a in hexadecimal that has
-passed about 14 kilobytes of traffic in 14 packets since it was created,
-269 seconds ago, first used 149 seconds ago and has been idle for 23
-seconds.
-.LP
-.B "esp:9a35fc02@3049:1::1 ESP_3DES_HMAC_MD5:"
-.br
-.B " dir=in src=9a35fc02@3049:1::2"
-.br
-.B " ooowin=32 seq=7149 bit=0xffffffff"
-.br
-.B " alen=128 aklen=128 eklen=192"
-.br
-.B " life(c,s,h)=bytes(1222304,0,0)add(4593,0,0)"
-.br
-.B " use(3858,0,0)packets(7149,0,0)"
-.br
-.B " idle=23"
-.LP
-is an inbound Encapsulating Security Payload (protocol 50) SA on machine
-3049:1::1 with an SPI of 9a35fc02 that uses 3DES as the encryption
-cipher, HMAC MD5 as the authentication algorithm, an out-of-order
-window of 32 packets, a present sequence number of 7149, every one of
-the last 32 sequence numbers was received, the authenticator length and
-keys is 128 bits, the encryption key is 192 bits (actually 168 for 3DES
-since 1 of 8 bits is a parity bit), has passed 1.2 Mbytes of data in
-7149 packets, was added 4593 seconds ago, first used
-3858 seconds ago and has been idle for 23 seconds.
-.LP
-.SH FILES
-/proc/net/ipsec_spi, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(5), ipsec_eroute(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_spi(8), ipsec_version(5),
-ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.SH BUGS
-The add and use times are awkward, displayed in seconds since machine
-start. It would be better to display them in seconds before now for
-human readability.
-.\"
-.\" $Log: spi.5,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.9 2002/04/24 07:35:39 mcr
-.\" Moved from ./klips/utils/spi.5,v
-.\"
-.\" Revision 1.8 2001/08/01 23:22:44 rgb
-.\" Fix inconsistancies between manpage and output.
-.\"
-.\" Revision 1.7 2000/11/30 16:47:28 rgb
-.\" Added src= to /proc/net/ipsec_spi manpage.
-.\"
-.\" Revision 1.6 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.5 2000/09/13 15:54:32 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.4 2000/07/05 17:24:03 rgb
-.\" Updated for relative, rather than absolute values for addtime and
-.\" usetime.
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/28 12:44:12 henry
-.\" format touchup
-.\"
-.\" Revision 1.1 2000/06/28 05:43:00 rgb
-.\" Added manpages for all 5 klips utils.
-.\"
-.\"
diff --git a/programs/spi/spi.8 b/programs/spi/spi.8
deleted file mode 100644
index fe6537c07..000000000
--- a/programs/spi/spi.8
+++ /dev/null
@@ -1,525 +0,0 @@
-.TH IPSEC_SPI 8 "23 Oct 2001"
-.\"
-.\" RCSID $Id: spi.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec spi \- manage IPSEC Security Associations
-.SH SYNOPSIS
-.br
-Note: In the following,
-.br
-.B <SA>
-means:
-.B \-\-af
-(inet | inet6)
-.B \-\-edst
-daddr
-.B \-\-spi
-spi
-.B \-\-proto
-proto OR
-.B \-\-said
-said,
-.br
-.B <life>
-means:
-.B \-\-life
-(soft | hard)\-(allocations | bytes | addtime | usetime | packets)=value[,...]
-.PP
-.B ipsec
-.B spi
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-src
-src
-.B \-\-ah
-.BR hmac-md5-96 | hmac-sha1-96
-[
-.B \-\-replay_window
-replayw ]
-[
-.B <life>
-]
-.B \-\-authkey
-akey
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-src
-src
-.B \-\-esp
-.BR 3des
-[
-.B \-\-replay_window
-replayw ]
-[
-.B <life>
-]
-.B \-\-enckey
-ekey
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-src
-src
-.B \-\-esp
-.BR 3des-md5-96 | 3des-sha1-96
-[
-.B \-\-replay_window
-replayw ]
-[
-.B <life>
-]
-.B \-\-enckey
-ekey
-.B \-\-authkey
-akey
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-src
-src
-.B \-\-comp
-.BR deflate
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-ip4
-.B \-\-src
-encap-src
-.B \-\-dst
-encap-dst
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-ip6
-.B \-\-src
-encap-src
-.B \-\-dst
-encap-dst
-.PP
-.B ipsec
-.B spi
-.B <SA>
-.B \-\-del
-.PP
-.B ipsec
-.B spi
-.B \-\-help
-.PP
-.B ipsec
-.B spi
-.B \-\-version
-.PP
-.B ipsec
-.B spi
-.B \-\-clear
-.PP
-.SH DESCRIPTION
-.I Spi
-creates and deletes IPSEC Security Associations.
-A Security Association (SA) is a transform through which packet
-contents are to be processed before being forwarded.
-A transform can be an IPv4-in-IPv4 or an IPv6-in-IPv6 encapsulation,
-an IPSEC Authentication Header (authentication with no encryption),
-or an IPSEC Encapsulation Security Payload (encryption, possibly
-including authentication).
-.PP
-When a packet is passed from a higher networking layer
-through an IPSEC virtual interface,
-a search in the extended routing table (see
-.IR ipsec_eroute (8))
-yields an effective destination address, a
-Security Parameters Index (SPI) and a IP protocol number.
-When an IPSEC packet arrives from the network,
-its ostensible destination, an SPI and an IP protocol
-specified by its outermost IPSEC header are used.
-The destination/SPI/protocol combination is used to select a relevant SA.
-(See
-.IR ipsec_spigrp (8)
-for discussion of how multiple transforms are combined.)
-.PP
-The
-.IR af ,
-.IR daddr ,
-.I spi
-and
-.I proto
-arguments specify the SA to be created or deleted.
-.I af
-is the address family (inet for IPv4, inet6 for IPv6).
-.I Daddr
-is a destination address
-in dotted-decimal notation for IPv4
-or in a coloned hex notation for IPv6.
-.I Spi
-is a number, preceded by '0x' for hexadecimal,
-between
-.B 0x100
-and
-.BR 0xffffffff ;
-values from
-.B 0x0
-to
-.B 0xff
-are reserved.
-.I Proto
-is an ASCII string, "ah", "esp", "comp" or "tun", specifying the IP protocol.
-The protocol must agree with the algorithm selected.
-.PP
-Alternatively, the
-.I said
-argument can also specify an SA to be created or deleted.
-.I Said
-combines the three parameters above, such as: "tun.101@1.2.3.4" or "tun:101@1:2::3:4",
-where the address family is specified by "." for IPv4 and ":" for IPv6. The address
-family indicators substitute the "0x" for hexadecimal.
-.PP
-The source address,
-.IR src ,
-must also be provided for the inbound policy check to
-function. The source address does not need to be included if inbound
-policy checking has been disabled.
-.PP
-Keys vectors must be entered as hexadecimal or base64 numbers.
-They should be cryptographically strong random numbers.
-.PP
-All hexadecimal numbers are entered as strings of hexadecimal digits
-(0-9 and a-f), without spaces, preceded by '0x', where each hexadecimal
-digit represents 4 bits.
-All base64 numbers are entered as strings of base64 digits
- (0-9, A-Z, a-z, '+' and '/'), without spaces, preceded by '0s',
-where each hexadecimal digit represents 6 bits and '=' is used for padding.
-.PP
-The deletion of an SA which has been grouped will result in the entire chain
-being deleted.
-.PP
-The form with no additional arguments lists the contents of
-/proc/net/ipsec_spi. The format of /proc/net/ipsec_spi is discussed in
-ipsec_spi(5).
-.PP
-The lifetime severity of
-.B soft
-sets a limit when the key management daemons are asked to rekey the SA.
-The lifetime severity of
-.B hard
-sets a limit when the SA must expire.
-The lifetime type
-.B allocations
-tells the system when to expire the SA because it is being shared by too many
-eroutes (not currently used). The lifetime type of
-.B bytes
-tells the system to expire the SA after a certain number of bytes have been
-processed with that SA. The lifetime type of
-.B addtime
-tells the system to expire the SA a certain number of seconds after the SA was
-installed. The lifetime type of
-.B usetime
-tells the system to expire the SA a certain number of seconds after that SA has
-processed its first packet. The lifetime type of
-.B packets
-tells the system to expire the SA after a certain number of packets have been
-processed with that SA.
-.SH OPTIONS
-.TP 10
-.B \-\-af
-specifies the address family (inet for IPv4, inet6 for IPv6)
-.TP
-.B \-\-edst
-specifies the effective destination
-.I daddr
-of the Security Association
-.TP
-.B \-\-spi
-specifies the Security Parameters Index
-.I spi
-of the Security Association
-.TP
-.B \-\-proto
-specifies the IP protocol
-.I proto
-of the Security Association
-.TP
-.B \-\-said
-specifies the Security Association in monolithic format
-.TP
-.B \-\-ah
-add an SA for an IPSEC Authentication Header,
-specified by the following transform identifier
-(\c
-.BR hmac-md5-96
-or
-.BR hmac-sha1-96 )
-(RFC2402, obsoletes RFC1826)
-.TP
-.B hmac-md5-96
-transform following the HMAC and MD5 standards,
-using a 128-bit
-.I key
-to produce a 96-bit authenticator (RFC2403)
-.TP
-.B hmac-sha1-96
-transform following the HMAC and SHA1 standards,
-using a 160-bit
-.I key
-to produce a 96-bit authenticator (RFC2404)
-.TP
-.B \-\-esp
-add an SA for an IPSEC Encapsulation Security Payload,
-specified by the following
-transform identifier (\c
-.BR 3des ,
-or
-.BR 3des-md5-96 )
-(RFC2406, obsoletes RFC1827)
-.TP
-.B 3des
-encryption transform following the Triple-DES standard in
-Cipher-Block-Chaining mode using a 64-bit
-.I iv
-(internally generated) and a 192-bit 3DES
-.I ekey
-(RFC2451)
-.TP
-.B 3des-md5-96
-encryption transform following the Triple-DES standard in
-Cipher-Block-Chaining mode with authentication provided by
-HMAC and MD5
-(96-bit authenticator),
-using a 64-bit
-.IR iv
-(internally generated), a 192-bit 3DES
-.I ekey
-and a 128-bit HMAC-MD5
-.I akey
-(RFC2451, RFC2403)
-.TP
-.B 3des-sha1-96
-encryption transform following the Triple-DES standard in
-Cipher-Block-Chaining mode with authentication provided by
-HMAC and SHA1
-(96-bit authenticator),
-using a 64-bit
-.IR iv
-(internally generated), a 192-bit 3DES
-.I ekey
-and a 160-bit HMAC-SHA1
-.I akey
-(RFC2451, RFC2404)
-.TP
-.BR \-\-replay_window " replayw"
-sets the replay window size; valid values are decimal, 1 to 64
-.TP
-.BR \-\-life " life_param[,life_param]"
-sets the lifetime expiry; the format of
-.B life_param
-consists of a comma-separated list of lifetime specifications without spaces;
-a lifetime specification is comprised of a severity of
-.BR soft " or " hard
-followed by a '-', followed by a lifetime type of
-.BR allocations ", " bytes ", " addtime ", " usetime " or " packets
-followed by an '=' and finally by a value
-.TP
-.B \-\-comp
-add an SA for IPSEC IP Compression,
-specified by the following
-transform identifier (\c
-.BR deflate )
-(RFC2393)
-.TP
-.B deflate
-compression transform following the patent-free Deflate compression algorithm
-(RFC2394)
-.TP
-.B \-\-ip4
-add an SA for an IPv4-in-IPv4
-tunnel from
-.I encap-src
-to
-.I encap-dst
-.TP
-.B \-\-ip6
-add an SA for an IPv6-in-IPv6
-tunnel from
-.I encap-src
-to
-.I encap-dst
-.TP
-.B \-\-src
-specify the source end of an IP-in-IP tunnel from
-.I encap-src
-to
-.I encap-dst
-and also specifies the source address of the Security Association to be
-used in inbound policy checking and must be the same address
-family as
-.I af
-and
-.I edst
-.TP
-.B \-\-dst
-specify the destination end of an IP-in-IP tunnel from
-.I encap-src
-to
-.I encap-dst
-.TP
-.B \-\-del
-delete the specified SA
-.TP
-.BR \-\-clear
-clears the table of
-.BR SA s
-.TP
-.BR \-\-help
-display synopsis
-.TP
-.BR \-\-version
-display version information
-.SH EXAMPLES
-To keep line lengths down and reduce clutter,
-some of the long keys in these examples have been abbreviated
-by replacing part of their text with
-.RI `` ... ''.
-Keys used when the programs are actually run must,
-of course, be the full length required for the particular algorithm.
-.LP
-.B "ipsec spi \-\-af inet \-\-edst gw2 \-\-spi 0x125 \-\-proto esp \e"
-.br
-.B " \-\-src gw1 \e"
-.br
-.B " \-\-esp 3des\-md5\-96 \e"
-.br
-.BI "\ \ \ \-\-enckey\ 0x6630" "..." "97ce\ \e"
-.br
-.BI " \-\-authkey 0x9941" "..." "71df"
-.LP
-sets up an SA from
-.BR gw1
-to
-.BR gw2
-with an SPI of
-.BR 0x125
-and protocol
-.BR ESP
-(50) using
-.BR 3DES
-encryption with integral
-.BR MD5-96
-authentication transform, using an encryption key of
-.BI 0x6630 ... 97ce
-and an authentication key of
-.BI 0x9941 ... 71df
-(see note above about abbreviated keys).
-.LP
-.B "ipsec spi \-\-af inet6 \-\-edst 3049:9::9000:3100 \-\-spi 0x150 \-\-proto ah \e"
-.br
-.B " \-\-src 3049:9::9000:3101 \e"
-.br
-.B " \-\-ah hmac\-md5\-96 \e"
-.br
-.BI "\ \ \ \-\-authkey\ 0x1234" "..." "2eda\ \e"
-.LP
-sets up an SA from
-.BR 3049:9::9000:3101
-to
-.BR 3049:9::9000:3100
-with an SPI of
-.BR 0x150
-and protocol
-.BR AH
-(50) using
-.BR MD5-96
-authentication transform, using an authentication key of
-.BI 0x1234 ... 2eda
-(see note above about abbreviated keys).
-.LP
-.B "ipsec spi \-\-said tun.987@192.168.100.100 \-\-del "
-.LP
-deletes an SA to
-.BR 192.168.100.100
-with an SPI of
-.BR 0x987
-and protocol
-.BR IPv4-in-IPv4
-(4).
-.LP
-.B "ipsec spi \-\-said tun:500@3049:9::1000:1 \-\-del "
-.LP
-deletes an SA to
-.BR 3049:9::1000:1
-with an SPI of
-.BR 0x500
-and protocol
-.BR IPv6-in-IPv6
-(4).
-.LP
-.SH FILES
-/proc/net/ipsec_spi, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_eroute(8),
-ipsec_spigrp(8), ipsec_klipsdebug(8), ipsec_spi(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.SH BUGS
-The syntax is messy and the transform naming needs work.
-.\"
-.\" $Log: spi.8,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.32 2002/04/24 07:35:40 mcr
-.\" Moved from ./klips/utils/spi.8,v
-.\"
-.\" Revision 1.31 2001/11/06 20:18:47 rgb
-.\" Added lifetime parameters.
-.\"
-.\" Revision 1.30 2001/10/24 03:23:32 rgb
-.\" Added lifetime option and parameters.
-.\"
-.\" Revision 1.29 2001/05/30 08:14:04 rgb
-.\" Removed vestiges of esp-null transforms.
-.\"
-.\" Revision 1.28 2000/11/29 19:15:20 rgb
-.\" Add --src requirement for inbound policy routing.
-.\"
-.\" Revision 1.27 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.26 2000/09/13 15:54:32 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.25 2000/09/12 22:36:45 rgb
-.\" Gerhard's IPv6 support.
-.\"
-.\" Revision 1.24 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.23 2000/06/21 16:54:57 rgb
-.\" Added 'no additional args' text for listing contents of
-.\" /proc/net/ipsec_* files.
-.\"
-.\" Revision 1.22 1999/08/11 08:35:16 rgb
-.\" Update, deleting references to obsolete and insecure algorithms.
-.\"
-.\" Revision 1.21 1999/07/19 18:53:55 henry
-.\" improve font usage in key abbreviations
-.\"
-.\" Revision 1.20 1999/07/19 18:50:09 henry
-.\" fix slightly-misformed comments
-.\" abbreviate long keys to avoid long-line complaints
-.\"
-.\" Revision 1.19 1999/04/06 04:54:38 rgb
-.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-.\" patch shell fixes.
-.\"
diff --git a/programs/spi/spi.c b/programs/spi/spi.c
deleted file mode 100644
index 369d556c7..000000000
--- a/programs/spi/spi.c
+++ /dev/null
@@ -1,1689 +0,0 @@
-/*
- * All-in-one program to set Security Association parameters
- * Copyright (C) 1996 John Ioannidis.
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char spi_c_version[] = "RCSID $Id: spi.c,v 1.7 2004/10/14 20:03:26 as Exp $";
-
-#include <asm/types.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-/* #include <linux/netdevice.h> */
-#include <net/if.h>
-/* #include <linux/types.h> */ /* new */
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-/* #include <sys/socket.h> */
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-/* #include <linux/ip.h> */
-#include <netdb.h>
-
-#include <unistd.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <freeswan.h>
-#if 0
-#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */
-#endif
- #include <signal.h>
- #include <sys/socket.h>
- #include <pfkeyv2.h>
- #include <pfkey.h>
-
-#include "freeswan/radij.h"
-#include "freeswan/ipsec_encap.h"
-#include "freeswan/ipsec_xform.h"
-#include "freeswan/ipsec_ipe4.h"
-#include "freeswan/ipsec_ah.h"
-#include "freeswan/ipsec_esp.h"
-#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL */
-
-/*
- * Manual conn support for ipsec_alg (modular algos).
- * Rather ugly to include from pluto dir but avoids
- * code duplication.
- */
-#ifndef NO_KERNEL_ALG
-#include "../pluto/alg_info.h"
-#include "../pluto/constants.h"
-struct connection;
-#include "../pluto/kernel_alg.h"
-#endif /* NO_KERNEL_ALG */
-
-char *program_name;
-int debug = 0;
-int saref = 0;
-char *command;
-extern char *optarg;
-extern int optind, opterr, optopt;
-char scratch[2];
-char *iv = NULL, *enckey = NULL, *authkey = NULL;
-size_t ivlen = 0, enckeylen = 0, authkeylen = 0;
-ip_address edst, dst, src;
-int address_family = 0;
-unsigned char proto = 0;
-int alg = 0;
-
-#ifndef NO_KERNEL_ALG
-/*
- * Manual connection support for modular algos (ipsec_alg) --Juanjo.
- */
-#define XF_OTHER_ALG (XF_CLR-1) /* define magic XF_ symbol for alg_info's */
-#include <assert.h>
-const char *alg_string = NULL; /* algorithm string */
-struct alg_info_esp *alg_info = NULL; /* algorithm info got from string */
-struct esp_info *esp_info = NULL; /* esp info from 1st (only) element */
-const char *alg_err; /* auxiliar for parsing errors */
-int proc_read_ok = 0; /* /proc/net/pf_key_support read ok */
-#endif /* NO_KERNEL_ALG */
-
-int replay_window = 0;
-char sa[SATOT_BUF];
-
-extern unsigned int pfkey_lib_debug; /* used by libfreeswan/pfkey_v2_build */
-int pfkey_sock;
-fd_set pfkey_socks;
-uint32_t pfkey_seq = 0;
-enum life_severity {
- life_soft = 0,
- life_hard = 1,
- life_maxsever = 2
-};
-enum life_type {
- life_alloc = 0,
- life_bytes = 1,
- life_addtime = 2,
- life_usetime = 3,
- life_packets = 4,
- life_maxtype = 5
-};
-
-#define streql(_a,_b) (!strcmp((_a),(_b)))
-
-static const char *usage_string = "\
-Usage:\n\
- in the following, <SA> is: --af <inet | inet6> --edst <dstaddr> --spi <spi> --proto <proto>\n\
- OR: --said <proto><.|:><spi>@<dstaddr>\n\
- <life> is: --life <soft|hard>-<allocations|bytes|addtime|usetime|packets>=<value>[,...]\n\
-spi --clear\n\
-spi --help\n\
-spi --version\n\
-spi\n\
-spi --del <SA>\n\
-spi --ip4 <SA> --src <encap-src> --dst <encap-dst>\n\
-spi --ip6 <SA> --src <encap-src> --dst <encap-dst>\n\
-spi --ah <algo> <SA> [<life> ][ --replay_window <replay_window> ] --authkey <key>\n\
- where <algo> is one of: hmac-md5-96 | hmac-sha1-96\n\
-spi --esp <algo> <SA> [<life> ][ --replay_window <replay-window> ] --enckey <ekey> --authkey <akey>\n\
- where <algo> is one of: 3des-md5-96 | 3des-sha1-96\n\
-spi --esp <algo> <SA> [<life> ][ --replay_window <replay-window> ] --enckey <ekey>\n\
- where <algo> is: 3des\n\
-spi --comp <algo> <SA>\n\
- where <algo> is: deflate\n\
-[ --debug ] is optional to any spi command.\n\
-[ --label <label> ] is optional to any spi command.\n\
-[ --listenreply ] is optional, and causes the command to stick\n\
- around and listen to what the PF_KEY socket says.\n\
-";
-
-
-static void
-usage(char *s, FILE *f)
-{
- /* s argument is actually ignored, at present */
- fprintf(f, "%s:%s", s, usage_string);
- exit(-1);
-}
-
-int
-parse_life_options(uint32_t life[life_maxsever][life_maxtype],
- char *life_opt[life_maxsever][life_maxtype],
- char *optarg)
-{
- char *optargp = optarg;
- char *endptr;
-
- do {
- int life_severity, life_type;
- char *optargt = optargp;
-
- if(strncmp(optargp, "soft", sizeof("soft")-1) == 0) {
- life_severity = life_soft;
- optargp += sizeof("soft")-1;
- } else if(strncmp(optargp, "hard", sizeof("hard")-1) == 0) {
- life_severity = life_hard;
- optargp += sizeof("hard")-1;
- } else {
- fprintf(stderr,
- "%s: missing lifetime severity in %s, optargt=0p%p, optargp=0p%p, sizeof(\"soft\")=%d\n",
- program_name,
- optargt,
- optargt,
- optargp,
- (int)sizeof("soft"));
- usage(program_name, stderr);
- return(1);
- }
- if(debug) {
- fprintf(stdout,
- "%s: debug: life_severity=%d, optargt=0p%p=\"%s\", optargp=0p%p=\"%s\", sizeof(\"soft\")=%d\n",
- program_name,
- life_severity,
- optargt,
- optargt,
- optargp,
- optargp,
- (int)sizeof("soft"));
- }
- if(*(optargp++) != '-') {
- fprintf(stderr,
- "%s: expected '-' after severity of lifetime parameter to --life option.\n",
- program_name);
- usage(program_name, stderr);
- return(1);
- }
- if(debug) {
- fprintf(stdout,
- "%s: debug: optargt=0p%p=\"%s\", optargp=0p%p=\"%s\", strlen(optargt)=%d, strlen(optargp)=%d, strncmp(optargp, \"addtime\", sizeof(\"addtime\")-1)=%d\n",
- program_name,
- optargt,
- optargt,
- optargp,
- optargp,
- (int)strlen(optargt),
- (int)strlen(optargp),
- strncmp(optargp, "addtime", sizeof("addtime")-1));
- }
- if(strncmp(optargp, "allocations", sizeof("allocations")-1) == 0) {
- life_type = life_alloc;
- optargp += sizeof("allocations")-1;
- } else if(strncmp(optargp, "bytes", sizeof("bytes")-1) == 0) {
- life_type = life_bytes;
- optargp += sizeof("bytes")-1;
- } else if(strncmp(optargp, "addtime", sizeof("addtime")-1) == 0) {
- life_type = life_addtime;
- optargp += sizeof("addtime")-1;
- } else if(strncmp(optargp, "usetime", sizeof("usetime")-1) == 0) {
- life_type = life_usetime;
- optargp += sizeof("usetime")-1;
- } else if(strncmp(optargp, "packets", sizeof("packets")-1) == 0) {
- life_type = life_packets;
- optargp += sizeof("packets")-1;
- } else {
- fprintf(stderr,
- "%s: missing lifetime type after '-' in %s\n",
- program_name,
- optargt);
- usage(program_name, stderr);
- return(1);
- }
- if(debug) {
- fprintf(stdout,
- "%s: debug: life_type=%d\n",
- program_name,
- life_type);
- }
- if(life_opt[life_severity][life_type] != NULL) {
- fprintf(stderr,
- "%s: Error, lifetime parameter redefined:%s, already defined as:0p%p\n",
- program_name,
- optargt,
- life_opt[life_severity][life_type]);
- return(1);
- }
- if(*(optargp++) != '=') {
- fprintf(stderr,
- "%s: expected '=' after type of lifetime parameter to --life option.\n",
- program_name);
- usage(program_name, stderr);
- return(1);
- }
- if(debug) {
- fprintf(stdout,
- "%s: debug: optargt=0p%p, optargt+strlen(optargt)=0p%p, optargp=0p%p, strlen(optargp)=%d\n",
- program_name,
- optargt,
- optargt+strlen(optargt),
- optargp,
- (int)strlen(optargp));
- }
- if(strlen(optargp) == 0) {
- fprintf(stderr,
- "%s: expected value after '=' in --life option. optargt=0p%p, optargt+strlen(optargt)=0p%p, optargp=0p%p\n",
- program_name,
- optargt,
- optargt+strlen(optargt),
- optargp);
- usage(program_name, stderr);
- return(1);
- }
- life[life_severity][life_type] = strtoul(optargp, &endptr, 0);
-
- if(!((endptr == optargp + strlen(optargp)) || (endptr == optargp + strcspn(optargp, ", ")))) {
- fprintf(stderr,
- "%s: Invalid character='%c' at offset %d in lifetime option parameter: '%s', parameter string is %d characters long, %d valid value characters found.\n",
- program_name,
- *endptr,
- (int)(endptr - optarg),
- optarg,
- (int)strlen(optarg),
- (int)(strcspn(optargp, ", ") - 1));
- return(1);
- }
- life_opt[life_severity][life_type] = optargt;
- if(debug) {
- fprintf(stdout, "%s lifetime %s set to %d.\n",
- program_name, optargt, life[life_severity][life_type]);
- }
- optargp=endptr+1;
- } while(*endptr==',' || isspace(*endptr));
-
- return(0);
-}
-
-int
-pfkey_register(uint8_t satype) {
- /* for registering SA types that can be negotiated */
- int error;
- ssize_t wlen;
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
-
- pfkey_extensions_init(extensions);
- error = pfkey_msg_hdr_build(&extensions[0],
- SADB_REGISTER,
- satype,
- 0,
- ++pfkey_seq,
- getpid());
- if(error != 0) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- return(1);
- }
-
- error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
- if(error != 0) {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- return(1);
- }
- wlen = write(pfkey_sock, pfkey_msg,
- pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
- if(wlen != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
- /* cleanup code here */
- if(wlen < 0)
- fprintf(stderr, "%s: Trouble writing to channel PF_KEY: %s\n",
- program_name,
- strerror(errno));
- else
- fprintf(stderr, "%s: write to channel PF_KEY truncated.\n",
- program_name);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- return(1);
- }
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
-
- return(0);
-}
-
-static struct option const longopts[] =
-{
- {"ah", 1, 0, 'H'},
- {"esp", 1, 0, 'P'},
- {"comp", 1, 0, 'Z'},
- {"ip4", 0, 0, '4'},
- {"ip6", 0, 0, '6'},
- {"del", 0, 0, 'd'},
-
- {"authkey", 1, 0, 'A'},
- {"enckey", 1, 0, 'E'},
- {"edst", 1, 0, 'e'},
- {"spi", 1, 0, 's'},
- {"proto", 1, 0, 'p'},
- {"af", 1, 0, 'a'},
- {"replay_window", 1, 0, 'w'},
- {"iv", 1, 0, 'i'},
- {"dst", 1, 0, 'D'},
- {"src", 1, 0, 'S'},
- {"said", 1, 0, 'I'},
-
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"clear", 0, 0, 'c'},
- {"label", 1, 0, 'l'},
- {"debug", 0, 0, 'g'},
- {"optionsfrom", 1, 0, '+'},
- {"life", 1, 0, 'f'},
- {"saref", 0, 0, 'r'},
- {"listenreply", 0, 0, 'R'},
- {0, 0, 0, 0}
-};
-
-int
-main(int argc, char *argv[])
-{
- char *endptr;
- __u32 spi = 0;
- int c, previous = -1;
-/* int ret; */
- ip_said said;
- size_t sa_len;
- const char* error_s;
- char ipaddr_txt[ADDRTOT_BUF];
- char ipsaid_txt[SATOT_BUF];
-
- int error = 0;
- ssize_t io_error;
- int argcount = argc;
- pid_t mypid;
- int listenreply = 0;
-
- unsigned char authalg, encryptalg;
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
- char *iv_opt, *akey_opt, *ekey_opt, *alg_opt, *edst_opt, *spi_opt, *proto_opt, *af_opt, *said_opt, *dst_opt, *src_opt;
-#if 0
- ip_address pfkey_address_p_ska;
- ip_address pfkey_ident_s_ska;
- ip_address pfkey_ident_d_ska;
-#endif
- uint32_t life[life_maxsever][life_maxtype];
- char *life_opt[life_maxsever][life_maxtype];
-
- program_name = argv[0];
- mypid = getpid();
-
- memset(&said, 0, sizeof(said));
- iv_opt = akey_opt = ekey_opt = alg_opt = edst_opt = spi_opt = proto_opt = af_opt = said_opt = dst_opt = src_opt = NULL;
- {
- int i,j;
- for(i = 0; i < life_maxsever; i++) {
- for(j = 0; j < life_maxtype; j++) {
- life_opt[i][j] = NULL;
- life[i][j] = 0;
- }
- }
- }
-
- while((c = getopt_long(argc, argv, ""/*"H:P:Z:46dcA:E:e:s:a:w:i:D:S:hvgl:+:f:"*/, longopts, 0)) != EOF) {
- switch(c) {
- case 'g':
- debug = 1;
- pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
- argcount--;
- break;
-
- case 'R':
- listenreply = 1;
- argcount--;
- break;
-
- case 'r':
- saref = 1;
- argcount--;
- break;
-
- case 'l':
- program_name = malloc(strlen(argv[0])
- + 10 /* update this when changing the sprintf() */
- + strlen(optarg));
- sprintf(program_name, "%s --label %s",
- argv[0],
- optarg);
- argcount -= 2;
- break;
- case 'H':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- if (!strcmp(optarg, "hmac-md5-96")) {
- alg = XF_AHHMACMD5;
- } else if(!strcmp(optarg, "hmac-sha1-96")) {
- alg = XF_AHHMACSHA1;
- } else {
- fprintf(stderr, "%s: Unknown authentication algorithm '%s' follows '--ah' option.\n",
- program_name, optarg);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case 'P':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- if (!strcmp(optarg, "3des-md5-96")) {
- alg = XF_ESP3DESMD596;
- } else if(!strcmp(optarg, "3des-sha1-96")) {
- alg = XF_ESP3DESSHA196;
- } else if(!strcmp(optarg, "3des")) {
- alg = XF_ESP3DES;
-#ifndef NO_KERNEL_ALG
- } else if((alg_info=alg_info_esp_create_from_str(optarg, &alg_err))) {
- int esp_ealg_id, esp_aalg_id;
- alg = XF_OTHER_ALG;
- if (alg_info->alg_info_cnt>1) {
- fprintf(stderr, "%s: Invalid encryption algorithm '%s' "
- "follows '--esp' option: lead too many(%d) "
- "transforms\n",
- program_name, optarg, alg_info->alg_info_cnt);
- exit(1);
- }
- alg_string=optarg;
- esp_info=&alg_info->esp[0];
- if (debug) {
- fprintf(stdout, "%s: alg_info: cnt=%d ealg[0]=%d aalg[0]=%d\n",
- program_name,
- alg_info->alg_info_cnt,
- esp_info->encryptalg,
- esp_info->authalg);
- }
- esp_ealg_id=esp_info->esp_ealg_id;
- esp_aalg_id=esp_info->esp_aalg_id;
- if (kernel_alg_proc_read()==0) {
- proc_read_ok++;
- if (!kernel_alg_esp_enc_ok(esp_ealg_id, 0, 0))
- {
- fprintf(stderr, "%s: ESP encryptalg=%d (\"%s\") "
- "not present\n",
- program_name,
- esp_ealg_id,
- enum_name(&esp_transformid_names, esp_ealg_id));
- exit(1);
- }
- if (!kernel_alg_esp_auth_ok(esp_aalg_id, 0))
- {
- fprintf(stderr, "%s: ESP authalg=%d (\"%s\")"
- "not present\n",
- program_name,
- esp_aalg_id,
- enum_name(&auth_alg_names, esp_aalg_id));
- exit(1);
- }
- }
-#endif /* NO_KERNEL_ALG */
- } else {
- fprintf(stderr, "%s: Invalid encryption algorithm '%s' follows '--esp' option.\n",
- program_name, optarg);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case 'Z':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- if (!strcmp(optarg, "deflate")) {
- alg = XF_COMPDEFLATE;
- } else {
- fprintf(stderr, "%s: Unknown compression algorithm '%s' follows '--comp' option.\n",
- program_name, optarg);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case '4':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- alg = XF_IP4;
- address_family = AF_INET;
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case '6':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- alg = XF_IP6;
- address_family = AF_INET6;
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case 'd':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- alg = XF_DEL;
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case 'c':
- if(alg) {
- fprintf(stderr, "%s: Only one of '--ah', '--esp', '--comp', '--ip4', '--ip6', '--del' or '--clear' options permitted.\n",
- program_name);
- exit(1);
- }
- alg = XF_CLR;
- if(debug) {
- fprintf(stdout, "%s: Algorithm %d selected.\n",
- program_name,
- alg);
- }
- alg_opt = optarg;
- break;
- case 'e':
- if(said_opt) {
- fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined in SA:%s\n",
- program_name, optarg, said_opt);
- exit (1);
- }
- if(edst_opt) {
- fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, edst_opt);
- exit (1);
- }
- error_s = ttoaddr(optarg, 0, address_family, &edst);
- if(error_s != NULL) {
- if(error_s) {
- fprintf(stderr, "%s: Error, %s converting --edst argument:%s\n",
- program_name, error_s, optarg);
- exit (1);
- }
- }
- edst_opt = optarg;
- if(debug) {
- addrtot(&edst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: edst=%s.\n",
- program_name,
- ipaddr_txt);
- }
- break;
- case 's':
- if(said_opt) {
- fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined in SA:%s\n",
- program_name, optarg, said_opt);
- exit (1);
- }
- if(spi_opt) {
- fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, spi_opt);
- exit (1);
- }
- spi = strtoul(optarg, &endptr, 0);
- if(!(endptr == optarg + strlen(optarg))) {
- fprintf(stderr, "%s: Invalid character in SPI parameter: %s\n",
- program_name, optarg);
- exit (1);
- }
- if(spi < 0x100) {
- fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than 0x100.\n",
- program_name, optarg, spi);
- exit(1);
- }
- spi_opt = optarg;
- break;
- case 'p':
- if(said_opt) {
- fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined in SA:%s\n",
- program_name, optarg, said_opt);
- exit (1);
- }
- if(proto_opt) {
- fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, proto_opt);
- exit (1);
- }
- if(!strcmp(optarg, "ah"))
- proto = SA_AH;
- if(!strcmp(optarg, "esp"))
- proto = SA_ESP;
- if(!strcmp(optarg, "tun"))
- proto = SA_IPIP;
- if(!strcmp(optarg, "comp"))
- proto = SA_COMP;
- if(proto == 0) {
- fprintf(stderr, "%s: Invalid PROTO parameter: %s\n",
- program_name, optarg);
- exit (1);
- }
- proto_opt = optarg;
- break;
- case 'a':
- if(said_opt) {
- fprintf(stderr, "%s: Error, ADDRESS FAMILY parameter redefined:%s, already defined in SA:%s\n",
- program_name, optarg, said_opt);
- exit (1);
- }
- if(af_opt) {
- fprintf(stderr, "%s: Error, ADDRESS FAMILY parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, af_opt);
- exit (1);
- }
- if(strcmp(optarg, "inet") == 0) {
- address_family = AF_INET;
- /* currently we ensure that all addresses belong to the same address family */
- anyaddr(address_family, &dst);
- anyaddr(address_family, &edst);
- anyaddr(address_family, &src);
- }
- if(strcmp(optarg, "inet6") == 0) {
- address_family = AF_INET6;
- /* currently we ensure that all addresses belong to the same address family */
- anyaddr(address_family, &dst);
- anyaddr(address_family, &edst);
- anyaddr(address_family, &src);
- }
- if((strcmp(optarg, "inet") != 0) && (strcmp(optarg, "inet6") != 0)) {
- fprintf(stderr, "%s: Invalid ADDRESS FAMILY parameter: %s.\n",
- program_name, optarg);
- exit (1);
- }
- af_opt = optarg;
- break;
- case 'I':
- if(said_opt) {
- fprintf(stderr, "%s: Error, SAID parameter redefined:%s, already defined in SA:%s\n",
- program_name, optarg, said_opt);
- exit (1);
- }
- if(proto_opt) {
- fprintf(stderr, "%s: Error, PROTO parameter redefined in SA:%s, already defined as:%s\n",
- program_name, optarg, proto_opt);
- exit (1);
- }
- if(edst_opt) {
- fprintf(stderr, "%s: Error, EDST parameter redefined in SA:%s, already defined as:%s\n",
- program_name, optarg, edst_opt);
- exit (1);
- }
- if(spi_opt) {
- fprintf(stderr, "%s: Error, SPI parameter redefined in SA:%s, already defined as:%s\n",
- program_name, optarg, spi_opt);
- exit (1);
- }
- error_s = ttosa(optarg, 0, &said);
- if(error_s != NULL) {
- fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n",
- program_name, error_s, optarg);
- exit (1);
- }
- if(debug) {
- satot(&said, 0, ipsaid_txt, sizeof(ipsaid_txt));
- fprintf(stdout, "%s: said=%s.\n",
- program_name,
- ipsaid_txt);
- }
- /* init the src and dst with the same address family */
- if(address_family == 0) {
- address_family = addrtypeof(&said.dst);
- } else if(address_family != addrtypeof(&said.dst)) {
- fprintf(stderr, "%s: Error, specified address family (%d) is different that of SAID: %s\n",
- program_name, address_family, optarg);
- exit (1);
- }
- anyaddr(address_family, &dst);
- anyaddr(address_family, &edst);
- anyaddr(address_family, &src);
- said_opt = optarg;
- break;
- case 'A':
- if(optarg[0] == '0') {
- switch(optarg[1]) {
- case 't':
- case 'x':
- case 's':
- break;
- default:
- fprintf(stderr, "%s: Authentication key must have a '0x', '0t' or '0s' prefix to select the format: %s\n",
- program_name, optarg);
- exit(1);
- }
- }
- authkeylen = atodata(optarg, 0, NULL, 0);
- if(!authkeylen) {
- fprintf(stderr, "%s: unknown format or syntax error in authentication key: %s\n",
- program_name, optarg);
- exit (1);
- }
- authkey = malloc(authkeylen);
- if(authkey == NULL) {
- fprintf(stderr, "%s: Memory allocation error.\n", program_name);
- exit(1);
- }
- memset(authkey, 0, authkeylen);
- authkeylen = atodata(optarg, 0, authkey, authkeylen);
- akey_opt = optarg;
- break;
- case 'E':
- if(optarg[0] == '0') {
- switch(optarg[1]) {
- case 't':
- case 'x':
- case 's':
- break;
- default:
- fprintf(stderr, "%s: Encryption key must have a '0x', '0t' or '0s' prefix to select the format: %s\n",
- program_name, optarg);
- exit(1);
- }
- }
- enckeylen = atodata(optarg, 0, NULL, 0);
- if(!enckeylen) {
- fprintf(stderr, "%s: unknown format or syntax error in encryption key: %s\n",
- program_name, optarg);
- exit (1);
- }
- enckey = malloc(enckeylen);
- if(enckey == NULL) {
- fprintf(stderr, "%s: Memory allocation error.\n", program_name);
- exit(1);
- }
- memset(enckey, 0, enckeylen);
- enckeylen = atodata(optarg, 0, enckey, enckeylen);
- ekey_opt = optarg;
- break;
- case 'w':
- replay_window = strtoul(optarg, &endptr, 0);
- if(!(endptr == optarg + strlen(optarg))) {
- fprintf(stderr, "%s: Invalid character in replay_window parameter: %s\n",
- program_name, optarg);
- exit (1);
- }
- if((replay_window < 0x1) || (replay_window > 64)) {
- fprintf(stderr, "%s: Failed -- Illegal window size: arg=%s, replay_window=%d, must be 1 <= size <= 64.\n",
- program_name, optarg, replay_window);
- exit(1);
- }
- break;
- case 'i':
- if(optarg[0] == '0') {
- switch(optarg[1]) {
- case 't':
- case 'x':
- case 's':
- break;
- default:
- fprintf(stderr, "%s: IV must have a '0x', '0t' or '0s' prefix to select the format, found '%c'.\n",
- program_name, optarg[1]);
- exit(1);
- }
- }
- ivlen = atodata(optarg, 0, NULL, 0);
- if(!ivlen) {
- fprintf(stderr, "%s: unknown format or syntax error in IV: %s\n",
- program_name, optarg);
- exit (1);
- }
- iv = malloc(ivlen);
- if(iv == NULL) {
- fprintf(stderr, "%s: Memory allocation error.\n", program_name);
- exit(1);
- }
- memset(iv, 0, ivlen);
- ivlen = atodata(optarg, 0, iv, ivlen);
- iv_opt = optarg;
- break;
- case 'D':
- if(dst_opt) {
- fprintf(stderr, "%s: Error, DST parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, dst_opt);
- exit (1);
- }
- error_s = ttoaddr(optarg, 0, address_family, &dst);
- if(error_s != NULL) {
- fprintf(stderr, "%s: Error, %s converting --dst argument:%s\n",
- program_name, error_s, optarg);
- exit (1);
- }
- dst_opt = optarg;
- if(debug) {
- addrtot(&dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: dst=%s.\n",
- program_name,
- ipaddr_txt);
- }
- break;
- case 'S':
- if(src_opt) {
- fprintf(stderr, "%s: Error, SRC parameter redefined:%s, already defined as:%s\n",
- program_name, optarg, src_opt);
- exit (1);
- }
- error_s = ttoaddr(optarg, 0, address_family, &src);
- if(error_s != NULL) {
- fprintf(stderr, "%s: Error, %s converting --src argument:%s\n",
- program_name, error_s, optarg);
- exit (1);
- }
- src_opt = optarg;
- if(debug) {
- addrtot(&src, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: src=%s.\n",
- program_name,
- ipaddr_txt);
- }
- break;
- case 'h':
- usage(program_name, stdout);
- exit(0);
- case '?':
- usage(program_name, stderr);
- exit(1);
- case 'v':
- fprintf(stdout, "%s, %s\n", program_name, spi_c_version);
- exit(1);
- case '+': /* optionsfrom */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* no return on error */
- break;
- case 'f':
- if(parse_life_options(life,
- life_opt,
- optarg) != 0) {
- exit(1);
- };
- break;
- default:
- fprintf(stderr, "%s: unrecognized option '%c', update option processing.\n",
- program_name, c);
- exit(1);
- }
- previous = c;
- }
- if(debug) {
- fprintf(stdout, "%s: All options processed.\n",
- program_name);
- }
-
- if(argcount == 1) {
- system("cat /proc/net/ipsec_spi");
- exit(0);
- }
-
- switch(alg) {
-#ifndef NO_KERNEL_ALG
- case XF_OTHER_ALG:
- /* validate keysizes */
- if (proc_read_ok) {
- const struct sadb_alg *alg_p;
- size_t keylen, minbits, maxbits;
-
- alg_p=kernel_alg_sadb_alg_get(SADB_SATYPE_ESP,SADB_EXT_SUPPORTED_ENCRYPT,
- esp_info->encryptalg);
- assert(alg_p);
- keylen=enckeylen * 8;
-
- if (alg_p->sadb_alg_id==ESP_3DES || alg_p->sadb_alg_id==ESP_DES) {
- maxbits=minbits=alg_p->sadb_alg_minbits * 8 /7;
- } else {
- minbits=alg_p->sadb_alg_minbits;
- maxbits=alg_p->sadb_alg_maxbits;
- }
- /*
- * if explicit keylen told in encrypt algo, eg "aes128"
- * check actual keylen "equality"
- */
- if (esp_info->esp_ealg_keylen &&
- esp_info->esp_ealg_keylen!=keylen) {
- fprintf(stderr, "%s: invalid encryption keylen=%d, "
- "required %d by encrypt algo string=\"%s\"\n",
- program_name,
- (int)keylen,
- (int)esp_info->esp_ealg_keylen,
- alg_string);
- exit(1);
-
- }
- /* thanks DES for this sh*t */
-
- if (minbits > keylen || maxbits < keylen) {
- fprintf(stderr, "%s: invalid encryption keylen=%d, "
- "must be between %d and %d bits\n",
- program_name,
- (int)keylen, (int)minbits, (int)maxbits);
- exit(1);
- }
- alg_p=kernel_alg_sadb_alg_get(SADB_SATYPE_ESP,SADB_EXT_SUPPORTED_AUTH,
- esp_info->authalg);
- assert(alg_p);
- keylen=authkeylen * 8;
- minbits=alg_p->sadb_alg_minbits;
- maxbits=alg_p->sadb_alg_maxbits;
- if (minbits > keylen || maxbits < keylen) {
- fprintf(stderr, "%s: invalid auth keylen=%d, "
- "must be between %d and %d bits\n",
- program_name,
- (int)keylen, (int)minbits, (int)maxbits);
- exit(1);
- }
-
- }
-#endif /* NO_KERNEL_ALG */
- case XF_IP4:
- case XF_IP6:
- case XF_DEL:
- case XF_AHHMACMD5:
- case XF_AHHMACSHA1:
- case XF_ESP3DESMD596:
- case XF_ESP3DESSHA196:
- case XF_ESP3DES:
- case XF_COMPDEFLATE:
- if(!said_opt) {
- if(isanyaddr(&edst)) {
- fprintf(stderr, "%s: SA destination not specified.\n",
- program_name);
- exit(1);
- }
- if(!spi) {
- fprintf(stderr, "%s: SA SPI not specified.\n",
- program_name);
- exit(1);
- }
- if(!proto) {
- fprintf(stderr, "%s: SA PROTO not specified.\n",
- program_name);
- exit(1);
- }
- initsaid(&edst, htonl(spi), proto, &said);
- } else {
- proto = said.proto;
- spi = ntohl(said.spi);
- edst = said.dst;
- }
- if((address_family != 0) && (address_family != addrtypeof(&said.dst))) {
- fprintf(stderr, "%s: Defined address family and address family of SA missmatch.\n",
- program_name);
- exit(1);
- }
- sa_len = satot(&said, 0, sa, sizeof(sa));
-
- if(debug) {
- fprintf(stdout, "%s: SA valid.\n",
- program_name);
- }
- break;
- case XF_CLR:
- break;
- default:
- fprintf(stderr, "%s: No action chosen. See '%s --help' for usage.\n",
- program_name, program_name);
- exit(1);
- }
-
- switch(alg) {
- case XF_CLR:
- case XF_DEL:
- case XF_IP4:
- case XF_IP6:
- case XF_AHHMACMD5:
- case XF_AHHMACSHA1:
- case XF_ESP3DESMD596:
- case XF_ESP3DESSHA196:
- case XF_ESP3DES:
- case XF_COMPDEFLATE:
-#ifndef NO_KERNEL_ALG
- case XF_OTHER_ALG:
-#endif /* NO_KERNEL_ALG */
- break;
- default:
- fprintf(stderr, "%s: No action chosen. See '%s --help' for usage.\n",
- program_name, program_name);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: Algorithm ok.\n",
- program_name);
- }
-
- if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
- fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",
- program_name);
- switch(errno) {
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENXIO:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case EAFNOSUPPORT:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- default:
- fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno);
- }
- exit(1);
- }
-
-#ifdef MANUAL_IS_NOT_ABLE_TO_NEGOTIATE
- /* for registering SA types that can be negotiated */
- if(pfkey_register(SADB_SATYPE_AH) != 0) {
- exit(1);
- }
- if(pfkey_register(SADB_SATYPE_ESP) != 0) {
- exit(1);
- }
- if(pfkey_register(SADB_X_SATYPE_IPIP) != 0) {
- exit(1);
- }
- if(pfkey_register(SADB_X_SATYPE_COMP) != 0) {
- exit(1);
- }
-#endif /* MANUAL_IS_NOT_ABLE_TO_NEGOTIATE */
-
- /* Build an SADB_ADD message to send down. */
- /* It needs <base, SA, address(SD), key(AE)> minimum. */
- /* Lifetime(HS) could be added before addresses. */
- pfkey_extensions_init(extensions);
- if(debug) {
- fprintf(stdout, "%s: extensions=0p%p &extensions=0p%p extensions[0]=0p%p &extensions[0]=0p%p cleared.\n",
- program_name,
- extensions,
- &extensions,
- extensions[0],
- &extensions[0]);
- }
- if((error = pfkey_msg_hdr_build(&extensions[0],
- (alg == XF_DEL ? SADB_DELETE : alg == XF_CLR ? SADB_FLUSH : SADB_ADD),
- proto2satype(proto),
- 0,
- ++pfkey_seq,
- mypid))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: extensions=0p%p &extensions=0p%p extensions[0]=0p%p &extensions[0]=0p%p set w/msghdr.\n",
- program_name,
- extensions,
- &extensions,
- extensions[0],
- &extensions[0]);
- }
- if(debug) {
- fprintf(stdout, "%s: base message assembled.\n", program_name);
- }
-
- switch(alg) {
- case XF_AHHMACMD5:
- case XF_ESP3DESMD596:
- authalg = SADB_AALG_MD5_HMAC;
- break;
- case XF_AHHMACSHA1:
- case XF_ESP3DESSHA196:
- authalg = SADB_AALG_SHA1_HMAC;
- break;
-#ifndef NO_KERNEL_ALG
- case XF_OTHER_ALG:
- authalg= esp_info->authalg;
- if(debug) {
- fprintf(stdout, "%s: debug: authalg=%d\n",
- program_name, authalg);
- }
- break;
-#endif /* NO_KERNEL_ALG */
- case XF_ESP3DESMD5:
- default:
- authalg = SADB_AALG_NONE;
- }
- switch(alg) {
- case XF_ESP3DES:
- case XF_ESP3DESMD596:
- case XF_ESP3DESSHA196:
- encryptalg = SADB_EALG_3DES_CBC;
- break;
- case XF_COMPDEFLATE:
- encryptalg = SADB_X_CALG_DEFLATE;
- break;
-#ifndef NO_KERNEL_ALG
- case XF_OTHER_ALG:
- encryptalg= esp_info->encryptalg;
- if(debug) {
- fprintf(stdout, "%s: debug: encryptalg=%d\n",
- program_name, encryptalg);
- }
- break;
-#endif /* NO_KERNEL_ALG */
- default:
- encryptalg = SADB_EALG_NONE;
- }
- if(!(alg == XF_CLR /* IE: pfkey_msg->sadb_msg_type == SADB_FLUSH */)) {
- if((error = pfkey_sa_build(&extensions[SADB_EXT_SA],
- SADB_EXT_SA,
- htonl(spi), /* in network order */
- replay_window,
- SADB_SASTATE_MATURE,
- authalg,
- encryptalg,
- 0))) {
- fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: extensions[0]=0p%p previously set with msg_hdr.\n",
- program_name,
- extensions[0]);
- }
- if(debug) {
- fprintf(stdout, "%s: assembled SA extension, pfkey msg authalg=%d encalg=%d.\n",
- program_name,
- authalg,
- encryptalg);
- }
-
- if(debug) {
- int i,j;
- for(i = 0; i < life_maxsever; i++) {
- for(j = 0; j < life_maxtype; j++) {
- fprintf(stdout, "%s: i=%d, j=%d, life_opt[%d][%d]=0p%p, life[%d][%d]=%d\n",
- program_name,
- i, j, i, j, life_opt[i][j], i, j, life[i][j]);
- }
- }
- }
- if(life_opt[life_soft][life_alloc] != NULL ||
- life_opt[life_soft][life_bytes] != NULL ||
- life_opt[life_soft][life_addtime] != NULL ||
- life_opt[life_soft][life_usetime] != NULL ||
- life_opt[life_soft][life_packets] != NULL) {
- if((error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
- SADB_EXT_LIFETIME_SOFT,
- life[life_soft][life_alloc],/*-1,*/ /*allocations*/
- life[life_soft][life_bytes],/*-1,*/ /*bytes*/
- life[life_soft][life_addtime],/*-1,*/ /*addtime*/
- life[life_soft][life_usetime],/*-1,*/ /*usetime*/
- life[life_soft][life_packets]/*-1*/))) { /*packets*/
- fprintf(stderr, "%s: Trouble building lifetime_s extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: lifetime_s extension assembled.\n",
- program_name);
- }
- }
-
- if(life_opt[life_hard][life_alloc] != NULL ||
- life_opt[life_hard][life_bytes] != NULL ||
- life_opt[life_hard][life_addtime] != NULL ||
- life_opt[life_hard][life_usetime] != NULL ||
- life_opt[life_hard][life_packets] != NULL) {
- if((error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
- SADB_EXT_LIFETIME_HARD,
- life[life_hard][life_alloc],/*-1,*/ /*allocations*/
- life[life_hard][life_bytes],/*-1,*/ /*bytes*/
- life[life_hard][life_addtime],/*-1,*/ /*addtime*/
- life[life_hard][life_usetime],/*-1,*/ /*usetime*/
- life[life_hard][life_packets]/*-1*/))) { /*packets*/
- fprintf(stderr, "%s: Trouble building lifetime_h extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: lifetime_h extension assembled.\n",
- program_name);
- }
- }
-
- if(debug) {
- addrtot(&src, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: assembling address_s extension (%s).\n",
- program_name, ipaddr_txt);
- }
-
- if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
- SADB_EXT_ADDRESS_SRC,
- 0,
- 0,
- sockaddrof(&src)))) {
- addrtot(&src, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n",
- program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- ip_address temp_addr;
-
- switch(address_family) {
- case AF_INET:
- initaddr((const unsigned char *)&(((struct sockaddr_in*)( ((struct sadb_address*)(extensions[SADB_EXT_ADDRESS_SRC])) + 1))->sin_addr),
- sockaddrlenof(&src), address_family, &temp_addr);
- break;
- case AF_INET6:
- initaddr((const unsigned char *)&(((struct sockaddr_in6*)( ((struct sadb_address*)(extensions[SADB_EXT_ADDRESS_SRC])) + 1))->sin6_addr),
- sockaddrlenof(&src), address_family, &temp_addr);
- break;
- default:
- fprintf(stdout, "%s: unknown address family (%d).\n",
- program_name, address_family);
- exit(1);
- }
- addrtot(&temp_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: address_s extension assembled (%s).\n",
- program_name, ipaddr_txt);
- }
-
- if(debug) {
- addrtot(&edst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: assembling address_d extension (%s).\n",
- program_name, ipaddr_txt);
- }
-
- if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
- SADB_EXT_ADDRESS_DST,
- 0,
- 0,
- sockaddrof(&edst)))) {
- addrtot(&edst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n",
- program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- ip_address temp_addr;
- switch(address_family) {
- case AF_INET:
- initaddr((const unsigned char *)&(((struct sockaddr_in*)( ((struct sadb_address*)(extensions[SADB_EXT_ADDRESS_DST])) + 1))->sin_addr),
- 4, address_family, &temp_addr);
- break;
- case AF_INET6:
- initaddr((const unsigned char *)&(((struct sockaddr_in6*)( ((struct sadb_address*)(extensions[SADB_EXT_ADDRESS_DST])) + 1))->sin6_addr),
- 16, address_family, &temp_addr);
- break;
- default:
- fprintf(stdout, "%s: unknown address family (%d).\n",
- program_name, address_family);
- exit(1);
- }
- addrtot(&temp_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "%s: address_d extension assembled (%s).\n",
- program_name, ipaddr_txt);
- }
-
-#if PFKEY_PROXY
- anyaddr(address_family, &pfkey_address_p_ska);
- if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
- SADB_EXT_ADDRESS_PROXY,
- 0,
- 0,
- sockaddrof(&pfkey_address_p_ska)))) {
- fprintf(stderr, "%s: Trouble building address_p extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: address_p extension assembled.\n", program_name);
- }
-#endif /* PFKEY_PROXY */
-
- switch(alg) {
-#ifndef NO_KERNEL_ALG
- /* Allow no auth ... after all is local root decision 8) */
- case XF_OTHER_ALG:
- if (!authalg)
- break;
-#endif /* NO_KERNEL_ALG */
- case XF_AHHMACMD5:
- case XF_ESP3DESMD596:
- case XF_AHHMACSHA1:
- case XF_ESP3DESSHA196:
- if((error = pfkey_key_build(&extensions[SADB_EXT_KEY_AUTH],
- SADB_EXT_KEY_AUTH,
- authkeylen * 8,
- authkey))) {
- fprintf(stderr, "%s: Trouble building key_a extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: key_a extension assembled.\n",
- program_name);
- }
- break;
- default:
- break;
- }
-
- switch(alg) {
- case XF_ESP3DES:
- case XF_ESP3DESMD596:
- case XF_ESP3DESSHA196:
-#ifndef NO_KERNEL_ALG
- case XF_OTHER_ALG:
-#endif /* NO_KERNEL_ALG */
- if((error = pfkey_key_build(&extensions[SADB_EXT_KEY_ENCRYPT],
- SADB_EXT_KEY_ENCRYPT,
- enckeylen * 8,
- enckey))) {
- fprintf(stderr, "%s: Trouble building key_e extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: key_e extension assembled.\n",
- program_name);
- }
- break;
- default:
- break;
- }
-
-#ifdef PFKEY_IDENT /* GG: looks wierd, not touched */
- if((pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
- SADB_EXT_IDENTITY_SRC,
- SADB_IDENTTYPE_PREFIX,
- 0,
- strlen(pfkey_ident_s_ska),
- pfkey_ident_s_ska))) {
- fprintf(stderr, "%s: Trouble building ident_s extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(subnettoa(addr, mask, format, pfkey_ident_s_ska,
- sizeof(pfkey_ident_s_ska) ) !=
- sizeof(pfkey_ident_s_ska) ) {
- exit (1);
- }
-
- if((error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
- SADB_EXT_IDENTITY_DST,
- SADB_IDENTTYPE_PREFIX,
- 0,
- strlen(pfkey_ident_d_ska),
- pfkey_ident_d_ska))) {
- fprintf(stderr, "%s: Trouble building ident_d extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- if(subnettoa(addr, mask, format, pfkey_ident_d_ska,
- sizeof(pfkey_ident_d_ska) ) !=
- sizeof(pfkey_ident_d_ska) ) {
- exit (1);
- }
-
- if(debug) {
- fprintf(stdout, "%s: ident extensions assembled.\n",
- program_name);
- }
-#endif /* PFKEY_IDENT */
- }
-
- if(debug) {
- fprintf(stdout, "%s: assembling pfkey msg....\n",
- program_name);
- }
- if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
- if(debug) {
- fprintf(stdout, "%s: assembled.\n",
- program_name);
- }
- if(debug) {
- fprintf(stdout, "%s: writing pfkey msg.\n",
- program_name);
- }
- io_error = write(pfkey_sock,
- pfkey_msg,
- pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
- if(io_error < 0) {
- fprintf(stderr, "%s: pfkey write failed (errno=%d): ",
- program_name, errno);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- switch(errno) {
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- fprintf(stderr, "No device?!?\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case ENXIO:
- case ESRCH:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case ENOSPC:
- fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n");
- break;
- case ESPIPE:
- fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket write error %d (%s). Please report as much detail as possible to development team.\n",
- errno, strerror(errno));
- }
- exit(1);
- } else if (io_error != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
- fprintf(stderr, "%s: pfkey write truncated to %d bytes\n",
- program_name, (int)io_error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
-
- if(debug) {
- fprintf(stdout, "%s: pfkey command written to socket.\n",
- program_name);
- }
-
- if(pfkey_msg) {
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- }
- if(debug) {
- fprintf(stdout, "%s: pfkey message buffer freed.\n",
- program_name);
- }
- if(authkey) {
- memset((caddr_t)authkey, 0, authkeylen);
- free(authkey);
- }
- if(enckey) {
- memset((caddr_t)enckey, 0, enckeylen);
- free(enckey);
- }
- if(iv) {
- memset((caddr_t)iv, 0, ivlen);
- free(iv);
- }
-
- if(listenreply || saref) {
- ssize_t readlen;
- unsigned char pfkey_buf[PFKEYv2_MAX_MSGSIZE];
-
- while((readlen = read(pfkey_sock, pfkey_buf, sizeof(pfkey_buf))) > 0) {
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- pfkey_extensions_init(extensions);
- pfkey_msg = (struct sadb_msg *)pfkey_buf;
-
- /* first, see if we got enough for an sadb_msg */
- if((size_t)readlen < sizeof(struct sadb_msg)) {
- if(debug) {
- printf("%s: runt packet of size: %ld (<%lu)\n",
- program_name, (long)readlen, (unsigned long)sizeof(struct sadb_msg));
- }
- continue;
- }
-
- /* okay, we got enough for a message, print it out */
- if(debug) {
- printf("%s: pfkey v%d msg received. type=%d(%s) seq=%d len=%d pid=%d errno=%d satype=%d(%s)\n",
- program_name,
- pfkey_msg->sadb_msg_version,
- pfkey_msg->sadb_msg_type,
- pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
- pfkey_msg->sadb_msg_seq,
- pfkey_msg->sadb_msg_len,
- pfkey_msg->sadb_msg_pid,
- pfkey_msg->sadb_msg_errno,
- pfkey_msg->sadb_msg_satype,
- satype2name(pfkey_msg->sadb_msg_satype));
- }
-
- if(readlen != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN))
- {
- if(debug) {
- printf("%s: packet size read from socket=%d doesn't equal sadb_msg_len %u * %u; message not decoded\n",
- program_name,
- (int)readlen,
- (unsigned)pfkey_msg->sadb_msg_len,
- (unsigned)IPSEC_PFKEYv2_ALIGN);
- }
- continue;
- }
-
- if (pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_OUT)) {
- if(debug) {
- printf("%s: unparseable PF_KEY message.\n",
- program_name);
- }
- continue;
- } else {
- if(debug) {
- printf("%s: parseable PF_KEY message.\n",
- program_name);
- }
- }
- if((pid_t)pfkey_msg->sadb_msg_pid == mypid) {
- if(saref) {
- printf("%s: saref=%d\n",
- program_name,
- (extensions[SADB_EXT_SA] != NULL)
- ? ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_x_sa_ref
- : IPSEC_SAREF_NULL);
- }
- break;
- }
- }
- }
- (void) close(pfkey_sock); /* close the socket */
- if(debug || listenreply) {
- printf("%s: exited normally\n", program_name);
- }
- exit(0);
-}
diff --git a/programs/spigrp/.cvsignore b/programs/spigrp/.cvsignore
deleted file mode 100644
index 4fee1abcf..000000000
--- a/programs/spigrp/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-spigrp
diff --git a/programs/spigrp/Makefile b/programs/spigrp/Makefile
deleted file mode 100644
index df8899eaf..000000000
--- a/programs/spigrp/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# Makefile for miscelaneous programs
-# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM=spigrp
-EXTRA5PROC=${PROGRAM}.5
-
-LIBS=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
-
diff --git a/programs/spigrp/spigrp.5 b/programs/spigrp/spigrp.5
deleted file mode 100644
index b00d7ae73..000000000
--- a/programs/spigrp/spigrp.5
+++ /dev/null
@@ -1,116 +0,0 @@
-.TH IPSEC_SPIGRP 5 "27 Jun 2000"
-.\"
-.\" RCSID $Id: spigrp.5,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec_spigrp \- list IPSEC Security Association groupings
-.SH SYNOPSIS
-.B ipsec
-.B spigrp
-.PP
-.B cat
-.B /proc/net/ipsec_spigrp
-.PP
-.SH DESCRIPTION
-.I /proc/net/ipsec_spigrp
-is a read-only file that lists groups of IPSEC Security Associations
-(SAs).
-.PP
-An entry in the IPSEC extended routing table can only point (via an
-SAID) to one SA. If more than one transform must be applied to a given
-type of packet, this can be accomplished by setting up several SAs with
-the same destination address but potentially different SPIs and
-protocols, and grouping them with
-.IR ipsec_spigrp(8) .
-.PP
-The SA groups are listed, one line per connection/group, as a sequence
-of SAs to be applied (or that should have been applied, in the case of
-an incoming packet) from inside to outside the packet. An SA is
-identified by its SAID, which consists of protocol ("ah", "esp", "comp" or
-"tun"), SPI (with '.' for IPv4 or ':' for IPv6 prefixed hexadecimal number ) and destination address
-(IPv4 dotted quad or IPv6 coloned hex) prefixed by '@', in the format <proto><af><spi>@<dest>.
-.SH EXAMPLES
-.TP
-.B tun.3d0@192.168.2.110
-.B comp.3d0@192.168.2.110
-.B esp.187a101b@192.168.2.110
-.B ah.187a101a@192.168.2.110
-.LP
-is a group of 3 SAs, destined for
-.BR 192.168.2.110
-with an IPv4-in-IPv4 tunnel SA applied first with an SPI of
-.BR 3d0
-in hexadecimal, followed by a Deflate compression header to compress
-the packet with CPI of
-.BR 3d0
-in hexadecimal, followed by an Encapsulating Security Payload header to
-encrypt the packet with SPI
-.BR 187a101b
-in hexadecimal, followed by an Authentication Header to authenticate the
-packet with SPI
-.BR 187a101a
-in hexadecimal, applied from inside to outside the packet. This could
-be an incoming or outgoing group, depending on the address of the local
-machine.
-.LP
-.TP
-.B tun:3d0@3049:1::2
-.B comp:3d0@3049:1::2
-.B esp:187a101b@3049:1::2
-.B ah:187a101a@3049:1::2
-.LP
-is a group of 3 SAs, destined for
-.BR 3049:1::2
-with an IPv6-in-IPv6 tunnel SA applied first with an SPI of
-.BR 3d0
-in hexadecimal, followed by a Deflate compression header to compress
-the packet with CPI of
-.BR 3d0
-in hexadecimal, followed by an Encapsulating Security Payload header to
-encrypt the packet with SPI
-.BR 187a101b
-in hexadecimal, followed by an Authentication Header to authenticate the
-packet with SPI
-.BR 187a101a
-in hexadecimal, applied from inside to outside the packet. This could
-be an incoming or outgoing group, depending on the address of the local
-machine.
-.LP
-.SH FILES
-/proc/net/ipsec_spigrp, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(5), ipsec_eroute(5),
-ipsec_spi(5), ipsec_klipsdebug(5), ipsec_spigrp(8), ipsec_version(5),
-ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.SH BUGS
-:-)
-.\"
-.\" $Log: spigrp.5,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.6 2002/04/24 07:35:40 mcr
-.\" Moved from ./klips/utils/spigrp.5,v
-.\"
-.\" Revision 1.5 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.4 2000/09/13 15:54:32 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/28 12:44:12 henry
-.\" format touchup
-.\"
-.\" Revision 1.1 2000/06/28 05:43:00 rgb
-.\" Added manpages for all 5 klips utils.
-.\"
-.\"
diff --git a/programs/spigrp/spigrp.8 b/programs/spigrp/spigrp.8
deleted file mode 100644
index 418ed5c3e..000000000
--- a/programs/spigrp/spigrp.8
+++ /dev/null
@@ -1,174 +0,0 @@
-.TH IPSEC_SPIGRP 8 "21 Jun 2000"
-.\"
-.\" RCSID $Id: spigrp.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec spigrp \- group/ungroup IPSEC Security Associations
-.SH SYNOPSIS
-.B ipsec
-.B spigrp
-.PP
-.B ipsec
-.B spigrp
-[
-.B \-\-label
-label ]
-af1 dst1 spi1 proto1 [ af2 dst2 spi2 proto2 [ af3 dst3 spi3 proto3 [ af4 dst4 spi4 proto4 ] ] ]
-.PP
-.B ipsec
-.B spigrp
-[
-.B \-\-label
-label ]
-.B \-\-said
-SA1 [ SA2 [ SA3 [ SA4 ] ] ]
-.PP
-.B ipsec
-.B spigrp
-.B \-\-help
-.PP
-.B ipsec
-.B spigrp
-.B \-\-version
-.PP
-.SH DESCRIPTION
-.I Spigrp
-groups IPSEC Security Associations (SAs) together or ungroups
-previously grouped SAs.
-An entry in the IPSEC extended
-routing table can only point
-(via a destination address, a Security Parameters Index (SPI) and
-a protocol identifier) to one SA.
-If more than one transform must be applied to a given type of packet,
-this can be accomplished by setting up several SAs
-with the same destination address but potentially different SPIs and protocols,
-and grouping them with
-.IR spigrp .
-.PP
-The SAs to be grouped,
-specified by destination address (DNS name lookup, IPv4 dotted quad or IPv6 coloned hex), SPI
-('0x'-prefixed hexadecimal number) and protocol ("ah", "esp", "comp" or "tun"),
-are listed from the inside transform to the
-outside;
-in other words, the transforms are applied in
-the order of the command line and removed in the reverse
-order.
-The resulting SA group is referred to by its first SA (by
-.IR af1 ,
-.IR dst1 ,
-.IR spi1
-and
-.IR proto1 ).
-.PP
-The \-\-said option indicates that the SA IDs are to be specified as
-one argument each, in the format <proto><af><spi>@<dest>. The SA IDs must
-all be specified as separate parameters without the \-\-said option or
-all as monolithic parameters after the \-\-said option.
-.PP
-The SAs must already exist and must not already
-be part of a group.
-.PP
-If
-.I spigrp
-is invoked with only one SA specification,
-it ungroups the previously-grouped set of SAs containing
-the SA specified.
-.PP
-The \-\-label option identifies all responses from that command
-invocation with a user-supplied label, provided as an argument to the
-label option. This can be helpful for debugging one invocation of the
-command out of a large number.
-.PP
-The command form with no additional arguments lists the contents of
-/proc/net/ipsec_spigrp. The format of /proc/net/ipsec_spigrp is
-discussed in ipsec_spigrp(5).
-.SH EXAMPLES
-.TP
-.B ipsec spigrp inet gw2 0x113 tun inet gw2 0x115 esp inet gw2 0x116 ah
-groups 3 SAs together, all destined for
-.BR gw2 ,
-but with an IPv4-in-IPv4 tunnel SA applied first with SPI
-.BR 0x113 ,
-then an ESP header to encrypt the packet with SPI
-.BR 0x115 ,
-and finally an AH header to authenticate the packet with SPI
-.BR 0x116 .
-.LP
-.TP
-.B ipsec spigrp --said tun.113@gw2 esp.115@gw2 ah.116@gw2
-groups 3 SAs together, all destined for
-.BR gw2 ,
-but with an IPv4-in-IPv4 tunnel SA applied first with SPI
-.BR 0x113 ,
-then an ESP header to encrypt the packet with SPI
-.BR 0x115 ,
-and finally an AH header to authenticate the packet with SPI
-.BR 0x116 .
-.LP
-.TP
-.B ipsec spigrp --said tun:233@3049:1::1 esp:235@3049:1::1 ah:236@3049:1::1
-groups 3 SAs together, all destined for
-.BR 3049:1::1,
-but with an IPv6-in-IPv6 tunnel SA applied first with SPI
-.BR 0x233 ,
-then an ESP header to encrypt the packet with SPI
-.BR 0x235 ,
-and finally an AH header to authenticate the packet with SPI
-.BR 0x236 .
-.LP
-.TP
-.B ipsec spigrp inet6 3049:1::1 0x233 tun inet6 3049:1::1 0x235 esp inet6 3049:1::1 0x236 ah
-groups 3 SAs together, all destined for
-.BR 3049:1::1,
-but with an IPv6-in-IPv6 tunnel SA applied first with SPI
-.BR 0x233 ,
-then an ESP header to encrypt the packet with SPI
-.BR 0x235 ,
-and finally an AH header to authenticate the packet with SPI
-.BR 0x236 .
-.LP
-.SH FILES
-/proc/net/ipsec_spigrp, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_tncfg(8), ipsec_eroute(8),
-ipsec_spi(8), ipsec_klipsdebug(8), ipsec_spigrp(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.SH BUGS
-Yes, it really is limited to a maximum of four SAs,
-although admittedly it's hard to see why you would need more.
-.\"
-.\" $Log: spigrp.8,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.20 2002/04/24 07:35:41 mcr
-.\" Moved from ./klips/utils/spigrp.8,v
-.\"
-.\" Revision 1.19 2000/09/17 18:56:48 rgb
-.\" Added IPCOMP support.
-.\"
-.\" Revision 1.18 2000/09/13 15:54:32 rgb
-.\" Added Gerhard's ipv6 updates.
-.\"
-.\" Revision 1.17 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.16 2000/06/21 16:54:57 rgb
-.\" Added 'no additional args' text for listing contents of
-.\" /proc/net/ipsec_* files.
-.\"
-.\" Revision 1.15 2000/02/14 21:08:30 rgb
-.\" Added description of --said option.
-.\"
-.\" Revision 1.14 1999/07/19 18:47:25 henry
-.\" fix slightly-misformed comments
-.\"
-.\" Revision 1.13 1999/04/06 04:54:39 rgb
-.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-.\" patch shell fixes.
-.\"
diff --git a/programs/spigrp/spigrp.c b/programs/spigrp/spigrp.c
deleted file mode 100644
index 4cbac304d..000000000
--- a/programs/spigrp/spigrp.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * SA grouping
- * Copyright (C) 1996 John Ioannidis.
- * Copyright (C) 1997, 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char spigrp_c_version[] = "RCSID $Id: spigrp.c,v 1.2 2004/06/07 15:16:34 as Exp $";
-
-
-#include <sys/types.h>
-#include <linux/types.h> /* new */
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h> /* open() */
-#include <fcntl.h> /* open() */
-#include <stdlib.h> /* system(), strtoul() */
-
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-/* #include <linux/ip.h> */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <freeswan.h>
-#if 0
-#include <linux/autoconf.h> /* CONFIG_IPSEC_PFKEYv2 */
-#endif
-
-#include <signal.h>
-#include <pfkeyv2.h>
-#include <pfkey.h>
-
-#include "freeswan/radij.h"
-#include "freeswan/ipsec_encap.h"
-#include "freeswan/ipsec_ah.h"
-
-
-char *program_name;
-
-int pfkey_sock;
-fd_set pfkey_socks;
-uint32_t pfkey_seq = 0;
-
-struct said_af {
- int af;
- ip_said said;
-}; /* to store the given saids and their address families in an array */
- /* XXX: Note that we do *not* check if the address families of all SAID?s are the same.
- * This can make it possible to group SAs for IPv4 addresses with SAs for
- * IPv6 addresses (perhaps some kind of IPv4-over-secIPv6 or vice versa).
- * Do not know, if this is a bug or feature */
-
-static void
-usage(char *s)
-{
- fprintf(stdout, "usage: Note: position of options and arguments is important!\n");
- fprintf(stdout, "usage: %s [ --debug ] [ --label <label> ] af1 dst1 spi1 proto1 [ af2 dst2 spi2 proto2 [ af3 dst3 spi3 proto3 [ af4 dst4 spi4 proto4 ] ] ]\n", s);
- fprintf(stdout, "usage: %s [ --debug ] [ --label <label> ] --said <SA1> [ <SA2> [ <SA3> [ <SA4> ] ] ]\n", s);
- fprintf(stdout, "usage: %s --help\n", s);
- fprintf(stdout, "usage: %s --version\n", s);
- fprintf(stdout, "usage: %s\n", s);
- fprintf(stdout, " [ --debug ] is optional to any %s command.\n", s);
- fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", s);
-}
-
-
-int
-main(int argc, char **argv)
-{
- int i, nspis;
- char *endptr;
- int said_opt = 0;
-
- const char* error_s = NULL;
- char ipaddr_txt[ADDRTOT_BUF];
- int debug = 0;
- int j;
- struct said_af said_af_array[4];
-
- int error = 0;
-
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- struct sadb_msg *pfkey_msg;
-#if 0
- ip_address pfkey_address_s_ska;
-#endif
-
- program_name = argv[0];
- for(i = 0; i < 4; i++) {
- memset(&said_af_array[i], 0, sizeof(struct said_af));
- }
-
- if(argc > 1 && strcmp(argv[1], "--debug") == 0) {
- debug = 1;
- if(debug) {
- fprintf(stdout, "\"--debug\" option requested.\n");
- }
- argv += 1;
- argc -= 1;
- pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX;
- }
-
- if(debug) {
- fprintf(stdout, "argc=%d (%d incl. --debug option).\n",
- argc,
- argc + 1);
- }
-
- if(argc > 1 && strcmp(argv[1], "--label") == 0) {
- if(argc > 2) {
- program_name = malloc(strlen(argv[0])
- + 10 /* update this when changing the sprintf() */
- + strlen(argv[2]));
- sprintf(program_name, "%s --label %s",
- argv[0],
- argv[2]);
- if(debug) {
- fprintf(stdout, "using \"%s\" as a label.\n", program_name);
- }
- argv += 2;
- argc -= 2;
- } else {
- fprintf(stderr, "%s: --label option requires an argument.\n",
- program_name);
- exit(1);
- }
- }
-
- if(debug) {
- fprintf(stdout, "...After check for --label option.\n");
- }
-
- if(argc == 1) {
- system("cat /proc/net/ipsec_spigrp");
- exit(0);
- }
-
- if(debug) {
- fprintf(stdout, "...After check for no option to print /proc/net/ipsec_spigrp.\n");
- }
-
- if(strcmp(argv[1], "--help") == 0) {
- if(debug) {
- fprintf(stdout, "\"--help\" option requested.\n");
- }
- usage(program_name);
- exit(1);
- }
-
- if(debug) {
- fprintf(stdout, "...After check for --help option.\n");
- }
-
- if(strcmp(argv[1], "--version") == 0) {
- if(debug) {
- fprintf(stdout, "\"--version\" option requested.\n");
- }
- fprintf(stderr, "%s, %s\n", program_name, spigrp_c_version);
- exit(1);
- }
-
- if(debug) {
- fprintf(stdout, "...After check for --version option.\n");
- }
-
- if(strcmp(argv[1], "--said") == 0) {
- if(debug) {
- fprintf(stdout, "processing %d args with --said flag.\n", argc);
- }
- said_opt = 1;
- }
-
- if(debug) {
- fprintf(stdout, "...After check for --said option.\n");
- }
-
- if(said_opt) {
- if (argc < 3 /*|| argc > 5*/) {
- fprintf(stderr, "expecting 3 or more args with --said, got %d.\n", argc);
- usage(program_name);
- exit(1);
- }
- nspis = argc - 2;
- } else {
- if ((argc < 5) || (argc > 17) || ((argc % 4) != 1)) {
- fprintf(stderr, "expecting 5 or more args without --said, got %d.\n", argc);
- usage(program_name);
- exit(1);
- }
- nspis = argc / 4;
- }
-
- if(debug) {
- fprintf(stdout, "processing %d nspis.\n", nspis);
- }
-
- for(i = 0; i < nspis; i++) {
- if(debug) {
- fprintf(stdout, "processing spi #%d.\n", i);
- }
-
- if(said_opt) {
- error_s = ttosa((const char *)argv[i+2], 0, (ip_said*)&(said_af_array[i].said));
- if(error_s != NULL) {
- fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n",
- program_name, error_s, argv[i+2]);
- exit (1);
- }
- said_af_array[i].af = addrtypeof(&(said_af_array[i].said.dst));
- if(debug) {
- addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "said[%d].dst=%s.\n", i, ipaddr_txt);
- }
- } else {
- if(!strcmp(argv[i*4+4], "ah")) {
- said_af_array[i].said.proto = SA_AH;
- }
- if(!strcmp(argv[i*4+4], "esp")) {
- said_af_array[i].said.proto = SA_ESP;
- }
- if(!strcmp(argv[i*4+4], "tun")) {
- said_af_array[i].said.proto = SA_IPIP;
- }
- if(!strcmp(argv[i*4+4], "comp")) {
- said_af_array[i].said.proto = SA_COMP;
- }
- if(said_af_array[i].said.proto == 0) {
- fprintf(stderr, "%s: Badly formed proto: %s\n",
- program_name, argv[i*4+4]);
- exit(1);
- }
- said_af_array[i].said.spi = htonl(strtoul(argv[i*4+3], &endptr, 0));
- if(!(endptr == argv[i*4+3] + strlen(argv[i*4+3]))) {
- fprintf(stderr, "%s: Badly formed spi: %s\n",
- program_name, argv[i*4+3]);
- exit(1);
- }
- if(!strcmp(argv[i*4+1], "inet")) {
- said_af_array[i].af = AF_INET;
- }
- if(!strcmp(argv[i*4+1], "inet6")) {
- said_af_array[i].af = AF_INET6;
- }
- if((said_af_array[i].af != AF_INET) && (said_af_array[i].af != AF_INET6)) {
- fprintf(stderr, "%s: Address family %s not supported\n",
- program_name, argv[i*4+1]);
- exit(1);
- }
- error_s = ttoaddr(argv[i*4+2], 0, said_af_array[i].af, &(said_af_array[i].said.dst));
- if(error_s != NULL) {
- fprintf(stderr, "%s: Error, %s converting %dth address argument:%s\n",
- program_name, error_s, i, argv[i*4+2]);
- exit (1);
- }
- }
- if(debug) {
- fprintf(stdout, "SA %d contains: ", i+1);
- fprintf(stdout, "\n");
- fprintf(stdout, "proto = %d\n", said_af_array[i].said.proto);
- fprintf(stdout, "spi = %08x\n", said_af_array[i].said.spi);
- addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stdout, "edst = %s\n", ipaddr_txt);
- }
- }
-
- if(debug) {
- fprintf(stdout, "Opening pfkey socket.\n");
- }
-
- if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) {
- fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ",
- program_name);
- switch(errno) {
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENXIO:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case EAFNOSUPPORT:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- break;
- default:
- fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno);
- }
- exit(1);
- }
-
- for(i = 0; i < (((nspis - 1) < 2) ? 1 : (nspis - 1)); i++) {
- if(debug) {
- fprintf(stdout, "processing %dth pfkey message.\n", i);
- }
-
- pfkey_extensions_init(extensions);
- for(j = 0; j < ((nspis == 1) ? 1 : 2); j++) {
- if(debug) {
- fprintf(stdout, "processing %dth said of %dth pfkey message.\n", j, i);
- }
-
- /* Build an SADB_X_GRPSA message to send down. */
- /* It needs <base, SA, SA2, address(D,D2) > minimum. */
- if(!j) {
- if((error = pfkey_msg_hdr_build(&extensions[0],
- SADB_X_GRPSA,
- proto2satype(said_af_array[i].said.proto),
- 0,
- ++pfkey_seq,
- getpid()))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- } else {
- if(debug) {
- fprintf(stdout, "setting x_satype proto=%d satype=%d\n",
- said_af_array[i+j].said.proto,
- proto2satype(said_af_array[i+j].said.proto)
- );
- }
-
- if((error = pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2],
- proto2satype(said_af_array[i+j].said.proto)
- ))) {
- fprintf(stderr, "%s: Trouble building message header, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- }
-
- if((error = pfkey_sa_build(&extensions[!j ? SADB_EXT_SA : SADB_X_EXT_SA2],
- !j ? SADB_EXT_SA : SADB_X_EXT_SA2,
- said_af_array[i+j].said.spi, /* in network order */
- 0,
- 0,
- 0,
- 0,
- 0))) {
- fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
-
-#if 0
- if(!j) {
- anyaddr(said_af_array[i].af, &pfkey_address_s_ska); /* Is the address family correct ?? */
- if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
- SADB_EXT_ADDRESS_SRC,
- 0,
- 0,
- sockaddrof(&pfkey_address_s_ska)))) {
- addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n",
- program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
- }
-#endif
- if((error = pfkey_address_build(&extensions[!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2],
- !j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2,
- 0,
- 0,
- sockaddrof(&said_af_array[i+j].said.dst)))) {
- addrtot(&said_af_array[i+j].said.dst,
- 0, ipaddr_txt, sizeof(ipaddr_txt));
- fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n",
- program_name, ipaddr_txt, error);
- pfkey_extensions_free(extensions);
- exit(1);
- }
-
- }
-
- if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) {
- fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n",
- program_name, error);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- exit(1);
- }
-
- if((error = write(pfkey_sock,
- pfkey_msg,
- pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) !=
- (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) {
- fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n",
- program_name, error, errno);
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- switch(errno) {
- case EACCES:
- fprintf(stderr, "access denied. ");
- if(getuid() == 0) {
- fprintf(stderr, "Check permissions. Should be 600.\n");
- } else {
- fprintf(stderr, "You must be root to open this file.\n");
- }
- break;
- case EUNATCH:
- fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
- break;
- case EBUSY:
- fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n");
- break;
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "KLIPS not loaded or enabled.\n");
- fprintf(stderr, "No device?!?\n");
- break;
- case ENOBUFS:
- fprintf(stderr, "No kernel memory to allocate SA.\n");
- break;
- case ESOCKTNOSUPPORT:
- fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n");
- break;
- case EEXIST:
- fprintf(stderr, "SA already in use. Delete old one first.\n");
- break;
- case ENOENT:
- fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n");
- break;
- case ENXIO:
- fprintf(stderr, "SA does not exist. Cannot delete.\n");
- break;
- case ENOSPC:
- fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n");
- break;
- case ESPIPE:
- fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno);
- }
- exit(1);
- }
- if(pfkey_msg) {
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- }
- }
-
- (void) close(pfkey_sock); /* close the socket */
- exit(0);
-}
diff --git a/programs/starter/Makefile b/programs/starter/Makefile
deleted file mode 100644
index 60e95d360..000000000
--- a/programs/starter/Makefile
+++ /dev/null
@@ -1,182 +0,0 @@
-# ipsec starter Makefile
-# Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.14 2006/02/17 19:34:02 as Exp $
-
-FREESWANSRCDIR?=$(shell cd ../..; pwd)
-include ${FREESWANSRCDIR}/Makefile.inc
-
-LD=$(CC)
-RM=rm
-LEX=flex
-BISON=bison
-GPERF=gperf
-
-FREESWANDIR=../..
-FREESWANLIB=$(FREESWANDIR)/lib/libfreeswan/libfreeswan.a
-PLUTODIR=../pluto
-OPENACDIR=../openac
-
-DEFINES+= -DVIRTUAL_IP -DDEBUG
-
-# This compile option activates the leak detective
-ifeq ($(USE_LEAK_DETECTIVE),true)
- DEFINES+= -DLEAK_DETECTIVE
-endif
-
-INCLUDES=-I${FREESWANDIR}/linux/include
-CFLAGS=$(DEFINES) $(INCLUDES) -Wall
-CFLAGS+=-DIPSEC_EXECDIR=\"${FINALLIBEXECDIR}\" -DIPSEC_CONFDDIR=\"${FINALCONFDDIR}\"
-CFLAGS+=-DIPSEC_CONFDIR=\"${FINALCONFDIR}\"
-LDFLAGS=
-
-PLUTO_OBJS=defs.o
-
-OBJS=starter.o parser.tab.o lex.yy.o keywords.o args.o invokepluto.o \
- starterwhack.o klips.o netkey.o interfaces.o exec.o cmp.o confread.o \
- loglite.o ${PLUTO_OBJS}
-
-DISTSRC=$(OBJS:.o=.c)
-DISTSRC+=cmp.h confread.h confwrite.h exec.h files.h interfaces.h klips.h netkey.h
-DISTSRC+=parser.h args.h invokepluto.h starterwhack.h keywords.h keywords.txt
-
-LIBS=$(FREESWANLIB)
-
-PROGRAM=starter
-
-include ../Makefile.program
-
-all: starter
-
-starter: $(OBJS) $(FREESWANLIB)
- $(LD) $(LDFLAGS) -o starter $(OBJS) $(LIBS)
-
-lex.yy.c: parser.tab.c parser.l parser.y parser.h
- $(LEX) parser.l
-
-parser.tab.c: parser.l parser.y parser.h
- $(BISON) -v -d parser.y
-
-keywords.c: keywords.txt keywords.h
- $(GPERF) -C -G -t < keywords.txt > keywords.c
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-loglite.o : $(OPENACDIR)/loglite.c $(PLUTODIR)/log.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-# pluto library
-
-defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
- $(CC) $(CFLAGS) -c -o $@ $<
-
-clean::
- $(RM) -f starter $(OBJS) parser.tab.* lex.yy.*
-
-# Stolen from pluto/Makefile
-
-gatherdeps:
- @ls | grep '\.c$$' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
- @echo
- @ls | grep '\.c$$' | xargs grep '^#[ ]*include[ ]*"' | \
- sed -e 's/\.c:#[ ]*include[ ]*"/.o: /' -e 's/".*//'
-
-# Dependencies generated by "make gatherdeps":
-
-args.o: args.c
-cmp.o: cmp.c
-confread.o: confread.c
-exec.o: exec.c
-interfaces.o: interfaces.c
-invokepluto.o: invokepluto.c
-keywords.o: keywords.c
-klips.o: klips.c
-lex.yy.o: lex.yy.c
-netkey.o: netkey.c
-parser.tab.o: parser.tab.c
-starter.o: starter.c
-starterwhack.o: starterwhack.c
-
-args.o: ../pluto/constants.h
-args.o: ../pluto/defs.h
-args.o: ../pluto/log.h
-args.o: keywords.h
-args.o: parser.h
-args.o: confread.h
-args.o: args.h
-cmp.o: ../pluto/constants.h
-cmp.o: ../pluto/defs.h
-cmp.o: confread.h
-cmp.o: args.h
-cmp.o: interfaces.h
-cmp.o: cmp.h
-confread.o: ../pluto/constants.h
-confread.o: ../pluto/defs.h
-confread.o: ../pluto/log.h
-confread.o: keywords.h
-confread.o: parser.h
-confread.o: confread.h
-confread.o: args.h
-confread.o: interfaces.h
-exec.o: ../pluto/constants.h
-exec.o: ../pluto/defs.h
-exec.o: ../pluto/log.h
-exec.o: exec.h
-interfaces.o: ../pluto/constants.h
-interfaces.o: ../pluto/defs.h
-interfaces.o: ../pluto/log.h
-interfaces.o: interfaces.h
-interfaces.o: exec.h
-interfaces.o: files.h
-invokepluto.o: ../pluto/constants.h
-invokepluto.o: ../pluto/defs.h
-invokepluto.o: ../pluto/log.h
-invokepluto.o: confread.h
-invokepluto.o: invokepluto.h
-invokepluto.o: files.h
-invokepluto.o: starterwhack.h
-keywords.o: keywords.h
-klips.o: ../pluto/constants.h
-klips.o: ../pluto/defs.h
-klips.o: ../pluto/log.h
-klips.o: confread.h
-klips.o: klips.h
-klips.o: files.h
-klips.o: exec.h
-lex.yy.o: parser.tab.h
-netkey.o: ../pluto/constants.h
-netkey.o: ../pluto/defs.h
-netkey.o: ../pluto/log.h
-netkey.o: files.h
-parser.tab.o: ../pluto/constants.h
-parser.tab.o: ../pluto/defs.h
-parser.tab.o: parser.h
-starter.o: ../pluto/constants.h
-starter.o: ../pluto/defs.h
-starter.o: ../pluto/log.h
-starter.o: confread.h
-starter.o: files.h
-starter.o: starterwhack.h
-starter.o: invokepluto.h
-starter.o: klips.h
-starter.o: netkey.h
-starter.o: cmp.h
-starter.o: interfaces.h
-starterwhack.o: ../pluto/constants.h
-starterwhack.o: ../pluto/defs.h
-starterwhack.o: ../pluto/log.h
-starterwhack.o: ../pluto/whack.h
-starterwhack.o: starterwhack.h
-starterwhack.o: confread.h
-starterwhack.o: files.h
diff --git a/programs/starter/README b/programs/starter/README
deleted file mode 100644
index 12a60a11d..000000000
--- a/programs/starter/README
+++ /dev/null
@@ -1,104 +0,0 @@
-
-IPsec Starter -- Version 0.2 [Contributed by Arkoon Network Security]
-============================ [ http://www.arkoon.net/]
-
-IPsec Starter is aimed to replace all the scripts which are used to
-start and stop strongSwan and to do that in a quicker and a smarter way.
-
-IPsec Starter can also reload the configuration file (kill --HUP or periodicaly)
-and apply the changes.
-
-Usage:
- starter [--debug] [--auto_update <x seconds>]
- --debug: enable debugging output
- --no_fork: all msg (including pluto) are sent to the console
- --auto_update: reload the config file (like kill -HUP) every x seconds
- and determine any configuration changes
-
-FEATURES
---------
-
-o Load and unload KLIPS (ipsec.o kernel module)
-
-o Load modules of the native Linux 2.6 IPsec stack
-
-o Launch and monitor pluto
-
-o Add, initiate, route and del connections
-
-o Attach and detach interfaces according to config file
-
-o kill -HUP can be used to reload the config file. New connections will be
- added, old ones will be removed and modified ones will be reloaded.
- Interfaces/Klips/Pluto will be reloaded if necessary.
-
-o Full support of the %defaultroute wildcard parameter.
-
-o save own pid in /var/run/starter
-
-o Upon reloading, dynamic DNS addr will be resolved and reloaded. Use
- --auto_update to periodicaly check dynamic DNS changes.
-
-o kill -USR1 can be used to reload all connections (delete then add and
- route/initiate)
-
-o /var/run/dynip/xxxx can be used to use a virtual interface name in
- ipsec.conf. By example, when adsl can be ppp0, ppp1, ... :
- ipsec.conf: interfaces="ipsec0=adsl"
- And use /etc/ppp/ip-up to create /var/run/dynip/adsl
- /var/run/dynip/adsl: IP_PHYS=ppp0
-
-o %auto can be used to automaticaly name the connections
-
-o kill -TERM can be used to stop FS. pluto will be stopped and KLIPS unloaded
- (if it has been loaded).
-
-o Can be used to start strongSwan and load lots of connections in a few
- seconds.
-
-TODO
-----
-
-o handle wildcards in include lines -- use glob() fct
- ex: include /etc/ipsec.*.conf
-
-o handle duplicates keywords and sections
-
-o 'also' keyword not supported
-
-o manually keyed connections
-
-o IPv6
-
-o Documentation
-
-
-CHANGES
--------
-
-o Version 0.1 -- 2002.01.14 -- First public release
-
-o Version 0.2 -- 2002.09.04 -- Various enhancements
- FreeS/WAN 1.98b, x509 0.9.14, algo 0.8.0
-
-o Version 0.2d -- 2004.01.13 -- Adaptions for Openswan 1.0.0
- by Stephan Scholz <sscholz@astaro.com>
-
-o Version 0.2e -- 2004.10.14 -- Added support for change of interface address
- by Stephan Scholz <sscholz@astaro.com>
-
-o Version 0.2s -- 2005-12-02 -- Ported to strongSwan
- by Stephan Scholz <sscholz@astaro.com>
-
-o Version 0.2x -- 2006-01-02 -- Added missing strongSwan keywords
- Full support of the native Linux 2.6 IPsec stack
- Full support of %defaultroute
- Improved parsing of keywords using perfect hash
- function generated by gperf.
- by Andreas Steffen <andreas.steffen@hsr.ch>
-
-THANKS
-------
-
-o Nathan Angelacos - include fix
-
diff --git a/programs/starter/args.c b/programs/starter/args.c
deleted file mode 100644
index 9dece2dfb..000000000
--- a/programs/starter/args.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/* automatic handling of confread struct arguments
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: args.c,v 1.11 2007/01/11 21:27:27 as Exp $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "keywords.h"
-#include "parser.h"
-#include "confread.h"
-#include "args.h"
-
-/* argument types */
-
-typedef enum {
- ARG_NONE,
- ARG_ENUM,
- ARG_UINT,
- ARG_TIME,
- ARG_ULNG,
- ARG_PCNT,
- ARG_STR,
- ARG_LST,
- ARG_MISC
-} arg_t;
-
-/* various keyword lists */
-
-static const char *LST_bool[] = {
- "no",
- "yes",
- NULL
-};
-
-static const char *LST_sendcert[] = {
- "always",
- "ifasked",
- "never",
- "yes",
- "no",
- NULL
-};
-
-static const char *LST_dpd_action[] = {
- "none",
- "clear",
- "hold",
- "restart",
- NULL
-};
-
-static const char *LST_startup[] = {
- "ignore",
- "add",
- "route",
- "start",
- NULL
-};
-
-static const char *LST_packetdefault[] = {
- "drop",
- "reject",
- "pass",
- NULL
-};
-
-static const char *LST_keyexchange[] = {
- "ike",
- NULL
-};
-
-static const char *LST_pfsgroup[] = {
- "modp1024",
- "modp1536",
- "modp2048",
- "modp3072",
- "modp4096",
- "modp6144",
- "modp8192",
- NULL
-};
-
-static const char *LST_plutodebug[] = {
- "none",
- "all",
- "raw",
- "crypt",
- "parsing",
- "emitting",
- "control",
- "lifecycle",
- "klips",
- "dns",
- "natt",
- "oppo",
- "controlmore",
- "private",
- NULL
-};
-
-static const char *LST_klipsdebug[] = {
- "tunnel",
- "tunnel-xmit",
- "pfkey",
- "xform",
- "eroute",
- "spi",
- "radij",
- "esp",
- "ah",
- "ipcomp",
- "verbose",
- "all",
- "none",
- NULL
-};
-
-typedef struct {
- arg_t type;
- size_t offset;
- const char **list;
-} token_info_t;
-
-static const token_info_t token_info[] =
-{
- /* config setup keywords */
- { ARG_LST, offsetof(starter_config_t, setup.interfaces), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.dumpdir), NULL },
-
- /* pluto keywords */
- { ARG_LST, offsetof(starter_config_t, setup.plutodebug), LST_plutodebug },
- { ARG_STR, offsetof(starter_config_t, setup.prepluto), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.postpluto), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_bool },
- { ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
- { ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
- { ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.virtual_private), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.pkcs11module), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11keepstate), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11proxy), LST_bool },
-
- /* KLIPS keywords */
- { ARG_LST, offsetof(starter_config_t, setup.klipsdebug), LST_klipsdebug },
- { ARG_ENUM, offsetof(starter_config_t, setup.fragicmp), LST_bool },
- { ARG_STR, offsetof(starter_config_t, setup.packetdefault), LST_packetdefault },
- { ARG_ENUM, offsetof(starter_config_t, setup.hidetos), LST_bool },
-
- /* conn section keywords */
- { ARG_STR, offsetof(starter_conn_t, name), NULL },
- { ARG_ENUM, offsetof(starter_conn_t, startup), LST_startup },
- { ARG_ENUM, offsetof(starter_conn_t, keyexchange), LST_keyexchange },
- { ARG_MISC, 0, NULL /* KW_TYPE */ },
- { ARG_MISC, 0, NULL /* KW_PFS */ },
- { ARG_MISC, 0, NULL /* KW_COMPRESS */ },
- { ARG_MISC, 0, NULL /* KW_AUTH */ },
- { ARG_MISC, 0, NULL /* KW_AUTHBY */ },
- { ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL },
- { ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL },
- { ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL },
- { ARG_ULNG, offsetof(starter_conn_t, sa_keying_tries), NULL },
- { ARG_PCNT, offsetof(starter_conn_t, sa_rekey_fuzz), NULL },
- { ARG_MISC, 0, NULL /* KW_REKEY */ },
- { ARG_STR, offsetof(starter_conn_t, ike), NULL },
- { ARG_STR, offsetof(starter_conn_t, esp), NULL },
- { ARG_STR, offsetof(starter_conn_t, pfsgroup), LST_pfsgroup },
- { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
- { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
- { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
- { ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
- { ARG_MISC, 0, NULL /* KW_XAUTH */ },
-
- /* ca section keywords */
- { ARG_STR, offsetof(starter_ca_t, name), NULL },
- { ARG_ENUM, offsetof(starter_ca_t, startup), LST_startup },
- { ARG_STR, offsetof(starter_ca_t, cacert), NULL },
- { ARG_STR, offsetof(starter_ca_t, ldaphost), NULL },
- { ARG_STR, offsetof(starter_ca_t, ldapbase), NULL },
- { ARG_STR, offsetof(starter_ca_t, crluri), NULL },
- { ARG_STR, offsetof(starter_ca_t, crluri2), NULL },
- { ARG_STR, offsetof(starter_ca_t, ocspuri), NULL },
-
- /* end keywords */
- { ARG_MISC, 0, NULL /* KW_HOST */ },
- { ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
- { ARG_MISC, 0, NULL /* KW_SUBNET */ },
- { ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
- { ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
- { ARG_MISC, 0, NULL /* KW_SOURCEIP */ },
- { ARG_MISC, 0, NULL /* KW_NATIP */ },
- { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
- { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
- { ARG_STR, offsetof(starter_end_t, updown), NULL },
- { ARG_STR, offsetof(starter_end_t, id), NULL },
- { ARG_STR, offsetof(starter_end_t, rsakey), NULL },
- { ARG_STR, offsetof(starter_end_t, cert), NULL },
- { ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert },
- { ARG_STR, offsetof(starter_end_t, ca), NULL },
- { ARG_STR, offsetof(starter_end_t, groups), NULL },
- { ARG_STR, offsetof(starter_end_t, iface), NULL }
-};
-
-static void
-free_list(char **list)
-{
- char **s;
-
- for (s = list; *s; s++)
- pfree(*s);
- pfree(list);
-}
-
-char **
-new_list(char *value)
-{
- char *val, *b, *e, *end, **ret;
- int count;
-
- val = value ? clone_str(value, "list value") : NULL;
- if (!val)
- return NULL;
- end = val + strlen(val);
- for (b = val, count = 0; b < end;)
- {
- for (e = b; ((*e != ' ') && (*e != '\0')); e++);
- *e = '\0';
- if (e != b)
- count++;
- b = e + 1;
- }
- if (count == 0)
- {
- pfree(val);
- return NULL;
- }
- ret = (char **)alloc_bytes((count+1) * sizeof(char *), "list");
-
- for (b = val, count = 0; b < end; )
- {
- for (e = b; (*e != '\0'); e++);
- if (e != b)
- ret[count++] = clone_str(b, "list value");
- b = e + 1;
- }
- ret[count] = NULL;
- pfree(val);
- return ret;
-}
-
-
-/*
- * assigns an argument value to a struct field
- */
-bool
-assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw, char *base
- , bool *assigned)
-{
- char *p = base + token_info[token].offset;
- const char **list = token_info[token].list;
-
- int index = -1; /* used for enumeration arguments */
-
- lset_t *seen = (lset_t *)base; /* seen flags are at the top of the struct */
- lset_t f = LELEM(token - first); /* compute flag position of argument */
-
- *assigned = FALSE;
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" %s=%s", kw->entry->name, kw->value)
- )
-
- if (*seen & f)
- {
- plog("# duplicate '%s' option", kw->entry->name);
- return FALSE;
- }
-
- /* set flag that this argument has been seen */
- *seen |= f;
-
- /* is there a keyword list? */
- if (list != NULL && token_info[token].type != ARG_LST)
- {
- bool match = FALSE;
-
- while (*list != NULL && !match)
- {
- index++;
- match = streq(kw->value, *list++);
- }
- if (!match)
- {
- plog("# bad value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
-
- switch (token_info[token].type)
- {
- case ARG_NONE:
- plog("# option '%s' not supported yet", kw->entry->name);
- return FALSE;
- case ARG_ENUM:
- {
- int *i = (int *)p;
-
- if (index < 0)
- {
- plog("# bad enumeration value: %s=%s (%d)"
- , kw->entry->name, kw->value, index);
- return FALSE;
- }
- *i = index;
- }
- break;
-
- case ARG_UINT:
- {
- char *endptr;
- u_int *u = (u_int *)p;
-
- *u = strtoul(kw->value, &endptr, 10);
-
- if (*endptr != '\0')
- {
- plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
- break;
- case ARG_ULNG:
- case ARG_PCNT:
- {
- char *endptr;
- unsigned long *l = (unsigned long *)p;
-
- *l = strtoul(kw->value, &endptr, 10);
-
- if (token_info[token].type == ARG_ULNG)
- {
- if (*endptr != '\0')
- {
- plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
- else
- {
- if ((*endptr != '%') || (endptr[1] != '\0') || endptr == kw->value)
- {
- plog("# bad percent value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
-
- }
- break;
- case ARG_TIME:
- {
- char *endptr;
- time_t *t = (time_t *)p;
-
- *t = strtoul(kw->value, &endptr, 10);
-
- /* time in seconds? */
- if (*endptr == '\0' || (*endptr == 's' && endptr[1] == '\0'))
- break;
-
- if (endptr[1] == '\0')
- {
- if (*endptr == 'm') /* time in minutes? */
- {
- *t *= 60;
- break;
- }
- if (*endptr == 'h') /* time in hours? */
- {
- *t *= 3600;
- break;
- }
- if (*endptr == 'd') /* time in days? */
- {
- *t *= 3600*24;
- break;
- }
- }
- plog("# bad duration value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- case ARG_STR:
- {
- char **cp = (char **)p;
-
- /* free any existing string */
- pfreeany(*cp);
-
- /* assign the new string */
- *cp = clone_str(kw->value, "str_value");
- }
- break;
- case ARG_LST:
- {
- char ***listp = (char ***)p;
-
- /* free any existing list */
- if (*listp != NULL)
- free_list(*listp);
-
- /* create a new list and assign values */
- *listp = new_list(kw->value);
-
- /* is there a keyword list? */
- if (list != NULL)
- {
- char ** lst;
-
- for (lst = *listp; lst && *lst; lst++)
- {
- bool match = FALSE;
-
- list = token_info[token].list;
-
- while (*list != NULL && !match)
- {
- match = streq(*lst, *list++);
- }
- if (!match)
- {
- plog("# bad value: %s=%s", kw->entry->name, *lst);
- return FALSE;
- }
- }
- }
- }
- default:
- return TRUE;
- }
-
- *assigned = TRUE;
- return TRUE;
-}
-
-/*
- * frees all dynamically allocated arguments in a struct
- */
-void
-free_args(kw_token_t first, kw_token_t last, char *base)
-{
- kw_token_t token;
-
- for (token = first; token <= last; token++)
- {
- char *p = base + token_info[token].offset;
-
- switch (token_info[token].type)
- {
- case ARG_STR:
- {
- char **cp = (char **)p;
-
- pfreeany(*cp);
- *cp = NULL;
- }
- break;
- case ARG_LST:
- {
- char ***listp = (char ***)p;
-
- if (*listp != NULL)
- {
- free_list(*listp);
- *listp = NULL;
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
-/*
- * clone all dynamically allocated arguments in a struct
- */
-void
-clone_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
-{
- kw_token_t token;
-
- for (token = first; token <= last; token++)
- {
- if (token_info[token].type == ARG_STR)
- {
- char **cp1 = (char **)(base1 + token_info[token].offset);
- char **cp2 = (char **)(base2 + token_info[token].offset);
-
- *cp1 = clone_str(*cp2, "cloned str");
- }
- }
-}
-
-static bool
-cmp_list(char **list1, char **list2)
-{
- if ((list1 == NULL) && (list2 == NULL))
- return TRUE;
- if ((list1 == NULL) || (list2 == NULL))
- return FALSE;
-
- for ( ; *list1 && *list2; list1++, list2++)
- {
- if (strcmp(*list1,*list2) != 0)
- return FALSE;
- }
-
- if ((*list1 != NULL) || (*list2 != NULL))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * compare all arguments in a struct
- */
-bool
-cmp_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
-{
- kw_token_t token;
-
- for (token = first; token <= last; token++)
- {
- char *p1 = base1 + token_info[token].offset;
- char *p2 = base2 + token_info[token].offset;
-
- switch (token_info[token].type)
- {
- case ARG_ENUM:
- {
- int *i1 = (int *)p1;
- int *i2 = (int *)p2;
-
- if (*i1 != *i2)
- return FALSE;
- }
- break;
- case ARG_UINT:
- {
- u_int *u1 = (u_int *)p1;
- u_int *u2 = (u_int *)p2;
-
- if (*u1 != *u2)
- return FALSE;
- }
- break;
- case ARG_ULNG:
- case ARG_PCNT:
- {
- unsigned long *l1 = (unsigned long *)p1;
- unsigned long *l2 = (unsigned long *)p2;
-
- if (*l1 != *l2)
- return FALSE;
- }
- break;
- case ARG_TIME:
- {
- time_t *t1 = (time_t *)p1;
- time_t *t2 = (time_t *)p2;
-
- if (*t1 != *t2)
- return FALSE;
- }
- break;
- case ARG_STR:
- {
- char **cp1 = (char **)p1;
- char **cp2 = (char **)p2;
-
- if (*cp1 == NULL && *cp2 == NULL)
- break;
- if (*cp1 == NULL || *cp2 == NULL || strcmp(*cp1, *cp2) != 0)
- return FALSE;
- }
- break;
- case ARG_LST:
- {
- char ***listp1 = (char ***)p1;
- char ***listp2 = (char ***)p2;
-
- if (!cmp_list(*listp1, *listp2))
- return FALSE;
- }
- break;
- default:
- break;
- }
- }
- return TRUE;
-}
diff --git a/programs/starter/args.h b/programs/starter/args.h
deleted file mode 100644
index 302e9bb7b..000000000
--- a/programs/starter/args.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* automatic handling of confread struct arguments
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: args.h,v 1.3 2006/01/13 18:02:02 as Exp $
- */
-
-#ifndef _ARGS_H_
-#define _ARGS_H_
-
-#include "keywords.h"
-#include "parser.h"
-
-extern char **new_list(char *value);
-extern bool assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw
- , char *base, bool *assigned);
-extern void free_args(kw_token_t first, kw_token_t last, char *base);
-extern void clone_args(kw_token_t first, kw_token_t last, char *base1
- , char *base2);
-extern bool cmp_args(kw_token_t first, kw_token_t last, char *base1
- , char *base2);
-
-#endif /* _ARGS_H_ */
-
diff --git a/programs/starter/cmp.c b/programs/starter/cmp.c
deleted file mode 100644
index 9222bf58f..000000000
--- a/programs/starter/cmp.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* strongSwan IPsec starter comparison functions
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: cmp.c,v 1.12 2006/01/13 18:03:25 as Exp $
- */
-
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-
-#include "confread.h"
-#include "args.h"
-#include "interfaces.h"
-#include "cmp.h"
-
-#define VARCMP(obj) if (c1->obj != c2->obj) return FALSE
-#define ADDCMP(obj) if (!sameaddr(&c1->obj,&c2->obj)) return FALSE
-#define SUBCMP(obj) if (!samesubnet(&c1->obj,&c2->obj)) return FALSE
-
-static bool
-starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
-{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
-
- ADDCMP(addr);
- ADDCMP(nexthop);
- ADDCMP(srcip);
- SUBCMP(subnet);
- VARCMP(has_client);
- VARCMP(has_client_wildcard);
- VARCMP(has_port_wildcard);
- VARCMP(has_srcip);
- VARCMP(modecfg);
- VARCMP(port);
- VARCMP(protocol);
-
- return cmp_args(KW_END_FIRST, KW_END_LAST, (char *)c1, (char *)c2);
- }
-
-bool
-starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2)
-{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
-
- VARCMP(policy);
- VARCMP(addr_family);
- VARCMP(tunnel_addr_family);
-
- if (!starter_cmp_end(&c1->left, &c2->left))
- return FALSE;
- if (!starter_cmp_end(&c1->right, &c2->right))
- return FALSE;
-
- return cmp_args(KW_CONN_NAME, KW_CONN_LAST, (char *)c1, (char *)c2);
-}
-
-bool
-starter_cmp_ca(starter_ca_t *c1, starter_ca_t *c2)
-{
- if (c1 == NULL || c2 == NULL)
- return FALSE;
-
- return cmp_args(KW_CA_NAME, KW_CA_LAST, (char *)c1, (char *)c2);
-}
-
-bool
-starter_cmp_klips(starter_config_t *c1, starter_config_t *c2)
-{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
-
- return cmp_args(KW_KLIPS_FIRST, KW_KLIPS_LAST, (char *)c1, (char *)c2);
-}
-
-bool
-starter_cmp_pluto(starter_config_t *c1, starter_config_t *c2)
-{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
-
- return cmp_args(KW_PLUTO_FIRST, KW_PLUTO_LAST, (char *)c1, (char *)c2);
-}
-
-bool
-starter_cmp_defaultroute(defaultroute_t *d1, defaultroute_t *d2)
-{
- if ((d1 == NULL) || (d2 == NULL))
- return FALSE;
- return memcmp(d1, d2, sizeof(defaultroute_t)) == 0;
-}
diff --git a/programs/starter/cmp.h b/programs/starter/cmp.h
deleted file mode 100644
index ca355e9eb..000000000
--- a/programs/starter/cmp.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* strongSwan IPsec starter comparison functions
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: cmp.h,v 1.4 2006/01/06 20:24:41 as Exp $
- */
-
-#ifndef _STARTER_CMP_H_
-#define _STARTER_CMP_H_
-
-#include "interfaces.h"
-
-extern bool starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2);
-extern bool starter_cmp_ca(starter_ca_t *c1, starter_ca_t *c2);
-extern bool starter_cmp_klips(starter_config_t *c1, starter_config_t *c2);
-extern bool starter_cmp_pluto(starter_config_t *c1, starter_config_t *c2);
-extern bool starter_cmp_defaultroute(defaultroute_t *d1, defaultroute_t *d2);
-
-#endif
-
diff --git a/programs/starter/confread.c b/programs/starter/confread.c
deleted file mode 100644
index 63010685b..000000000
--- a/programs/starter/confread.c
+++ /dev/null
@@ -1,908 +0,0 @@
-/* strongSwan IPsec config file parser
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: confread.c,v 1.40 2007/01/11 21:27:27 as Exp $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "keywords.h"
-#include "parser.h"
-#include "confread.h"
-#include "args.h"
-#include "interfaces.h"
-
-/* strings containing a colon are interpreted as an IPv6 address */
-#define ip_version(string) (strchr(string, ':') != NULL)? AF_INET6 : AF_INET;
-
-static const char ike_defaults[] = "3des-sha, 3des-md5";
-static const char esp_defaults[] = "3des-sha1, 3des-md5";
-
-static const char firewall_defaults[] = "ipsec _updown iptables";
-
-static void
-default_values(starter_config_t *cfg)
-{
- if (cfg == NULL)
- return;
-
- memset(cfg, 0, sizeof(struct starter_config));
-
- /* is there enough space for all seen flags? */
- assert(KW_SETUP_LAST - KW_SETUP_FIRST <
- sizeof(cfg->setup.seen) * BITS_PER_BYTE);
- assert(KW_CONN_LAST - KW_CONN_FIRST <
- sizeof(cfg->conn_default.seen) * BITS_PER_BYTE);
- assert(KW_END_LAST - KW_END_FIRST <
- sizeof(cfg->conn_default.right.seen) * BITS_PER_BYTE);
- assert(KW_CA_LAST - KW_CA_FIRST <
- sizeof(cfg->ca_default.seen) * BITS_PER_BYTE);
-
- cfg->setup.seen = LEMPTY;
- cfg->setup.fragicmp = TRUE;
- cfg->setup.hidetos = TRUE;
- cfg->setup.uniqueids = TRUE;
- cfg->setup.interfaces = new_list("%defaultroute");
-
- cfg->conn_default.seen = LEMPTY;
- cfg->conn_default.startup = STARTUP_NO;
- cfg->conn_default.state = STATE_IGNORE;
- cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_RSASIG
- | POLICY_PFS;
-
- cfg->conn_default.ike = clone_str(ike_defaults, "ike_defaults");
- cfg->conn_default.esp = clone_str(esp_defaults, "esp_defaults");
- cfg->conn_default.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
- cfg->conn_default.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
- cfg->conn_default.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
- cfg->conn_default.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
- cfg->conn_default.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
- cfg->conn_default.addr_family = AF_INET;
- cfg->conn_default.tunnel_addr_family = AF_INET;
-
- cfg->conn_default.left.seen = LEMPTY;
- cfg->conn_default.right.seen = LEMPTY;
-
- anyaddr(AF_INET, &cfg->conn_default.left.addr);
- anyaddr(AF_INET, &cfg->conn_default.left.nexthop);
- anyaddr(AF_INET, &cfg->conn_default.left.srcip);
- anyaddr(AF_INET, &cfg->conn_default.right.addr);
- anyaddr(AF_INET, &cfg->conn_default.right.nexthop);
- anyaddr(AF_INET, &cfg->conn_default.right.srcip);
-
- cfg->ca_default.seen = LEMPTY;
-}
-
-#define KW_POLICY_FLAG(sy, sn, fl) \
- if (streq(kw->value, sy)) { conn->policy |= fl; } \
- else if (streq(kw->value, sn)) { conn->policy &= ~fl; } \
- else { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; }
-
-static void
-load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
-{
- kw_list_t *kw;
-
- DBG(DBG_CONTROL,
- DBG_log("Loading config setup")
- )
-
- for (kw = cfgp->config_setup; kw; kw = kw->next)
- {
- bool assigned = FALSE;
-
- kw_token_t token = kw->entry->token;
-
- if (token < KW_SETUP_FIRST || token > KW_SETUP_LAST)
- {
- plog("# unsupported keyword '%s' in config setup", kw->entry->name);
- cfg->err++;
- continue;
- }
-
- if (!assign_arg(token, KW_SETUP_FIRST, kw, (char *)cfg, &assigned))
- {
- plog(" bad argument value in config setup");
- cfg->err++;
- continue;
- }
- }
-}
-
-static void
-kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
- , kw_list_t *kw, char *conn_name, starter_config_t *cfg)
-{
- err_t ugh = NULL;
- bool assigned = FALSE;
- int has_port_wildcard; /* set if port is %any */
-
- char *name = kw->entry->name;
- char *value = kw->value;
-
- if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned))
- goto err;
-
- if (token == KW_SENDCERT)
- {
- if (end->sendcert == CERT_YES_SEND)
- end->sendcert = CERT_ALWAYS_SEND;
- else if (end->sendcert == CERT_NO_SEND)
- end->sendcert = CERT_NEVER_SEND;
- }
-
- if (assigned)
- return;
-
- switch (token)
- {
- case KW_HOST:
- if (streq(value, "%defaultroute"))
- {
- if (cfg->defaultroute.defined)
- {
- end->addr = cfg->defaultroute.addr;
- end->nexthop = cfg->defaultroute.nexthop;
- }
- else
- {
- plog("# default route not known: %s=%s", name, value);
- goto err;
- }
- }
- else if (streq(value, "%any"))
- {
- anyaddr(conn->addr_family, &end->addr);
- }
- else if (streq(value, "%any6"))
- {
- conn->addr_family = AF_INET6;
- anyaddr(conn->addr_family, &end->addr);
- }
- else if (value[0] == '%')
- {
- if (end->iface)
- pfree(end->iface);
- end->iface = clone_str(value+1, "iface");
- if (starter_iface_find(end->iface, conn->addr_family, &end->addr,
- &end->nexthop) == -1)
- {
- conn->state = STATE_INVALID;
- }
- }
- else
- {
- conn->addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- }
- break;
- case KW_NEXTHOP:
- if (streq(value, "%defaultroute"))
- {
- if (cfg->defaultroute.defined)
- end->nexthop = cfg->defaultroute.nexthop;
- else
- {
- plog("# default route not known: %s=%s", name, value);
- goto err;
- }
- }
- else if (streq(value, "%direct"))
- {
- ugh = anyaddr(conn->addr_family, &end->nexthop);
- }
- else
- {
- conn->addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->addr_family, &end->nexthop);
- }
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- break;
- case KW_SUBNET:
- if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
- || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
- {
- end->virt = clone_str(value, "virt");
- }
- else
- {
- end->has_client = TRUE;
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
- if (ugh != NULL)
- {
- plog("# bad subnet: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- }
- break;
- case KW_SUBNETWITHIN:
- end->has_client = TRUE;
- end->has_client_wildcard = TRUE;
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
- break;
- case KW_PROTOPORT:
- ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
- end->has_port_wildcard = has_port_wildcard;
- break;
- case KW_SOURCEIP:
- if (end->has_natip)
- {
- plog("# natip and sourceip cannot be defined at the same time");
- goto err;
- }
- if (streq(value, "%modeconfig") || streq(value, "%modecfg"))
- {
- end->modecfg = TRUE;
- }
- else
- {
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip);
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- end->has_srcip = TRUE;
- }
- conn->policy |= POLICY_TUNNEL;
- break;
- case KW_NATIP:
- if (end->has_srcip)
- {
- plog("# natip and sourceip cannot be defined at the same time");
- goto err;
- }
- conn->tunnel_addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &end->srcip);
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- goto err;
- }
- end->has_natip = TRUE;
- conn->policy |= POLICY_TUNNEL;
- break;
- default:
- break;
- }
- return;
-
-err:
- plog(" bad argument value in conn '%s'", conn_name);
- cfg->err++;
-}
-
-/*
- * handles left|rightfirewall and left|rightupdown parameters
- */
-static void
-handle_firewall( const char *label, starter_end_t *end, starter_config_t *cfg)
-{
- if (end->firewall && (end->seen & LELEM(KW_FIREWALL - KW_END_FIRST)))
- {
- if (end->updown != NULL)
- {
- plog("# cannot have both %sfirewall and %supdown", label, label);
- cfg->err++;
- }
- else
- {
- end->updown = clone_str(firewall_defaults, "firewall_defaults");
- end->firewall = FALSE;
- }
- }
-}
-
-/*
- * parse a conn section
- */
-static void
-load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
-{
- char *conn_name = (conn->name == NULL)? "%default":conn->name;
-
- for ( ; kw; kw = kw->next)
- {
- bool assigned = FALSE;
-
- kw_token_t token = kw->entry->token;
-
- if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
- {
- kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST
- , kw, conn_name, cfg);
- continue;
- }
- else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
- {
- kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST
- , kw, conn_name, cfg);
- continue;
- }
-
- if (token == KW_AUTO)
- {
- token = KW_CONN_SETUP;
- }
- else if (token == KW_ALSO)
- {
- if (cfg->parse_also)
- {
- also_t *also = alloc_thing(also_t, "also_t");
-
- also->name = clone_str(kw->value, "also");
- also->next = conn->also;
- conn->also = also;
-
- DBG(DBG_CONTROL,
- DBG_log(" also=%s", kw->value)
- )
- }
- continue;
- }
-
- if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
- {
- plog("# unsupported keyword '%s' in conn '%s'"
- , kw->entry->name, conn_name);
- cfg->err++;
- continue;
- }
-
- if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned))
- {
- plog(" bad argument value in conn '%s'", conn_name);
- cfg->err++;
- continue;
- }
-
- if (assigned)
- continue;
-
- switch (token)
- {
- case KW_TYPE:
- conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK);
- if (streq(kw->value, "tunnel"))
- conn->policy |= POLICY_TUNNEL;
- else if (streq(kw->value, "passthrough") || streq(kw->value, "pass"))
- conn->policy |= POLICY_SHUNT_PASS;
- else if (streq(kw->value, "drop"))
- conn->policy |= POLICY_SHUNT_DROP;
- else if (streq(kw->value, "reject"))
- conn->policy |= POLICY_SHUNT_REJECT;
- else if (strcmp(kw->value, "transport") != 0)
- {
- plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
- cfg->err++;
- }
- break;
- case KW_PFS:
- KW_POLICY_FLAG("yes", "no", POLICY_PFS)
- break;
- case KW_COMPRESS:
- KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS)
- break;
- case KW_AUTH:
- KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE)
- break;
- case KW_AUTHBY:
- conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT);
-
- if (strcmp(kw->value, "never") != 0)
- {
- char *value = kw->value;
- char *second = strchr(kw->value, '|');
-
- if (second != NULL)
- *second = '\0';
-
- /* also handles the cases secret|rsasig and rsasig|secret */
- for (;;)
- {
- if (streq(value, "rsasig"))
- conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT;
- else if (streq(value, "secret") || streq(value, "psk"))
- conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
- else if (streq(value, "xauthrsasig"))
- conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
- else if (streq(value, "xauthpsk"))
- conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT;
- else
- {
- plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
- cfg->err++;
- break;
- }
- if (second == NULL)
- break;
- value = second;
- second = NULL; /* traverse the loop no more than twice */
- }
- }
- break;
- case KW_REKEY:
- KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY)
- break;
- case KW_MODECONFIG:
- KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH)
- break;
- case KW_XAUTH:
- KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER)
- break;
- default:
- break;
- }
- }
- handle_firewall("left", &conn->left, cfg);
- handle_firewall("right", &conn->right, cfg);
-}
-
-/*
- * initialize a conn object with the default conn
- */
-static void
-conn_default(char *name, starter_conn_t *conn, starter_conn_t *def)
-{
- memcpy(conn, def, sizeof(starter_conn_t));
- conn->name = clone_str(name, "conn name");
-
- clone_args(KW_CONN_FIRST, KW_CONN_LAST
- , (char *)conn, (char *)def);
- clone_args(KW_END_FIRST, KW_END_LAST
- , (char *)&conn->left, (char *)&def->left);
- clone_args(KW_END_FIRST, KW_END_LAST
- , (char *)&conn->right, (char *)&def->right);
-}
-
-/*
- * parse a ca section
- */
-static void
-load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg)
-{
- char *ca_name = (ca->name == NULL)? "%default":ca->name;
-
- for ( ; kw; kw = kw->next)
- {
- bool assigned = FALSE;
-
- kw_token_t token = kw->entry->token;
-
- if (token == KW_AUTO)
- {
- token = KW_CA_SETUP;
- }
- else if (token == KW_ALSO)
- {
- if (cfg->parse_also)
- {
- also_t *also = alloc_thing(also_t, "also_t");
-
- also->name = clone_str(kw->value, "also");
- also->next = ca->also;
- ca->also = also;
-
- DBG(DBG_CONTROL,
- DBG_log(" also=%s", kw->value)
- )
- }
- continue;
- }
-
- if (token < KW_CA_FIRST || token > KW_CA_LAST)
- {
- plog("# unsupported keyword '%s' in ca '%s'"
- , kw->entry->name, ca_name);
- cfg->err++;
- continue;
- }
-
- if (!assign_arg(token, KW_CA_FIRST, kw, (char *)ca, &assigned))
- {
- plog(" bad argument value in ca '%s'", ca_name);
- cfg->err++;
- }
- }
-
- /* treat 'route' and 'start' as 'add' */
- if (ca->startup != STARTUP_NO)
- ca->startup = STARTUP_ADD;
-}
-
-/*
- * initialize a ca object with the default ca
- */
-static void
-ca_default(char *name, starter_ca_t *ca, starter_ca_t *def)
-{
- memcpy(ca, def, sizeof(starter_ca_t));
- ca->name = clone_str(name, "ca name");
-
- clone_args(KW_CA_FIRST, KW_CA_LAST, (char *)ca, (char *)def);
-}
-
-static kw_list_t*
-find_also_conn(const char* name, starter_conn_t *conn, starter_config_t *cfg);
-
-static void
-load_also_conns(starter_conn_t *conn, also_t *also, starter_config_t *cfg)
-{
- while (also != NULL)
- {
- kw_list_t *kw = find_also_conn(also->name, conn, cfg);
-
- if (kw == NULL)
- {
- plog(" conn '%s' cannot include '%s'", conn->name, also->name);
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("conn '%s' includes '%s'", conn->name, also->name)
- )
- /* only load if no error occurred in the first round */
- if (cfg->err == 0)
- load_conn(conn, kw, cfg);
- }
- also = also->next;
- }
-}
-
-/*
- * find a conn included by also
- */
-static kw_list_t*
-find_also_conn(const char* name, starter_conn_t *conn, starter_config_t *cfg)
-{
- starter_conn_t *c = cfg->conn_first;
-
- while (c != NULL)
- {
- if (streq(name, c->name))
- {
- if (conn->visit == c->visit)
- {
- plog("# detected also loop");
- cfg->err++;
- return NULL;
- }
- c->visit = conn->visit;
- load_also_conns(conn, c->also, cfg);
- return c->kw;
- }
- c = c->next;
- }
-
- plog("# also '%s' not found", name);
- cfg->err++;
- return NULL;
-}
-
-static kw_list_t*
-find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg);
-
-static void
-load_also_cas(starter_ca_t *ca, also_t *also, starter_config_t *cfg)
-{
- while (also != NULL)
- {
- kw_list_t *kw = find_also_ca(also->name, ca, cfg);
-
- if (kw == NULL)
- {
- plog(" ca '%s' cannot include '%s'", ca->name, also->name);
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("ca '%s' includes '%s'", ca->name, also->name)
- )
- /* only load if no error occurred in the first round */
- if (cfg->err == 0)
- load_ca(ca, kw, cfg);
- }
- also = also->next;
- }
-}
-
-/*
- * find a ca included by also
- */
-static kw_list_t*
-find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg)
-{
- starter_ca_t *c = cfg->ca_first;
-
- while (c != NULL)
- {
- if (streq(name, c->name))
- {
- if (ca->visit == c->visit)
- {
- plog("# detected also loop");
- cfg->err++;
- return NULL;
- }
- c->visit = ca->visit;
- load_also_cas(ca, c->also, cfg);
- return c->kw;
- }
- c = c->next;
- }
-
- plog("# also '%s' not found", name);
- cfg->err++;
- return NULL;
-}
-
-
-
-/*
- * load and parse an IPsec configuration file
- */
-starter_config_t *
-confread_load(const char *file)
-{
- starter_config_t *cfg = NULL;
- config_parsed_t *cfgp;
- section_list_t *sconn, *sca;
- starter_conn_t *conn;
- starter_ca_t *ca;
-
- u_int visit = 0;
-
- /* load IPSec configuration file */
- cfgp = parser_load_conf(file);
- if (!cfgp)
- return NULL;
-
- cfg = (starter_config_t *)alloc_thing(starter_config_t, "starter_config_t");
-
- /* set default values */
- default_values(cfg);
-
- /* determine default route */
- get_defaultroute(&cfg->defaultroute);
-
- /* load config setup section */
- load_setup(cfg, cfgp);
-
- /* in the first round parse also statements */
- cfg->parse_also = TRUE;
-
- /* find %default ca section */
- for (sca = cfgp->ca_first; sca; sca = sca->next)
- {
- if (streq(sca->name, "%default"))
- {
- DBG(DBG_CONTROL,
- DBG_log("Loading ca %%default")
- )
- load_ca(&cfg->ca_default, sca->kw, cfg);
- }
- }
-
- /* parameters defined in ca %default sections can be overloads */
- cfg->ca_default.seen = LEMPTY;
-
- /* load other ca sections */
- for (sca = cfgp->ca_first; sca; sca = sca->next)
- {
- /* skip %default ca section */
- if (streq(sca->name, "%default"))
- continue;
-
- DBG(DBG_CONTROL,
- DBG_log("Loading ca '%s'", sca->name)
- )
- ca = (starter_ca_t *)alloc_thing(starter_ca_t, "starter_ca_t");
-
- ca_default(sca->name, ca, &cfg->ca_default);
- ca->kw = sca->kw;
- ca->next = NULL;
-
- if (cfg->ca_last)
- cfg->ca_last->next = ca;
- cfg->ca_last = ca;
- if (!cfg->ca_first)
- cfg->ca_first = ca;
-
- load_ca(ca, ca->kw, cfg);
- }
-
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- also_t *also = ca->also;
-
- while (also != NULL)
- {
- kw_list_t *kw = find_also_ca(also->name, cfg->ca_first, cfg);
-
- load_ca(ca, kw, cfg);
- also = also->next;
- }
-
- if (ca->startup != STARTUP_NO)
- ca->state = STATE_TO_ADD;
- }
-
- /* find %default conn sections */
- for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
- {
- if (streq(sconn->name, "%default"))
- {
- DBG(DBG_CONTROL,
- DBG_log("Loading conn %%default")
- )
- load_conn(&cfg->conn_default, sconn->kw, cfg);
- }
- }
-
- /* parameter defined in conn %default sections can be overloaded */
- cfg->conn_default.seen = LEMPTY;
- cfg->conn_default.right.seen = LEMPTY;
- cfg->conn_default.left.seen = LEMPTY;
-
- /* load other conn sections */
- for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
- {
- /* skip %default conn section */
- if (streq(sconn->name, "%default"))
- continue;
-
- DBG(DBG_CONTROL,
- DBG_log("Loading conn '%s'", sconn->name)
- )
- conn = (starter_conn_t *)alloc_thing(starter_conn_t, "starter_conn_t");
-
- conn_default(sconn->name, conn, &cfg->conn_default);
- conn->kw = sconn->kw;
- conn->next = NULL;
-
- if (cfg->conn_last)
- cfg->conn_last->next = conn;
- cfg->conn_last = conn;
- if (!cfg->conn_first)
- cfg->conn_first = conn;
-
- load_conn(conn, conn->kw, cfg);
- }
-
- /* in the second round do not parse also statements */
- cfg->parse_also = FALSE;
-
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- ca->visit = ++visit;
- load_also_cas(ca, ca->also, cfg);
-
- if (ca->startup != STARTUP_NO)
- ca->state = STATE_TO_ADD;
- }
-
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- conn->visit = ++visit;
- load_also_conns(conn, conn->also, cfg);
-
- if (conn->startup != STARTUP_NO)
- conn->state = STATE_TO_ADD;
- }
-
- parser_free_conf(cfgp);
-
- if (cfg->err)
- {
- plog("### %d parsing error%s ###", cfg->err, (cfg->err > 1)?"s":"");
- confread_free(cfg);
- cfg = NULL;
- }
-
- return cfg;
-}
-
-/*
- * free the memory used by also_t objects
- */
-static void
-free_also(also_t *head)
-{
- while (head != NULL)
- {
- also_t *also = head;
-
- head = also->next;
- pfree(also->name);
- pfree(also);
- }
-}
-
-/*
- * free the memory used by a starter_conn_t object
- */
-static void
-confread_free_conn(starter_conn_t *conn)
-{
- free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
- free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
- free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
- free_also(conn->also);
-}
-
-/*
- * free the memory used by a starter_ca_t object
- */
-static void
-confread_free_ca(starter_ca_t *ca)
-{
- free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
- free_also(ca->also);
-}
-
-/*
- * free the memory used by a starter_config_t object
- */
-void
-confread_free(starter_config_t *cfg)
-{
- starter_conn_t *conn = cfg->conn_first;
- starter_ca_t *ca = cfg->ca_first;
-
- free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
-
- confread_free_conn(&cfg->conn_default);
-
- while (conn != NULL)
- {
- starter_conn_t *conn_aux = conn;
-
- conn = conn->next;
- confread_free_conn(conn_aux);
- pfree(conn_aux);
- }
-
- confread_free_ca(&cfg->ca_default);
-
- while (ca != NULL)
- {
- starter_ca_t *ca_aux = ca;
-
- ca = ca->next;
- confread_free_ca(ca_aux);
- pfree(ca_aux);
- }
-
- pfree(cfg);
-}
diff --git a/programs/starter/confread.h b/programs/starter/confread.h
deleted file mode 100644
index 052f5d527..000000000
--- a/programs/starter/confread.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* strongSwan IPsec config file parser
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: confread.h,v 1.24 2006/10/19 15:01:05 as Exp $
- */
-
-#ifndef _IPSEC_CONFREAD_H_
-#define _IPSEC_CONFREAD_H_
-
-#ifndef _FREESWAN_H
-#include <freeswan.h>
-#include "../pluto/constants.h"
-#endif
-
-#include "parser.h"
-#include "interfaces.h"
-
-typedef enum {
- STARTUP_NO,
- STARTUP_ADD,
- STARTUP_ROUTE,
- STARTUP_START
-} startup_t;
-
-typedef enum {
- STATE_IGNORE,
- STATE_TO_ADD,
- STATE_ADDED,
- STATE_REPLACED,
- STATE_INVALID
-} starter_state_t;
-
-typedef struct starter_end starter_end_t;
-
-struct starter_end {
- lset_t seen;
- char *id;
- char *rsakey;
- char *cert;
- char *ca;
- char *groups;
- char *iface;
- ip_address addr;
- ip_address nexthop;
- ip_address srcip;
- ip_subnet subnet;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_srcip;
- bool has_natip;
- bool modecfg;
- certpolicy_t sendcert;
- bool firewall;
- bool hostaccess;
- char *updown;
- u_int16_t port;
- u_int8_t protocol;
-#ifdef VIRTUAL_IP
- char *virt;
-#endif
-};
-
-typedef struct also also_t;
-
-struct also {
- char *name;
- bool included;
- also_t *next;
-};
-
-typedef struct starter_conn starter_conn_t;
-
-struct starter_conn {
- lset_t seen;
- char *name;
- also_t *also;
- kw_list_t *kw;
- u_int visit;
- startup_t startup;
- starter_state_t state;
-
- int keyexchange;
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_keying_tries;
- unsigned long sa_rekey_fuzz;
- sa_family_t addr_family;
- sa_family_t tunnel_addr_family;
-
- starter_end_t left, right;
-
- unsigned long id;
-
- char *esp;
- char *ike;
- char *pfsgroup;
-
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
- int dpd_count;
-
- starter_conn_t *next;
-};
-
-typedef struct starter_ca starter_ca_t;
-
-struct starter_ca {
- lset_t seen;
- char *name;
- also_t *also;
- kw_list_t *kw;
- u_int visit;
- startup_t startup;
- starter_state_t state;
-
- char *cacert;
- char *ldaphost;
- char *ldapbase;
- char *crluri;
- char *crluri2;
- char *ocspuri;
-
- bool strict;
-
- starter_ca_t *next;
-};
-
-typedef struct starter_config starter_config_t;
-
-struct starter_config {
- struct {
- lset_t seen;
- char **interfaces;
- char *dumpdir;
-
- /* pluto keywords */
- char **plutodebug;
- char *prepluto;
- char *postpluto;
- bool uniqueids;
- u_int overridemtu;
- u_int crlcheckinterval;
- bool cachecrls;
- bool strictcrlpolicy;
- bool nocrsend;
- bool nat_traversal;
- u_int keep_alive;
- char *virtual_private;
- char *pkcs11module;
- bool pkcs11keepstate;
- bool pkcs11proxy;
-
- /* KLIPS keywords */
- char **klipsdebug;
- bool fragicmp;
- char *packetdefault;
- bool hidetos;
- } setup;
-
- /* information about the default route */
- defaultroute_t defaultroute;
-
- /* number of encountered parsing errors */
- u_int err;
-
- /* do we parse also statements */
- bool parse_also;
-
- /* ca %default */
- starter_ca_t ca_default;
-
- /* connections list (without %default) */
- starter_ca_t *ca_first, *ca_last;
-
- /* conn %default */
- starter_conn_t conn_default;
-
- /* connections list (without %default) */
- starter_conn_t *conn_first, *conn_last;
-};
-
-extern starter_config_t *confread_load(const char *file);
-extern void confread_free(starter_config_t *cfg);
-
-#endif /* _IPSEC_CONFREAD_H_ */
-
diff --git a/programs/starter/exec.c b/programs/starter/exec.c
deleted file mode 100644
index 98541db75..000000000
--- a/programs/starter/exec.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* strongSwan IPsec exec helper function
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: exec.c,v 1.4 2006/01/04 23:30:24 as Exp $
- */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "exec.h"
-
-#define BUF_SIZE 2048
-
-/**
- * TODO:
- * o log stdout with LOG_LEVEL_INFO and stderr with LOG_LEVEL_ERR
- */
-
-int
-starter_exec(const char *fmt, ...)
-{
- va_list args;
- static char buf[BUF_SIZE];
- int r;
-
- va_start (args, fmt);
- vsnprintf(buf, BUF_SIZE-1, fmt, args);
- buf[BUF_SIZE - 1] = '\0';
- va_end(args);
- r = system(buf);
- DBG(DBG_CONTROL,
- DBG_log("starter_exec(%s) = %d", buf, r)
- )
- return r;
-}
-
diff --git a/programs/starter/exec.h b/programs/starter/exec.h
deleted file mode 100644
index d4be931dd..000000000
--- a/programs/starter/exec.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* strongSwan IPsec starter exec helper function
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: exec.h,v 1.2 2005/12/28 10:20:32 as Exp $
- */
-
-#ifndef _STARTER_EXEC_H_
-#define _STARTER_EXEC_H_
-
-extern int starter_exec (const char *fmt, ...);
-
-#endif /* _STARTER_EXEC_H_ */
-
diff --git a/programs/starter/files.h b/programs/starter/files.h
deleted file mode 100644
index 286cdf105..000000000
--- a/programs/starter/files.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* strongSwan file locations
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: files.h,v 1.5 2006/02/04 18:52:58 as Exp $
- */
-
-#ifndef _STARTER_FILES_H_
-#define _STARTER_FILES_H_
-
-#ifndef DEFAULT_CTLBASE
-#define DEFAULT_CTLBASE "/var/run/pluto"
-#endif
-#define CTL_SUFFIX ".ctl"
-#define PID_SUFFIX ".pid"
-
-#define MY_PID_FILE "/var/run/starter.pid"
-
-#define DEV_RANDOM "/dev/random"
-#define DEV_URANDOM "/dev/urandom"
-
-#define PROC_NETKEY "/proc/net/pfkey"
-#define PROC_IPSECVERSION "/proc/net/ipsec_version"
-#define PROC_SYSFLAGS "/proc/sys/net/ipsec"
-#define PROC_MODULES "/proc/modules"
-
-#define CONFIG_FILE IPSEC_CONFDIR"/ipsec.conf"
-#define SECRETS_FILE IPSEC_CONFDIR"/ipsec.secrets"
-
-#define PLUTO_CMD IPSEC_EXECDIR"/pluto"
-#define CTL_FILE DEFAULT_CTLBASE CTL_SUFFIX
-#define PID_FILE DEFAULT_CTLBASE PID_SUFFIX
-
-#define DYNIP_DIR "/var/run/dynip"
-#define INFO_FILE "/var/run/ipsec.info"
-
-#endif /* _STARTER_FILES_H_ */
-
diff --git a/programs/starter/interfaces.c b/programs/starter/interfaces.c
deleted file mode 100644
index 3b24e2faf..000000000
--- a/programs/starter/interfaces.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/* strongSwan IPsec interfaces management
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: interfaces.c,v 1.16 2006/05/25 12:10:15 as Exp $
- */
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <linux/if.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <freeswan.h>
-#include <freeswan/ipsec_tunnel.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "interfaces.h"
-#include "exec.h"
-#include "files.h"
-
-#define MIN(a,b) ( ((a)>(b)) ? (b) : (a) )
-
-#define N_IPSEC_IF 4
-
-struct st_ipsec_if {
- char name[IFNAMSIZ];
- char phys[IFNAMSIZ];
- int up;
-};
-
-static struct st_ipsec_if _ipsec_if[N_IPSEC_IF];
-
-static char *
-_find_physical_iface(int sock, char *iface)
-{
- static char _if[IFNAMSIZ];
- char *b;
- struct ifreq req;
- FILE *fd;
- char line[BUF_LEN];
-
- strncpy(req.ifr_name, iface, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req)==0)
- {
- if (req.ifr_flags & IFF_UP)
- {
- strncpy(_if, iface, IFNAMSIZ);
- return _if;
- }
- }
- else
- {
- /* If there is a file named /var/run/dynip/<iface>, look if we
- * can get interface name from there (IP_PHYS)
- */
- b = (char *)alloc_bytes(strlen(DYNIP_DIR) + strlen(iface) + 10, "iface");
- if (b)
- {
- sprintf(b, "%s/%s", DYNIP_DIR, iface);
- fd = fopen(b, "r");
- pfree(b);
- if (fd)
- {
- memset(_if, 0, sizeof(_if));
- memset(line, 0, sizeof(line));
- while (fgets(line, sizeof(line), fd) != 0)
- {
- if ((strncmp(line,"IP_PHYS=\"", 9) == 0)
- && (line[strlen(line) - 2] == '"')
- && (line[strlen(line) - 1] == '\n'))
- {
- strncpy(_if, line + 9, MIN(strlen(line) - 11, IFNAMSIZ));
- break;
- }
- else if ((strncmp(line,"IP_PHYS=", 8) == 0)
- && (line[8] != '"')
- && (line[strlen(line) - 1] == '\n'))
- {
- strncpy(_if, line + 8, MIN(strlen(line) - 9, IFNAMSIZ));
- break;
- }
- }
- fclose(fd);
-
- if (*_if)
- {
- strncpy(req.ifr_name, _if, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
- {
- if (req.ifr_flags & IFF_UP)
- return _if;
- }
- }
- }
- }
- }
- return NULL;
-}
-
-int
-starter_iface_find(char *iface, int af, ip_address *dst, ip_address *nh)
-{
- char *phys;
- struct ifreq req;
- struct sockaddr_in *sa = (struct sockaddr_in *)(&req.ifr_addr);
- int sock;
-
- if (!iface)
- return -1;
-
- sock = socket(af, SOCK_DGRAM, 0);
- if (sock < 0)
- return -1;
-
- phys = _find_physical_iface(sock, iface);
- if (!phys)
- goto failed;
-
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req)!=0)
- goto failed;
- if (!(req.ifr_flags & IFF_UP))
- goto failed;
-
- if ((req.ifr_flags & IFF_POINTOPOINT)
- && nh
- && ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
- {
- if (sa->sin_family == af)
- initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, nh);
- }
- if ((dst) && (ioctl(sock, SIOCGIFADDR, &req) == 0))
- {
- if (sa->sin_family == af)
- initaddr((const void *)&sa->sin_addr, sizeof(struct in_addr), af, dst);
- }
- close(sock);
- return 0;
-
-failed:
- close(sock);
- return -1;
-}
-
-static int
-valid_str(char *str, unsigned int *pn, char **pphys
-, defaultroute_t *defaultroute)
-{
- if (streq(str, "%defaultroute"))
- {
- if (!defaultroute->defined)
- {
- return 0;
- }
- *pn = 0;
- *pphys = defaultroute->iface;
- }
- else
- {
- if (strlen(str) < 8
- || str[0] != 'i' || str[1] != 'p' || str[2] !='s' || str[3] != 'e'
- || str[4] != 'c' || str[5] < '0' || str[5] > '9' || str[6] != '=')
- {
- return 0;
- }
- *pn = str[5] - '0';
- *pphys = &(str[7]);
- }
- return 1;
-}
-
-static int
-_iface_up (int sock, struct st_ipsec_if *iface, char *phys
-, unsigned int mtu, bool nat_t)
-{
- struct ifreq req;
- struct ipsectunnelconf *shc=(struct ipsectunnelconf *)&req.ifr_data;
- short phys_flags;
- int ret = 0;
-
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) !=0 )
- return ret;
- phys_flags = req.ifr_flags;
-
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) != 0)
- return ret;
-
- if ((!(req.ifr_flags & IFF_UP)) || (!iface->up))
- {
- DBG(DBG_CONTROL,
- DBG_log("attaching interface %s to %s", iface->name, phys)
- )
- ret = 1;
- }
-
- if ((*iface->phys) && (strcmp(iface->phys, phys) != 0 ))
- {
- /* tncfg --detach if phys has changed */
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- ioctl(sock, IPSEC_DEL_DEV, &req);
- ret = 1;
- }
-
- /* tncfg --attach */
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- strncpy(shc->cf_name, phys, sizeof(shc->cf_name));
- ioctl(sock, IPSEC_SET_DEV, &req);
-
- /* set ipsec addr = phys addr */
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFADDR, &req) == 0)
- {
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- ioctl(sock, SIOCSIFADDR, &req);
- }
-
- /* set ipsec mask = phys mask */
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFNETMASK, &req) == 0)
- {
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- ioctl(sock, SIOCSIFNETMASK, &req);
- }
-
- /* set other flags & addr */
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req)==0)
- {
- if (phys_flags & IFF_POINTOPOINT)
- {
- req.ifr_flags |= IFF_POINTOPOINT;
- req.ifr_flags &= ~IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
- {
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- ioctl(sock, SIOCSIFDSTADDR, &req);
- }
- }
- else if (phys_flags & IFF_BROADCAST)
- {
- req.ifr_flags &= ~IFF_POINTOPOINT;
- req.ifr_flags |= IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFBRDADDR, &req) == 0)
- {
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- ioctl(sock, SIOCSIFBRDADDR, &req);
- }
- }
- else
- {
- req.ifr_flags &= ~IFF_POINTOPOINT;
- req.ifr_flags &= ~IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
- }
- }
-
- /*
- * guess MTU = phys interface MTU - ESP Overhead
- *
- * ESP overhead : 10+16+7+2+12=57 -> 60 by security
- * NAT-T overhead : 20
- */
- if (mtu == 0)
- {
- strncpy(req.ifr_name, phys, IFNAMSIZ);
- ioctl(sock, SIOCGIFMTU, &req);
- mtu = req.ifr_mtu - 60;
- if (nat_t)
- mtu -= 20;
- }
- /* set MTU */
- if (mtu)
- {
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- req.ifr_mtu = mtu;
- ioctl(sock, SIOCSIFMTU, &req);
- }
-
- /* ipsec interface UP */
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
- {
- req.ifr_flags |= IFF_UP;
- ioctl(sock, SIOCSIFFLAGS, &req);
- }
-
- iface->up = 1;
- strncpy(iface->phys, phys, IFNAMSIZ);
- return ret;
-}
-
-static int
-_iface_down(int sock, struct st_ipsec_if *iface)
-{
- struct ifreq req;
- int ret = 0;
-
- iface->up = 0;
-
- strncpy(req.ifr_name, iface->name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req)!=0)
- return ret;
-
- if (req.ifr_flags & IFF_UP)
- {
- DBG(DBG_CONTROL,
- DBG_log("shutting down interface %s/%s", iface->name, iface->phys)
- )
- req.ifr_flags &= ~IFF_UP;
- ioctl(sock, SIOCSIFFLAGS, &req);
- ret = 1;
- }
-
- /* unset addr */
- memset(&req.ifr_addr, 0, sizeof(req.ifr_addr));
- req.ifr_addr.sa_family = AF_INET;
- ioctl(sock, SIOCSIFADDR, &req);
-
- /* tncfg --detach */
- ioctl(sock, IPSEC_DEL_DEV, &req);
-
- memset(iface->phys, 0, sizeof(iface->phys));
-
- return ret;
-}
-
-void
-starter_ifaces_init(void)
-{
- int i;
-
- memset(_ipsec_if, 0, sizeof(_ipsec_if));
- for (i = 0; i < N_IPSEC_IF; i++)
- snprintf(_ipsec_if[i].name, IFNAMSIZ, "ipsec%d", i);
-}
-
-void
-starter_ifaces_clear (void)
-{
- int sock;
- unsigned int i;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0)
- return;
-
- for (i = 0; i < N_IPSEC_IF; i++)
- _iface_down (sock, &(_ipsec_if[i]));
-}
-
-int
-starter_ifaces_load(char **ifaces, unsigned int omtu, bool nat_t
-, defaultroute_t *defaultroute)
-{
- char *tmp_phys, *phys;
- int n;
- char **i;
- int sock;
- int j, found;
- int ret = 0;
- struct ifreq physreq, ipsecreq; // re-attach interface
- struct sockaddr_in *inp1, *inp2; // re-attach interface
-
- DBG(DBG_CONTROL,
- DBG_log("starter_ifaces_load()")
- )
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0)
- return -1;
-
- for (j = 0; j < N_IPSEC_IF; j++)
- {
- found = 0;
-
- for (i = ifaces; i && *i; i++)
- {
- if (valid_str(*i, &n, &tmp_phys, defaultroute)
- && tmp_phys
- && n >= 0
- && n < N_IPSEC_IF)
- {
- if (n==j)
- {
- if (found)
- {
- plog( "ignoring duplicate entry for interface ipsec%d", j);
- }
- else
- {
- found++;
- phys = _find_physical_iface(sock, tmp_phys);
-
- /* Re-attach ipsec interface if IP address changes
- * sscholz@astaro.com
- */
- if (phys)
- {
- memset ((void*)&physreq, 0, sizeof(physreq));
- memset ((void*)&ipsecreq, 0, sizeof(ipsecreq));
- strncpy(physreq.ifr_name, phys, IFNAMSIZ);
- sprintf(ipsecreq.ifr_name, "ipsec%d", j);
- ioctl(sock, SIOCGIFADDR, &physreq);
- ioctl(sock, SIOCGIFADDR, &ipsecreq);
- inp1 = (struct sockaddr_in *)&physreq.ifr_addr;
- inp2 = (struct sockaddr_in *)&ipsecreq.ifr_addr;
- if (inp1->sin_addr.s_addr != inp2->sin_addr.s_addr)
- {
- plog("IP address of physical interface changed "
- "-> reinit of ipsec interface");
- _iface_down (sock, &(_ipsec_if[n]));
- }
- ret += _iface_up (sock, &(_ipsec_if[n]), phys, omtu, nat_t);
- }
- else
- {
- ret += _iface_down (sock, &(_ipsec_if[n]));
- }
- }
- }
- }
- else if (j == 0)
- {
- /* Only log in the first loop */
- plog("ignoring invalid interface '%s'", *i);
- }
- }
- if (!found)
- ret += _iface_down (sock, &(_ipsec_if[j]));
- }
-
- close(sock);
- return ret; /* = number of changes - 'whack --listen' if > 0 */
-}
-
-/*
- * initialize a defaultroute_t struct
- */
-static void
-init_defaultroute(defaultroute_t *defaultroute)
-{
- memset(defaultroute, 0, sizeof(defaultroute_t));
-}
-
-/*
- * discover the default route via /proc/net/route
- */
-void
-get_defaultroute(defaultroute_t *defaultroute)
-{
- FILE *fd;
- char line[BUF_LEN];
- bool first = TRUE;
-
- init_defaultroute(defaultroute);
-
- fd = fopen("/proc/net/route", "r");
-
- if (!fd)
- {
- plog("could not open 'proc/net/route'");
- return;
- }
-
- while (fgets(line, sizeof(line), fd) != 0)
- {
- char iface[11];
- char destination[9];
- char gateway[11];
- char flags[5];
- char mask[9];
-
- int refcnt;
- int use;
- int metric;
- int items;
-
- /* proc/net/route returns IP addresses in host order */
- strcpy(gateway, "0h");
-
- /* skip the header line */
- if (first)
- {
- first = FALSE;
- continue;
- }
-
- /* parsing a single line of proc/net/route */
- items = sscanf(line, "%10s\t%8s\t%8s\t%5s\t%d\t%d\t%d\t%8s\t"
- , iface, destination, gateway+2, flags, &refcnt, &use, &metric, mask);
- if (items < 8)
- {
- plog("parsing error while scanning /proc/net/route");
- continue;
- }
-
- /* check for defaultroute (destination 0.0.0.0 and mask 0.0.0.0) */
- if (streq(destination, "00000000") && streq(mask, "00000000"))
- {
- if (defaultroute->defined)
- {
- plog("multiple default routes - cannot cope with %%defaultroute!!!");
- defaultroute->defined = FALSE;
- fclose(fd);
- return;
- }
- ttoaddr(gateway, strlen(gateway), AF_INET, &defaultroute->nexthop);
- strncpy(defaultroute->iface, iface, IFNAMSIZ);
- defaultroute->defined = TRUE;
- }
- }
- fclose(fd);
-
- if (!defaultroute->defined)
- {
- plog("no default route - cannot cope with %%defaultroute!!!");
- }
- else
- {
- char addr_buf[20], nexthop_buf[20];
- struct ifreq physreq;
-
- int sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- /* determine IP address of iface */
- if (sock < 0)
- {
- plog("could not open SOCK_DGRAM socket");
- defaultroute->defined = FALSE;
- return;
- }
- memset ((void*)&physreq, 0, sizeof(physreq));
- strncpy(physreq.ifr_name, defaultroute->iface, IFNAMSIZ);
- ioctl(sock, SIOCGIFADDR, &physreq);
- close(sock);
- defaultroute->addr.u.v4 = *((struct sockaddr_in *)&physreq.ifr_addr);
-
- addrtot(&defaultroute->addr, 0, addr_buf, sizeof(addr_buf));
- addrtot(&defaultroute->nexthop, 0, nexthop_buf, sizeof(nexthop_buf));
-
- DBG(DBG_CONTROL,
- DBG_log("Default route found: iface=%s, addr=%s, nexthop=%s"
- , defaultroute->iface, addr_buf, nexthop_buf)
- )
-
- /* for backwards-compatibility with the awk shell scripts
- * store the defaultroute in /var/run/ipsec.info
- */
- fd = fopen(INFO_FILE, "w");
-
- if (fd)
- {
- fprintf(fd, "defaultroutephys=%s\n", defaultroute->iface );
- fprintf(fd, "defaultroutevirt=ipsec0\n");
- fprintf(fd, "defaultrouteaddr=%s\n", addr_buf);
- fprintf(fd, "defaultroutenexthop=%s\n", nexthop_buf);
- fclose(fd);
- }
- }
- return;
-}
diff --git a/programs/starter/interfaces.h b/programs/starter/interfaces.h
deleted file mode 100644
index 9898c0516..000000000
--- a/programs/starter/interfaces.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* strongSwan IPsec interfaces management
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: interfaces.h,v 1.6 2006/01/06 20:24:07 as Exp $
- */
-
-#ifndef _STARTER_INTERFACES_H_
-#define _STARTER_INTERFACES_H_
-
-#include <linux/if.h>
-
-#include "../pluto/constants.h"
-
-typedef struct {
- bool defined;
- char iface[IFNAMSIZ];
- ip_address addr;
- ip_address nexthop;
-} defaultroute_t;
-
-extern void starter_ifaces_init (void);
-extern int starter_iface_find(char *iface, int af, ip_address *dst
- , ip_address *nh);
-extern int starter_ifaces_load (char **ifaces, unsigned int omtu, bool nat_t
- , defaultroute_t *defaultroute);
-extern void starter_ifaces_clear (void);
-extern void get_defaultroute(defaultroute_t *defaultroute);
-
-
-#endif /* _STARTER_INTERFACES_H_ */
-
diff --git a/programs/starter/invokepluto.c b/programs/starter/invokepluto.c
deleted file mode 100644
index 70376e380..000000000
--- a/programs/starter/invokepluto.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* strongSwan Pluto launcher
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: invokepluto.c,v 1.12 2006/02/17 21:41:50 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "confread.h"
-#include "invokepluto.h"
-#include "files.h"
-#include "starterwhack.h"
-#
-static int _pluto_pid = 0;
-static int _stop_requested;
-
-pid_t
-starter_pluto_pid(void)
-{
- return _pluto_pid;
-}
-
-void
-starter_pluto_sigchild(pid_t pid)
-{
- if (pid == _pluto_pid)
- {
- _pluto_pid = 0;
- if (!_stop_requested)
- {
- plog("pluto has died -- restart scheduled (%dsec)"
- , PLUTO_RESTART_DELAY);
- alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
- }
- unlink(PID_FILE);
- }
-}
-
-int
-starter_stop_pluto (void)
-{
- pid_t pid;
- int i;
-
- pid = _pluto_pid;
- if (pid)
- {
- _stop_requested = 1;
- if (starter_whack_shutdown() == 0)
- {
- for (i = 0; i < 20; i++)
- {
- usleep(20000);
- if (_pluto_pid == 0)
- return 0;
- }
- }
- /* be more and more aggressive */
- for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
- {
- if (i < 10)
- kill(pid, SIGTERM);
- else
- kill(pid, SIGKILL);
- usleep(20000);
- }
- if (_pluto_pid == 0)
- return 0;
- plog("starter_stop_pluto(): can't stop pluto !!!");
- return -1;
- }
- else
- {
- plog("stater_stop_pluto(): pluto is not started...");
- }
- return -1;
-}
-
-#define ADD_DEBUG(v) { \
- for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
- arg[argc++] = "--debug-" v; \
- }
-
-int
-starter_start_pluto (starter_config_t *cfg, bool debug)
-{
- int i;
- struct stat stb;
- pid_t pid;
- char **l;
- int argc = 2;
- char *arg[] = {
- PLUTO_CMD, "--nofork"
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- printf ("starter_start_pluto entered\n");
-
- if (debug)
- {
- arg[argc++] = "--stderrlog";
- }
- if (cfg->setup.uniqueids)
- {
- arg[argc++] = "--uniqueids";
- }
- ADD_DEBUG("none")
- ADD_DEBUG("all")
- ADD_DEBUG("raw")
- ADD_DEBUG("crypt")
- ADD_DEBUG("parsing")
- ADD_DEBUG("emitting")
- ADD_DEBUG("control")
- ADD_DEBUG("lifecycle")
- ADD_DEBUG("klips")
- ADD_DEBUG("dns")
- ADD_DEBUG("natt")
- ADD_DEBUG("oppo")
- ADD_DEBUG("controlmore")
- ADD_DEBUG("private")
- if (cfg->setup.crlcheckinterval > 0)
- {
- static char buf1[15];
-
- arg[argc++] = "--crlcheckinterval";
- snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
- arg[argc++] = buf1;
- }
- if (cfg->setup.cachecrls)
- {
- arg[argc++] = "--cachecrls";
- }
- if (cfg->setup.strictcrlpolicy)
- {
- arg[argc++] = "--strictcrlpolicy";
- }
- if (cfg->setup.nocrsend)
- {
- arg[argc++] = "--nocrsend";
- }
- if (cfg->setup.nat_traversal)
- {
- arg[argc++] = "--nat_traversal";
- }
- if (cfg->setup.keep_alive)
- {
- static char buf2[15];
-
- arg[argc++] = "--keep_alive";
- snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
- arg[argc++] = buf2;
- }
-#ifdef VIRTUAL_IP
- if (cfg->setup.virtual_private)
- {
- arg[argc++] = "--virtual_private";
- arg[argc++] = cfg->setup.virtual_private;
- }
-#endif
- if (cfg->setup.pkcs11module)
- {
- arg[argc++] = "--pkcs11module";
- arg[argc++] = cfg->setup.pkcs11module;
- }
- if (cfg->setup.pkcs11keepstate)
- {
- arg[argc++] = "--pkcs11keepstate";
- }
- if (cfg->setup.pkcs11proxy)
- {
- arg[argc++] = "--pkcs11proxy";
- }
-
- if (_pluto_pid)
- {
- plog("starter_start_pluto(): pluto already started...");
- return -1;
- }
- else
- {
- unlink(CTL_FILE);
- _stop_requested = 0;
-
- if (cfg->setup.prepluto)
- system(cfg->setup.prepluto);
-
- /* if ipsec.secrets file is missing then generate RSA default key pair */
- if (stat(SECRETS_FILE, &stb) != 0)
- {
- mode_t oldmask;
- FILE *f;
-
- plog("no %s file, generating RSA key", SECRETS_FILE);
- system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
-
- /* ipsec.secrets is root readable only */
- oldmask = umask(0066);
-
- f = fopen(SECRETS_FILE, "w");
- if (f)
- {
- fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
- fprintf(f, "\n");
- fprintf(f, ": RSA myKey.der\n");
- fclose(f);
- }
- umask(oldmask);
- }
-
- pid = fork();
- switch (pid)
- {
- case -1:
- plog("can't fork(): %s", strerror(errno));
- return -1;
- case 0:
- /* child */
- setsid();
- sigprocmask(SIG_SETMASK, 0, NULL);
- execv(arg[0], arg);
- plog("can't execv(%s,...): %s", arg[0], strerror(errno));
- exit(1);
- default:
- /* father */
- _pluto_pid = pid;
- for (i = 0; i < 50 && _pluto_pid; i++)
- {
- /* wait for pluto */
- usleep(20000);
- if (stat(CTL_FILE, &stb) == 0)
- {
- DBG(DBG_CONTROL,
- DBG_log("pluto (%d) started", _pluto_pid)
- )
- if (cfg->setup.postpluto)
- system(cfg->setup.postpluto);
- return 0;
- }
- }
- if (_pluto_pid)
- {
- /* If pluto is started but with no ctl file, stop it */
- plog("pluto too long to start... - kill kill");
- for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
- {
- if (i < 10)
- kill(pid, SIGTERM);
- else
- kill(pid, SIGKILL);
- usleep(20000);
- }
- }
- else
- {
- plog("pluto refused to be started");
- }
- return -1;
- }
- }
- return -1;
-}
diff --git a/programs/starter/invokepluto.h b/programs/starter/invokepluto.h
deleted file mode 100644
index 26858f9b2..000000000
--- a/programs/starter/invokepluto.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* strongSwan pluto launcher
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: invokepluto.h,v 1.3 2006/01/04 23:30:24 as Exp $
- */
-
-#ifndef _STARTER_PLUTO_H_
-#define _STARTER_PLUTO_H_
-
-#define PLUTO_RESTART_DELAY 5
-
-extern void starter_pluto_sigchild (pid_t pid);
-extern pid_t starter_pluto_pid (void);
-extern int starter_stop_pluto (void);
-extern int starter_start_pluto (struct starter_config *cfg, bool debug);
-
-#endif /* _STARTER_PLUTO_H_ */
-
diff --git a/programs/starter/keywords.c b/programs/starter/keywords.c
deleted file mode 100644
index b06ee3c0c..000000000
--- a/programs/starter/keywords.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* C code produced by gperf version 3.0.1 */
-/* Command-line: gperf -C -G -t */
-/* Computed positions: -k'3,$' */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
- && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
-/* The character set is not based on ISO-646. */
-error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
-#endif
-
-
-/* strongSwan keywords
- * Copyright (C) 2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: keywords.c,v 1.9 2007/01/11 21:29:28 as Exp $
- */
-
-#include <string.h>
-
-#include "keywords.h"
-
-struct kw_entry {
- char *name;
- kw_token_t token;
-};
-
-#define TOTAL_KEYWORDS 81
-#define MIN_WORD_LENGTH 3
-#define MAX_WORD_LENGTH 17
-#define MIN_HASH_VALUE 9
-#define MAX_HASH_VALUE 156
-/* maximum key range = 148, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-hash (str, len)
- register const char *str;
- register unsigned int len;
-{
- static const unsigned char asso_values[] =
- {
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 25, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 90, 157, 60,
- 50, 25, 0, 10, 30, 65, 157, 65, 70, 5,
- 0, 75, 35, 157, 10, 20, 5, 70, 157, 157,
- 157, 55, 0, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157
- };
- return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[len - 1]];
-}
-
-static const struct kw_entry wordlist[] =
- {
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"left", KW_LEFT},
- {"leftupdown", KW_LEFTUPDOWN},
- {""}, {""},
- {"leftcert", KW_LEFTCERT,},
- {""},
- {"leftsubnet", KW_LEFTSUBNET},
- {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
- {"leftsendcert", KW_LEFTSENDCERT},
- {"leftprotoport", KW_LEFTPROTOPORT},
- {""},
- {"right", KW_RIGHT},
- {"rightupdown", KW_RIGHTUPDOWN},
- {"dumpdir", KW_DUMPDIR},
- {""},
- {"rightcert", KW_RIGHTCERT},
- {""},
- {"rightsubnet", KW_RIGHTSUBNET},
- {"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
- {"rightsendcert", KW_RIGHTSENDCERT},
- {"rightprotoport", KW_RIGHTPROTOPORT},
- {"leftgroups", KW_LEFTGROUPS},
- {""}, {""},
- {"compress", KW_COMPRESS},
- {"lefthostaccess", KW_LEFTHOSTACCESS},
- {"interfaces", KW_INTERFACES},
- {""}, {""}, {""},
- {"auth", KW_AUTH},
- {""},
- {"rightgroups", KW_RIGHTGROUPS},
- {""},
- {"pfs", KW_PFS},
- {"leftnatip", KW_LEFTNATIP},
- {"righthostaccess", KW_RIGHTHOSTACCESS},
- {"leftnexthop", KW_LEFTNEXTHOP},
- {"leftsourceip", KW_LEFTSOURCEIP},
- {""}, {""},
- {"virtual_private", KW_VIRTUAL_PRIVATE},
- {""}, {""},
- {"ike", KW_IKE},
- {""},
- {"rightnatip", KW_RIGHTNATIP},
- {"leftid", KW_LEFTID},
- {"rightnexthop", KW_RIGHTNEXTHOP},
- {"rightsourceip", KW_RIGHTSOURCEIP},
- {"dpdaction", KW_DPDACTION},
- {"keep_alive", KW_KEEP_ALIVE},
- {"ikelifetime", KW_IKELIFETIME},
- {""},
- {"pfsgroup", KW_PFSGROUP},
- {"type", KW_TYPE},
- {"dpdtimeout", KW_DPDTIMEOUT},
- {"authby", KW_AUTHBY},
- {"rightid", KW_RIGHTID},
- {"leftrsasigkey", KW_LEFTRSASIGKEY},
- {""},
- {"modeconfig", KW_MODECONFIG},
- {"cacert", KW_CACERT},
- {""},
- {"esp", KW_ESP},
- {"rekeyfuzz", KW_REKEYFUZZ},
- {""},
- {"rekeymargin", KW_REKEYMARGIN},
- {"hidetos", KW_HIDETOS},
- {"packetdefault", KW_PACKETDEFAULT},
- {"rightrsasigkey", KW_RIGHTRSASIGKEY},
- {"strictcrlpolicy", KW_STRICTCRLPOLICY},
- {""},
- {"leftfirewall", KW_LEFTFIREWALL},
- {""},
- {"auto", KW_AUTO},
- {"klipsdebug", KW_KLIPSDEBUG},
- {"keyingtries", KW_KEYINGTRIES},
- {"keylife", KW_KEYLIFE},
- {"nat_traversal", KW_NAT_TRAVERSAL},
- {"cachecrls", KW_CACHECRLS},
- {"plutodebug", KW_PLUTODEBUG},
- {"keyexchange", KW_KEYEXCHANGE},
- {"ocspuri", KW_OCSPURI},
- {"rightfirewall", KW_RIGHTFIREWALL},
- {"uniqueids", KW_UNIQUEIDS},
- {""},
- {"leftca", KW_LEFTCA},
- {"pkcs11module", KW_PKCS11MODULE},
- {""},
- {"also", KW_ALSO},
- {"pkcs11keepstate", KW_PKCS11KEEPSTATE},
- {""},
- {"crluri2", KW_CRLURI2},
- {"ldaphost", KW_LDAPHOST},
- {"postpluto", KW_POSTPLUTO},
- {"xauth", KW_XAUTH},
- {"overridemtu", KW_OVERRIDEMTU},
- {"rightca", KW_RIGHTCA},
- {"prepluto", KW_PREPLUTO},
- {""}, {""}, {""}, {""},
- {"dpddelay", KW_DPDDELAY},
- {""}, {""}, {""}, {""},
- {"nocrsend", KW_NOCRSEND},
- {""}, {""}, {""}, {""},
- {"ldapbase", KW_LDAPBASE},
- {""},
- {"rekey", KW_REKEY},
- {"pkcs11proxy", KW_PKCS11PROXY},
- {""}, {""}, {""}, {""}, {""}, {""},
- {"fragicmp", KW_FRAGICMP},
- {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"crluri", KW_CRLURI},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""},
- {"crlcheckinterval", KW_CRLCHECKINTERVAL}
- };
-
-#ifdef __GNUC__
-__inline
-#endif
-const struct kw_entry *
-in_word_set (str, len)
- register const char *str;
- register unsigned int len;
-{
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = hash (str, len);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register const char *s = wordlist[key].name;
-
- if (*str == *s && !strcmp (str + 1, s + 1))
- return &wordlist[key];
- }
- }
- return 0;
-}
diff --git a/programs/starter/keywords.h b/programs/starter/keywords.h
deleted file mode 100644
index 4356b4947..000000000
--- a/programs/starter/keywords.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* strongSwan keywords
- * Copyright (C) 2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: keywords.h,v 1.10 2007/01/11 21:27:27 as Exp $
- */
-
-#ifndef _KEYWORDS_H_
-#define _KEYWORDS_H_
-
-typedef enum {
- /* config setup keywords */
- KW_INTERFACES,
- KW_DUMPDIR,
-
- /* pluto keywords */
- KW_PLUTODEBUG,
- KW_PREPLUTO,
- KW_POSTPLUTO,
- KW_UNIQUEIDS,
- KW_OVERRIDEMTU,
- KW_CRLCHECKINTERVAL,
- KW_CACHECRLS,
- KW_STRICTCRLPOLICY,
- KW_NOCRSEND,
- KW_NAT_TRAVERSAL,
- KW_KEEP_ALIVE,
- KW_VIRTUAL_PRIVATE,
- KW_PKCS11MODULE,
- KW_PKCS11KEEPSTATE,
- KW_PKCS11PROXY,
-
-#define KW_PLUTO_FIRST KW_PLUTODEBUG
-#define KW_PLUTO_LAST KW_PKCS11PROXY
-
- /* KLIPS keywords */
- KW_KLIPSDEBUG,
- KW_FRAGICMP,
- KW_PACKETDEFAULT,
- KW_HIDETOS,
-
-#define KW_KLIPS_FIRST KW_KLIPSDEBUG
-#define KW_KLIPS_LAST KW_HIDETOS
-
-#define KW_SETUP_FIRST KW_INTERFACES
-#define KW_SETUP_LAST KW_HIDETOS
-
- /* conn section keywords */
- KW_CONN_NAME,
- KW_CONN_SETUP,
- KW_KEYEXCHANGE,
- KW_TYPE,
- KW_PFS,
- KW_COMPRESS,
- KW_AUTH,
- KW_AUTHBY,
- KW_IKELIFETIME,
- KW_KEYLIFE,
- KW_REKEYMARGIN,
- KW_KEYINGTRIES,
- KW_REKEYFUZZ,
- KW_REKEY,
- KW_IKE,
- KW_ESP,
- KW_PFSGROUP,
- KW_DPDDELAY,
- KW_DPDTIMEOUT,
- KW_DPDACTION,
- KW_MODECONFIG,
- KW_XAUTH,
-
-#define KW_CONN_FIRST KW_CONN_SETUP
-#define KW_CONN_LAST KW_XAUTH
-
- /* ca section keywords */
- KW_CA_NAME,
- KW_CA_SETUP,
- KW_CACERT,
- KW_LDAPHOST,
- KW_LDAPBASE,
- KW_CRLURI,
- KW_CRLURI2,
- KW_OCSPURI,
-
-#define KW_CA_FIRST KW_CA_SETUP
-#define KW_CA_LAST KW_OCSPURI
-
- /* end keywords */
- KW_HOST,
- KW_NEXTHOP,
- KW_SUBNET,
- KW_SUBNETWITHIN,
- KW_PROTOPORT,
- KW_SOURCEIP,
- KW_NATIP,
- KW_FIREWALL,
- KW_HOSTACCESS,
- KW_UPDOWN,
- KW_ID,
- KW_RSASIGKEY,
- KW_CERT,
- KW_SENDCERT,
- KW_CA,
- KW_GROUPS,
- KW_IFACE,
-
-#define KW_END_FIRST KW_HOST
-#define KW_END_LAST KW_IFACE
-
- /* left end keywords */
- KW_LEFT,
- KW_LEFTNEXTHOP,
- KW_LEFTSUBNET,
- KW_LEFTSUBNETWITHIN,
- KW_LEFTPROTOPORT,
- KW_LEFTSOURCEIP,
- KW_LEFTNATIP,
- KW_LEFTFIREWALL,
- KW_LEFTHOSTACCESS,
- KW_LEFTUPDOWN,
- KW_LEFTID,
- KW_LEFTRSASIGKEY,
- KW_LEFTCERT,
- KW_LEFTSENDCERT,
- KW_LEFTCA,
- KW_LEFTGROUPS,
-
-#define KW_LEFT_FIRST KW_LEFT
-#define KW_LEFT_LAST KW_LEFTGROUPS
-
- /* right end keywords */
- KW_RIGHT,
- KW_RIGHTNEXTHOP,
- KW_RIGHTSUBNET,
- KW_RIGHTSUBNETWITHIN,
- KW_RIGHTPROTOPORT,
- KW_RIGHTSOURCEIP,
- KW_RIGHTNATIP,
- KW_RIGHTFIREWALL,
- KW_RIGHTHOSTACCESS,
- KW_RIGHTUPDOWN,
- KW_RIGHTID,
- KW_RIGHTRSASIGKEY,
- KW_RIGHTCERT,
- KW_RIGHTSENDCERT,
- KW_RIGHTCA,
- KW_RIGHTGROUPS,
-
-#define KW_RIGHT_FIRST KW_RIGHT
-#define KW_RIGHT_LAST KW_RIGHTGROUPS
-
- /* general section keywords */
- KW_ALSO,
- KW_AUTO
-
-} kw_token_t;
-
-#endif /* _KEYWORDS_H_ */
-
diff --git a/programs/starter/keywords.txt b/programs/starter/keywords.txt
deleted file mode 100644
index 6ad2d5fce..000000000
--- a/programs/starter/keywords.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-%{
-/* strongSwan keywords
- * Copyright (C) 2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: keywords.txt,v 1.8 2007/01/11 21:27:51 as Exp $
- */
-
-#include <string.h>
-
-#include "keywords.h"
-
-%}
-struct kw_entry {
- char *name;
- kw_token_t token;
-};
-%%
-interfaces, KW_INTERFACES
-klipsdebug, KW_KLIPSDEBUG
-plutodebug, KW_PLUTODEBUG
-dumpdir, KW_DUMPDIR
-prepluto, KW_PREPLUTO
-postpluto, KW_POSTPLUTO
-fragicmp, KW_FRAGICMP
-packetdefault, KW_PACKETDEFAULT
-hidetos, KW_HIDETOS
-uniqueids, KW_UNIQUEIDS
-overridemtu, KW_OVERRIDEMTU
-crlcheckinterval, KW_CRLCHECKINTERVAL
-cachecrls, KW_CACHECRLS
-strictcrlpolicy, KW_STRICTCRLPOLICY
-nocrsend, KW_NOCRSEND
-nat_traversal, KW_NAT_TRAVERSAL
-keep_alive, KW_KEEP_ALIVE
-virtual_private, KW_VIRTUAL_PRIVATE
-pkcs11module, KW_PKCS11MODULE
-pkcs11keepstate, KW_PKCS11KEEPSTATE
-pkcs11proxy, KW_PKCS11PROXY
-keyexchange, KW_KEYEXCHANGE
-type, KW_TYPE
-pfs, KW_PFS
-compress, KW_COMPRESS
-auth, KW_AUTH
-authby, KW_AUTHBY
-keylife, KW_KEYLIFE
-rekeymargin, KW_REKEYMARGIN
-ikelifetime, KW_IKELIFETIME
-keyingtries, KW_KEYINGTRIES
-rekeyfuzz, KW_REKEYFUZZ
-rekey, KW_REKEY
-esp, KW_ESP
-ike, KW_IKE
-pfsgroup, KW_PFSGROUP
-dpddelay, KW_DPDDELAY
-dpdtimeout, KW_DPDTIMEOUT
-dpdaction, KW_DPDACTION
-modeconfig, KW_MODECONFIG
-xauth, KW_XAUTH
-cacert, KW_CACERT
-ldaphost, KW_LDAPHOST
-ldapbase, KW_LDAPBASE
-crluri, KW_CRLURI
-crluri2, KW_CRLURI2
-ocspuri, KW_OCSPURI
-left, KW_LEFT
-leftnexthop, KW_LEFTNEXTHOP
-leftsubnet, KW_LEFTSUBNET
-leftsubnetwithin, KW_LEFTSUBNETWITHIN
-leftprotoport, KW_LEFTPROTOPORT
-leftsourceip, KW_LEFTSOURCEIP
-leftnatip, KW_LEFTNATIP
-leftfirewall, KW_LEFTFIREWALL
-lefthostaccess, KW_LEFTHOSTACCESS
-leftupdown, KW_LEFTUPDOWN
-leftid, KW_LEFTID
-leftrsasigkey, KW_LEFTRSASIGKEY
-leftcert, KW_LEFTCERT,
-leftsendcert, KW_LEFTSENDCERT
-leftca, KW_LEFTCA
-leftgroups, KW_LEFTGROUPS
-right, KW_RIGHT
-rightnexthop, KW_RIGHTNEXTHOP
-rightsubnet, KW_RIGHTSUBNET
-rightsubnetwithin, KW_RIGHTSUBNETWITHIN
-rightprotoport, KW_RIGHTPROTOPORT
-rightsourceip, KW_RIGHTSOURCEIP
-rightnatip, KW_RIGHTNATIP
-rightfirewall, KW_RIGHTFIREWALL
-righthostaccess, KW_RIGHTHOSTACCESS
-rightupdown, KW_RIGHTUPDOWN
-rightid, KW_RIGHTID
-rightrsasigkey, KW_RIGHTRSASIGKEY
-rightcert, KW_RIGHTCERT
-rightsendcert, KW_RIGHTSENDCERT
-rightca, KW_RIGHTCA
-rightgroups, KW_RIGHTGROUPS
-also, KW_ALSO
-auto, KW_AUTO
diff --git a/programs/starter/klips.c b/programs/starter/klips.c
deleted file mode 100644
index 5595eb6eb..000000000
--- a/programs/starter/klips.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* strongSwan KLIPS starter
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: klips.c,v 1.8 2006/02/15 18:33:57 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "confread.h"
-#include "klips.h"
-#include "files.h"
-#include "exec.h"
-
-static int _klips_module_loaded = 0;
-
-bool
-starter_klips_init(void)
-{
- struct stat stb;
-
- if (stat(PROC_IPSECVERSION, &stb) != 0)
- {
- if (stat(PROC_MODULES, &stb) == 0)
- {
- unsetenv("MODPATH");
- unsetenv("MODULECONF");
- system("depmod -a >/dev/null 2>&1");
- system("modprobe -qv ipsec");
- }
- if (stat(PROC_IPSECVERSION, &stb) == 0)
- {
- _klips_module_loaded = 1;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("kernel appears to lack KLIPS")
- )
- return FALSE;
- }
- }
-
- /* make sure that all available crypto algorithms are loaded */
- if (stat(PROC_MODULES, &stb) == 0)
- {
- system("modprobe -qv ipsec_aes");
- system("modprobe -qv ipsec_serpent");
- system("modprobe -qv ipsec_twofish");
- system("modprobe -qv ipsec_blowfish");
- system("modprobe -qv ipsec_sha2");
- }
-
- starter_klips_clear();
-
- DBG(DBG_CONTROL,
- DBG_log("Found KLIPS IPsec stack")
- )
- return TRUE;
-}
-
-static void
-_sysflags (char *name, int value)
-{
- int res = starter_exec("echo %d >%s/%s 2>/dev/null"
- , value? 1 : 0, PROC_SYSFLAGS, name);
-
- if (res)
- plog("can't set sysflag %s to %d", name, value? 1 : 0);
-}
-
-void
-starter_klips_set_config(starter_config_t *cfg)
-{
- char **l;
-
- _sysflags("icmp", cfg->setup.fragicmp);
- _sysflags("inbound_policy_check", 1);
- /* _sysflags("no_eroute_pass", 0); */
- /* _sysflags("opportunistic", 0); */
- _sysflags("tos", cfg->setup.hidetos);
-
- starter_exec("%s/klipsdebug --none", IPSEC_EXECDIR);
- for (l = cfg->setup.klipsdebug; l && *l; l++)
- {
- if ((streq(*l, "none")) || (streq(*l, "all")))
- starter_exec("%s/klipsdebug --%s", IPSEC_EXECDIR, *l);
- else
- starter_exec("%s/klipsdebug --set %s", IPSEC_EXECDIR, *l);
- }
-
- starter_exec("%s/eroute --del --eraf inet --src 0/0 --dst 0/0 2>/dev/null"
- , IPSEC_EXECDIR);
- starter_exec("%s/eroute --label packetdefault --replace --eraf inet "
- "--src 0/0 --dst 0/0 --said %%%s", IPSEC_EXECDIR
- , cfg->setup.packetdefault ? cfg->setup.packetdefault : "drop");
-}
-
-void
-starter_klips_clear(void)
-{
- system(IPSEC_EXECDIR"/eroute --clear");
- system(IPSEC_EXECDIR"/spi --clear");
- system(IPSEC_EXECDIR"/klipsdebug --none");
-}
-
-void
-starter_klips_cleanup(void)
-{
- starter_klips_clear();
- if (_klips_module_loaded)
- {
- system("rmmod ipsec");
- _klips_module_loaded = 0;
- }
-}
diff --git a/programs/starter/klips.h b/programs/starter/klips.h
deleted file mode 100644
index d07c6cca4..000000000
--- a/programs/starter/klips.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* strongSwan klips initialization and cleanup
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: klips.h,v 1.2 2005/12/30 19:03:56 as Exp $
- */
-
-#ifndef _STARTER_KLIPS_H_
-#define _STARTER_KLIPS_H_
-
-extern bool starter_klips_init (void);
-extern void starter_klips_set_config (struct starter_config *);
-extern void starter_klips_cleanup (void);
-extern void starter_klips_clear (void);
-
-#endif /* _STARTER_KLIPS_H_ */
-
diff --git a/programs/starter/lex.yy.c b/programs/starter/lex.yy.c
deleted file mode 100644
index 2c0dd040a..000000000
--- a/programs/starter/lex.yy.c
+++ /dev/null
@@ -1,1966 +0,0 @@
-
-#line 3 "lex.yy.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = (yy_hold_char); \
- YY_RESTORE_YY_MORE_OFFSET \
- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr) )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart (FILE *input_file );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
-void yy_delete_buffer (YY_BUFFER_STATE b );
-void yy_flush_buffer (YY_BUFFER_STATE b );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
-
-void *yyalloc (yy_size_t );
-void *yyrealloc (void *,yy_size_t );
-void yyfree (void * );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- yyensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-typedef unsigned char YY_CHAR;
-
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[] );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- (yytext_ptr) = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
- (yy_hold_char) = *yy_cp; \
- *yy_cp = '\0'; \
- (yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 14
-#define YY_END_OF_BUFFER 15
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[47] =
- { 0,
- 0, 0, 15, 11, 2, 4, 13, 11, 3, 11,
- 11, 11, 11, 1, 11, 2, 0, 12, 11, 0,
- 4, 8, 11, 11, 11, 11, 1, 11, 11, 11,
- 11, 11, 7, 11, 11, 11, 11, 11, 6, 11,
- 5, 11, 11, 9, 10, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 4, 5, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 6, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 7, 1, 8, 9,
-
- 10, 11, 12, 1, 13, 1, 1, 14, 1, 15,
- 16, 17, 1, 18, 19, 20, 21, 22, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[23] =
- { 0,
- 1, 2, 3, 2, 1, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1
- } ;
-
-static yyconst flex_int16_t yy_base[51] =
- { 0,
- 0, 69, 70, 0, 67, 72, 64, 21, 72, 19,
- 52, 56, 55, 62, 0, 61, 58, 72, 34, 58,
- 72, 0, 45, 51, 38, 39, 54, 17, 41, 33,
- 34, 39, 0, 30, 33, 36, 27, 25, 0, 17,
- 0, 21, 15, 0, 0, 72, 28, 40, 42, 45
- } ;
-
-static yyconst flex_int16_t yy_def[51] =
- { 0,
- 46, 1, 46, 47, 46, 46, 48, 49, 46, 47,
- 47, 47, 47, 46, 47, 46, 48, 46, 49, 50,
- 46, 47, 47, 47, 47, 47, 46, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 0, 46, 46, 46, 46
- } ;
-
-static yyconst flex_int16_t yy_nxt[95] =
- { 0,
- 4, 5, 6, 7, 8, 9, 4, 10, 4, 4,
- 4, 4, 11, 4, 4, 4, 4, 4, 12, 4,
- 4, 13, 20, 21, 20, 22, 20, 32, 15, 45,
- 44, 33, 43, 42, 23, 20, 21, 20, 41, 20,
- 17, 17, 19, 19, 19, 20, 20, 20, 40, 39,
- 38, 37, 36, 35, 34, 27, 31, 30, 29, 28,
- 21, 18, 16, 27, 26, 25, 24, 18, 16, 46,
- 14, 3, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46
-
- } ;
-
-static yyconst flex_int16_t yy_chk[95] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 8, 8, 8, 10, 8, 28, 47, 43,
- 42, 28, 40, 38, 10, 19, 19, 19, 37, 19,
- 48, 48, 49, 49, 49, 50, 50, 50, 36, 35,
- 34, 32, 31, 30, 29, 27, 26, 25, 24, 23,
- 20, 17, 16, 14, 13, 12, 11, 7, 5, 3,
- 2, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46
-
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "parser.l"
-#line 2 "parser.l"
-/* FreeS/WAN config file parser (parser.l)
- * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: lex.yy.c,v 1.6 2007/01/14 18:37:25 as Exp $
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <glob.h>
-
-#include "parser.tab.h"
-
-#define MAX_INCLUDE_DEPTH 20
-
-#define YY_NO_UNPUT
-extern void yyerror(const char *);
-extern int yylex (void);
-
-static struct {
- int stack_ptr;
- YY_BUFFER_STATE stack[MAX_INCLUDE_DEPTH];
- FILE *file[MAX_INCLUDE_DEPTH];
- unsigned int line[MAX_INCLUDE_DEPTH];
- char *filename[MAX_INCLUDE_DEPTH];
-} __parser_y_private;
-
-void _parser_y_error(char *b, int size, const char *s);
-void _parser_y_init (const char *f);
-void _parser_y_fini (void);
-int _parser_y_include (const char *filename);
-
-void _parser_y_error(char *b, int size, const char *s)
-{
- extern char *yytext; // was: char yytext[];
-
- snprintf(b, size, "%s:%d: %s [%s]",
- __parser_y_private.filename[__parser_y_private.stack_ptr],
- __parser_y_private.line[__parser_y_private.stack_ptr],
- s, yytext);
-}
-
-void _parser_y_init (const char *f)
-{
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
- __parser_y_private.line[0] = 1;
- __parser_y_private.filename[0] = strdup(f);
-}
-
-void _parser_y_fini (void)
-{
- unsigned int i;
-
- for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
- {
- if (__parser_y_private.filename[i])
- free(__parser_y_private.filename[i]);
- if (__parser_y_private.file[i])
- fclose(__parser_y_private.file[i]);
- }
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
-}
-
-int _parser_y_include (const char *filename)
-{
- glob_t files;
- int i, ret;
-
- ret = glob(filename, GLOB_ERR, NULL, &files);
- if (ret)
- {
- const char *err;
-
- switch (ret)
- {
- case GLOB_NOSPACE:
- err = "include files ran out of memory";
- break;
- case GLOB_ABORTED:
- err = "include files aborted due to read error";
- break;
- case GLOB_NOMATCH:
- err = "include files found no matches";
- break;
- default:
- err = "unknown include files error";
- }
- yyerror(err);
- return 1;
- }
-
- for (i = 0; i < files.gl_pathc; i++)
- {
- FILE *f;
- unsigned int p = __parser_y_private.stack_ptr + 1;
-
- if (p >= MAX_INCLUDE_DEPTH)
- {
- yyerror("max inclusion depth reached");
- return 1;
- }
-
- f = fopen(files.gl_pathv[i], "r");
- if (!f)
- {
- yyerror("can't open include filename");
- continue;
- }
-
- __parser_y_private.stack_ptr++;
- __parser_y_private.file[p] = f;
- __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
- __parser_y_private.line[p] = 1;
- __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
-
- yy_switch_to_buffer(yy_create_buffer(f,YY_BUF_SIZE));
- }
- globfree(&files);
- return 0;
-}
-
-#line 618 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr );
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- if ( yyleng > 0 ) \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
- (yytext[yyleng - 1] == '\n'); \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
-
-#line 134 "parser.l"
-
-
-#line 777 "lex.yy.c"
-
- if ( !(yy_init) )
- {
- (yy_init) = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! (yy_start) )
- (yy_start) = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE );
- }
-
- yy_load_buffer_state( );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = (yy_c_buf_p);
-
- /* Support of yytext. */
- *yy_cp = (yy_hold_char);
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = (yy_start);
- yy_current_state += YY_AT_BOL();
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 47 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 72 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = (yy_hold_char);
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- goto yy_find_action;
-
-case YY_STATE_EOF(INITIAL):
-#line 136 "parser.l"
-{
- if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
- free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
- __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
- }
- if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
- fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
- __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
- yy_delete_buffer (YY_CURRENT_BUFFER);
- yy_switch_to_buffer
- (__parser_y_private.stack[__parser_y_private.stack_ptr]);
- }
- if (--__parser_y_private.stack_ptr < 0) {
- yyterminate();
- }
-}
- YY_BREAK
-case 1:
-YY_RULE_SETUP
-#line 153 "parser.l"
-return FIRST_SPACES;
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 155 "parser.l"
-/* ignore spaces in line */ ;
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 157 "parser.l"
-return EQUAL;
- YY_BREAK
-case 4:
-/* rule 4 can match eol */
-YY_RULE_SETUP
-#line 159 "parser.l"
-{
- __parser_y_private.line[__parser_y_private.stack_ptr]++;
- return EOL;
- }
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 164 "parser.l"
-return CONFIG;
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 165 "parser.l"
-return SETUP;
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 166 "parser.l"
-return CONN;
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 167 "parser.l"
-return CA;
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 168 "parser.l"
-return INCLUDE;
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 169 "parser.l"
-return VERSION;
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 171 "parser.l"
-{
- yylval.s = strdup(yytext);
- return STRING;
- }
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 176 "parser.l"
-{
- yylval.s = strdup(yytext+1);
- if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
- return STRING;
- }
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 182 "parser.l"
-yyerror(yytext);
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 184 "parser.l"
-ECHO;
- YY_BREAK
-#line 961 "lex.yy.c"
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = (yy_hold_char);
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++(yy_c_buf_p);
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = (yy_c_buf_p);
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- (yy_did_buffer_switch_on_eof) = 0;
-
- if ( yywrap( ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) =
- (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- (yy_c_buf_p) =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = (yytext_ptr);
- register int number_to_move, i;
- int ret_val;
-
- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) ((yy_c_buf_p) - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- if ( (yy_n_chars) == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart(yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- (yy_n_chars) += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (void)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = (yy_start);
- yy_current_state += YY_AT_BOL();
-
- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 47 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
-{
- register int yy_is_jam;
- register char *yy_cp = (yy_c_buf_p);
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- (yy_last_accepting_state) = yy_current_state;
- (yy_last_accepting_cpos) = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 47 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 46);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp )
-{
- register char *yy_cp;
-
- yy_cp = (yy_c_buf_p);
-
- /* undo effects of setting up yytext */
- *yy_cp = (yy_hold_char);
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = (yy_n_chars) + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- (yytext_ptr) = yy_bp;
- (yy_hold_char) = *yy_cp;
- (yy_c_buf_p) = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (void)
-#else
- static int input (void)
-#endif
-
-{
- int c;
-
- *(yy_c_buf_p) = (yy_hold_char);
-
- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- /* This was really a NUL. */
- *(yy_c_buf_p) = '\0';
-
- else
- { /* need more input */
- int offset = (yy_c_buf_p) - (yytext_ptr);
- ++(yy_c_buf_p);
-
- switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart(yyin );
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap( ) )
- return EOF;
-
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) = (yytext_ptr) + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
- *(yy_c_buf_p) = '\0'; /* preserve yytext */
- (yy_hold_char) = *++(yy_c_buf_p);
-
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- *
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void yyrestart (FILE * input_file )
-{
-
- if ( ! YY_CURRENT_BUFFER ){
- yyensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE );
- }
-
- yy_init_buffer(YY_CURRENT_BUFFER,input_file );
- yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- *
- */
- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
-{
-
- /* TODO. We should be able to replace this entire function body
- * with
- * yypop_buffer_state();
- * yypush_buffer_state(new_buffer);
- */
- yyensure_buffer_stack ();
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state( );
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state (void)
-{
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- (yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- *
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer(b,file );
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- *
- */
- void yy_delete_buffer (YY_BUFFER_STATE b )
-{
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yyfree((void *) b->yy_ch_buf );
-
- yyfree((void *) b );
-}
-
-#ifndef _UNISTD_H /* assume unistd.h has isatty() for us */
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __THROW /* this is a gnuism */
-extern int isatty (int ) __THROW;
-#else
-extern int isatty (int );
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
-
-{
- int oerrno = errno;
-
- yy_flush_buffer(b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then yy_init_buffer was _probably_
- * called from yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
- */
- void yy_flush_buffer (YY_BUFFER_STATE b )
-{
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- *
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
- if (new_buffer == NULL)
- return;
-
- yyensure_buffer_stack();
-
- /* This block is copied from yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- (yy_buffer_stack_top)++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from yy_switch_to_buffer. */
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- *
- */
-void yypop_buffer_state (void)
-{
- if (!YY_CURRENT_BUFFER)
- return;
-
- yy_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if ((yy_buffer_stack_top) > 0)
- --(yy_buffer_stack_top);
-
- if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
- int num_to_alloc;
-
- if (!(yy_buffer_stack)) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- );
-
- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- (yy_buffer_stack_max) = num_to_alloc;
- (yy_buffer_stack_top) = 0;
- return;
- }
-
- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = (yy_buffer_stack_max) + grow_size;
- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
- ((yy_buffer_stack),
- num_to_alloc * sizeof(struct yy_buffer_state*)
- );
-
- /* zero only the new slots.*/
- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
- (yy_buffer_stack_max) = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer(b );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- *
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-
- return yy_scan_bytes(yystr,strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) yyalloc(n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer(buf,n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = (yy_hold_char); \
- (yy_c_buf_p) = yytext + yyless_macro_arg; \
- (yy_hold_char) = *(yy_c_buf_p); \
- *(yy_c_buf_p) = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- *
- */
-int yyget_lineno (void)
-{
-
- return yylineno;
-}
-
-/** Get the input stream.
- *
- */
-FILE *yyget_in (void)
-{
- return yyin;
-}
-
-/** Get the output stream.
- *
- */
-FILE *yyget_out (void)
-{
- return yyout;
-}
-
-/** Get the length of the current token.
- *
- */
-int yyget_leng (void)
-{
- return yyleng;
-}
-
-/** Get the current token.
- *
- */
-
-char *yyget_text (void)
-{
- return yytext;
-}
-
-/** Set the current line number.
- * @param line_number
- *
- */
-void yyset_lineno (int line_number )
-{
-
- yylineno = line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- *
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE * in_str )
-{
- yyin = in_str ;
-}
-
-void yyset_out (FILE * out_str )
-{
- yyout = out_str ;
-}
-
-int yyget_debug (void)
-{
- return yy_flex_debug;
-}
-
-void yyset_debug (int bdebug )
-{
- yy_flex_debug = bdebug ;
-}
-
-static int yy_init_globals (void)
-{
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from yylex_destroy(), so don't allocate here.
- */
-
- (yy_buffer_stack) = 0;
- (yy_buffer_stack_top) = 0;
- (yy_buffer_stack_max) = 0;
- (yy_c_buf_p) = (char *) 0;
- (yy_init) = 0;
- (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * yylex_init()
- */
- return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy (void)
-{
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- yy_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- yypop_buffer_state();
- }
-
- /* Destroy the stack itself. */
- yyfree((yy_buffer_stack) );
- (yy_buffer_stack) = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * yylex() is called, initialization will occur. */
- yy_init_globals( );
-
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *yyalloc (yy_size_t size )
-{
- return (void *) malloc( size );
-}
-
-void *yyrealloc (void * ptr, yy_size_t size )
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 184 "parser.l"
-
-
-
-int yywrap(void)
-{
- return 1;
-}
-
-
diff --git a/programs/starter/netkey.c b/programs/starter/netkey.c
deleted file mode 100644
index d0b8e0a2c..000000000
--- a/programs/starter/netkey.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* strongSwan netkey starter
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: netkey.c,v 1.4 2006/02/15 18:33:57 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "files.h"
-
-bool
-starter_netkey_init(void)
-{
- struct stat stb;
-
- if (stat(PROC_NETKEY, &stb) != 0)
- {
- /* af_key module makes the netkey proc interface visible */
- if (stat(PROC_MODULES, &stb) == 0)
- {
- system("modprobe -qv af_key");
- }
-
- /* now test again */
- if (stat(PROC_NETKEY, &stb) != 0)
- {
- DBG(DBG_CONTROL,
- DBG_log("kernel appears to lack the native netkey IPsec stack")
- )
- return FALSE;
- }
- }
-
- /* make sure that all required IPsec modules are loaded */
- if (stat(PROC_MODULES, &stb) == 0)
- {
- system("modprobe -qv ah4");
- system("modprobe -qv esp4");
- system("modprobe -qv ipcomp");
- system("modprobe -qv xfrm4_tunnel");
- system("modprobe -qv xfrm_user");
- }
-
- DBG(DBG_CONTROL,
- DBG_log("Found netkey IPsec stack")
- )
- return TRUE;
-}
-
-void
-starter_netkey_cleanup(void)
-{
- if (system("ip xfrm state > /dev/null 2>&1") == 0)
- {
- system("ip xfrm state flush");
- system("ip xfrm policy flush");
- }
- else if (system("type setkey > /dev/null 2>&1") == 0)
- {
- system("setkey -F");
- system("setkey -FP");
- }
- else
- {
- plog("WARNING: cannot flush IPsec state/policy database");
- }
-}
diff --git a/programs/starter/netkey.h b/programs/starter/netkey.h
deleted file mode 100644
index ff8989d34..000000000
--- a/programs/starter/netkey.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* strongSwan netkey initialization and cleanup
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: netkey.h,v 1.1 2005/12/30 19:03:15 as Exp $
- */
-
-#ifndef _STARTER_NETKEY_H_
-#define _STARTER_NETKEY_H_
-
-extern bool starter_netkey_init (void);
-extern void starter_netkey_cleanup (void);
-
-#endif /* _STARTER_NETKEY_H_ */
-
diff --git a/programs/starter/parser.h b/programs/starter/parser.h
deleted file mode 100644
index 61bdea974..000000000
--- a/programs/starter/parser.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* strongSwan config file parser
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: parser.h,v 1.5 2006/01/17 23:43:36 as Exp $
- */
-
-#ifndef _IPSEC_PARSER_H_
-#define _IPSEC_PARSER_H_
-
-#include "keywords.h"
-
-typedef struct kw_entry kw_entry_t;
-
-struct kw_entry {
- char *name;
- kw_token_t token;
-};
-
-typedef struct kw_list kw_list_t;
-
-struct kw_list {
- kw_entry_t *entry;
- char *value;
- kw_list_t *next;
-};
-
-typedef struct section_list section_list_t;
-
-struct section_list {
- char *name;
- kw_list_t *kw;
- section_list_t *next;
-};
-
-typedef struct config_parsed config_parsed_t;
-
-struct config_parsed {
- kw_list_t *config_setup;
- section_list_t *conn_first, *conn_last;
- section_list_t *ca_first, *ca_last;
-};
-
-config_parsed_t *parser_load_conf (const char *file);
-void parser_free_conf (config_parsed_t *cfg);
-
-#endif /* _IPSEC_PARSER_H_ */
-
diff --git a/programs/starter/parser.l b/programs/starter/parser.l
deleted file mode 100644
index 8d1cc4c31..000000000
--- a/programs/starter/parser.l
+++ /dev/null
@@ -1,190 +0,0 @@
-%{
-/* FreeS/WAN config file parser (parser.l)
- * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: parser.l,v 1.5 2006/03/28 22:32:33 as Exp $
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <glob.h>
-
-#include "parser.tab.h"
-
-#define MAX_INCLUDE_DEPTH 20
-
-#define YY_NO_UNPUT
-extern void yyerror(const char *);
-extern int yylex (void);
-
-static struct {
- int stack_ptr;
- YY_BUFFER_STATE stack[MAX_INCLUDE_DEPTH];
- FILE *file[MAX_INCLUDE_DEPTH];
- unsigned int line[MAX_INCLUDE_DEPTH];
- char *filename[MAX_INCLUDE_DEPTH];
-} __parser_y_private;
-
-void _parser_y_error(char *b, int size, const char *s);
-void _parser_y_init (const char *f);
-void _parser_y_fini (void);
-int _parser_y_include (const char *filename);
-
-void _parser_y_error(char *b, int size, const char *s)
-{
- extern char *yytext; // was: char yytext[];
-
- snprintf(b, size, "%s:%d: %s [%s]",
- __parser_y_private.filename[__parser_y_private.stack_ptr],
- __parser_y_private.line[__parser_y_private.stack_ptr],
- s, yytext);
-}
-
-void _parser_y_init (const char *f)
-{
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
- __parser_y_private.line[0] = 1;
- __parser_y_private.filename[0] = strdup(f);
-}
-
-void _parser_y_fini (void)
-{
- unsigned int i;
-
- for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
- {
- if (__parser_y_private.filename[i])
- free(__parser_y_private.filename[i]);
- if (__parser_y_private.file[i])
- fclose(__parser_y_private.file[i]);
- }
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
-}
-
-int _parser_y_include (const char *filename)
-{
- glob_t files;
- int i, ret;
-
- ret = glob(filename, GLOB_ERR, NULL, &files);
- if (ret)
- {
- const char *err;
-
- switch (ret)
- {
- case GLOB_NOSPACE:
- err = "include files ran out of memory";
- break;
- case GLOB_ABORTED:
- err = "include files aborted due to read error";
- break;
- case GLOB_NOMATCH:
- err = "include files found no matches";
- break;
- default:
- err = "unknown include files error";
- }
- yyerror(err);
- return 1;
- }
-
- for (i = 0; i < files.gl_pathc; i++)
- {
- FILE *f;
- unsigned int p = __parser_y_private.stack_ptr + 1;
-
- if (p >= MAX_INCLUDE_DEPTH)
- {
- yyerror("max inclusion depth reached");
- return 1;
- }
-
- f = fopen(files.gl_pathv[i], "r");
- if (!f)
- {
- yyerror("can't open include filename");
- continue;
- }
-
- __parser_y_private.stack_ptr++;
- __parser_y_private.file[p] = f;
- __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
- __parser_y_private.line[p] = 1;
- __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
-
- yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
- }
- globfree(&files);
- return 0;
-}
-
-%}
-
-%%
-
-<<EOF>> {
- if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
- free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
- __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
- }
- if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
- fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
- __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
- yy_delete_buffer (YY_CURRENT_BUFFER);
- yy_switch_to_buffer
- (__parser_y_private.stack[__parser_y_private.stack_ptr]);
- }
- if (--__parser_y_private.stack_ptr < 0) {
- yyterminate();
- }
-}
-
-^[\t ]+ return FIRST_SPACES;
-
-[\t ]+ /* ignore spaces in line */ ;
-
-= return EQUAL;
-
-\n|#.*\n {
- __parser_y_private.line[__parser_y_private.stack_ptr]++;
- return EOL;
- }
-
-config return CONFIG;
-setup return SETUP;
-conn return CONN;
-ca return CA;
-include return INCLUDE;
-version return VERSION;
-
-[^\"= \t\n]+ {
- yylval.s = strdup(yytext);
- return STRING;
- }
-
-\"[^\"\n]*\" {
- yylval.s = strdup(yytext+1);
- if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
- return STRING;
- }
-
-. yyerror(yytext);
-
-%%
-
-int yywrap(void)
-{
- return 1;
-}
-
diff --git a/programs/starter/parser.output b/programs/starter/parser.output
deleted file mode 100644
index ddb01e89a..000000000
--- a/programs/starter/parser.output
+++ /dev/null
@@ -1,351 +0,0 @@
-Grammar
-
- 0 $accept: config_file $end
-
- 1 config_file: config_file section_or_include
- 2 | /* empty */
-
- 3 section_or_include: VERSION STRING EOL
-
- 4 @1: /* empty */
-
- 5 section_or_include: CONFIG SETUP EOL @1 kw_section
-
- 6 @2: /* empty */
-
- 7 section_or_include: CONN STRING EOL @2 kw_section
-
- 8 @3: /* empty */
-
- 9 section_or_include: CA STRING EOL @3 kw_section
-
- 10 @4: /* empty */
-
- 11 section_or_include: INCLUDE STRING @4 EOL
- 12 | EOL
-
- 13 kw_section: FIRST_SPACES statement_kw EOL kw_section
- 14 | /* empty */
-
- 15 statement_kw: STRING EQUAL STRING
- 16 | STRING EQUAL
- 17 | /* empty */
-
-
-Terminals, with rules where they appear
-
-$end (0) 0
-error (256)
-EQUAL (258) 15 16
-FIRST_SPACES (259) 13
-EOL (260) 3 5 7 9 11 12 13
-CONFIG (261) 5
-SETUP (262) 5
-CONN (263) 7
-CA (264) 9
-INCLUDE (265) 11
-VERSION (266) 3
-STRING (267) 3 7 9 11 15 16
-
-
-Nonterminals, with rules where they appear
-
-$accept (13)
- on left: 0
-config_file (14)
- on left: 1 2, on right: 0 1
-section_or_include (15)
- on left: 3 5 7 9 11 12, on right: 1
-@1 (16)
- on left: 4, on right: 5
-@2 (17)
- on left: 6, on right: 7
-@3 (18)
- on left: 8, on right: 9
-@4 (19)
- on left: 10, on right: 11
-kw_section (20)
- on left: 13 14, on right: 5 7 9 13
-statement_kw (21)
- on left: 15 16 17, on right: 13
-
-
-state 0
-
- 0 $accept: . config_file $end
-
- $default reduce using rule 2 (config_file)
-
- config_file go to state 1
-
-
-state 1
-
- 0 $accept: config_file . $end
- 1 config_file: config_file . section_or_include
-
- $end shift, and go to state 2
- EOL shift, and go to state 3
- CONFIG shift, and go to state 4
- CONN shift, and go to state 5
- CA shift, and go to state 6
- INCLUDE shift, and go to state 7
- VERSION shift, and go to state 8
-
- section_or_include go to state 9
-
-
-state 2
-
- 0 $accept: config_file $end .
-
- $default accept
-
-
-state 3
-
- 12 section_or_include: EOL .
-
- $default reduce using rule 12 (section_or_include)
-
-
-state 4
-
- 5 section_or_include: CONFIG . SETUP EOL @1 kw_section
-
- SETUP shift, and go to state 10
-
-
-state 5
-
- 7 section_or_include: CONN . STRING EOL @2 kw_section
-
- STRING shift, and go to state 11
-
-
-state 6
-
- 9 section_or_include: CA . STRING EOL @3 kw_section
-
- STRING shift, and go to state 12
-
-
-state 7
-
- 11 section_or_include: INCLUDE . STRING @4 EOL
-
- STRING shift, and go to state 13
-
-
-state 8
-
- 3 section_or_include: VERSION . STRING EOL
-
- STRING shift, and go to state 14
-
-
-state 9
-
- 1 config_file: config_file section_or_include .
-
- $default reduce using rule 1 (config_file)
-
-
-state 10
-
- 5 section_or_include: CONFIG SETUP . EOL @1 kw_section
-
- EOL shift, and go to state 15
-
-
-state 11
-
- 7 section_or_include: CONN STRING . EOL @2 kw_section
-
- EOL shift, and go to state 16
-
-
-state 12
-
- 9 section_or_include: CA STRING . EOL @3 kw_section
-
- EOL shift, and go to state 17
-
-
-state 13
-
- 11 section_or_include: INCLUDE STRING . @4 EOL
-
- $default reduce using rule 10 (@4)
-
- @4 go to state 18
-
-
-state 14
-
- 3 section_or_include: VERSION STRING . EOL
-
- EOL shift, and go to state 19
-
-
-state 15
-
- 5 section_or_include: CONFIG SETUP EOL . @1 kw_section
-
- $default reduce using rule 4 (@1)
-
- @1 go to state 20
-
-
-state 16
-
- 7 section_or_include: CONN STRING EOL . @2 kw_section
-
- $default reduce using rule 6 (@2)
-
- @2 go to state 21
-
-
-state 17
-
- 9 section_or_include: CA STRING EOL . @3 kw_section
-
- $default reduce using rule 8 (@3)
-
- @3 go to state 22
-
-
-state 18
-
- 11 section_or_include: INCLUDE STRING @4 . EOL
-
- EOL shift, and go to state 23
-
-
-state 19
-
- 3 section_or_include: VERSION STRING EOL .
-
- $default reduce using rule 3 (section_or_include)
-
-
-state 20
-
- 5 section_or_include: CONFIG SETUP EOL @1 . kw_section
-
- FIRST_SPACES shift, and go to state 24
-
- $default reduce using rule 14 (kw_section)
-
- kw_section go to state 25
-
-
-state 21
-
- 7 section_or_include: CONN STRING EOL @2 . kw_section
-
- FIRST_SPACES shift, and go to state 24
-
- $default reduce using rule 14 (kw_section)
-
- kw_section go to state 26
-
-
-state 22
-
- 9 section_or_include: CA STRING EOL @3 . kw_section
-
- FIRST_SPACES shift, and go to state 24
-
- $default reduce using rule 14 (kw_section)
-
- kw_section go to state 27
-
-
-state 23
-
- 11 section_or_include: INCLUDE STRING @4 EOL .
-
- $default reduce using rule 11 (section_or_include)
-
-
-state 24
-
- 13 kw_section: FIRST_SPACES . statement_kw EOL kw_section
-
- STRING shift, and go to state 28
-
- $default reduce using rule 17 (statement_kw)
-
- statement_kw go to state 29
-
-
-state 25
-
- 5 section_or_include: CONFIG SETUP EOL @1 kw_section .
-
- $default reduce using rule 5 (section_or_include)
-
-
-state 26
-
- 7 section_or_include: CONN STRING EOL @2 kw_section .
-
- $default reduce using rule 7 (section_or_include)
-
-
-state 27
-
- 9 section_or_include: CA STRING EOL @3 kw_section .
-
- $default reduce using rule 9 (section_or_include)
-
-
-state 28
-
- 15 statement_kw: STRING . EQUAL STRING
- 16 | STRING . EQUAL
-
- EQUAL shift, and go to state 30
-
-
-state 29
-
- 13 kw_section: FIRST_SPACES statement_kw . EOL kw_section
-
- EOL shift, and go to state 31
-
-
-state 30
-
- 15 statement_kw: STRING EQUAL . STRING
- 16 | STRING EQUAL .
-
- STRING shift, and go to state 32
-
- $default reduce using rule 16 (statement_kw)
-
-
-state 31
-
- 13 kw_section: FIRST_SPACES statement_kw EOL . kw_section
-
- FIRST_SPACES shift, and go to state 24
-
- $default reduce using rule 14 (kw_section)
-
- kw_section go to state 33
-
-
-state 32
-
- 15 statement_kw: STRING EQUAL STRING .
-
- $default reduce using rule 15 (statement_kw)
-
-
-state 33
-
- 13 kw_section: FIRST_SPACES statement_kw EOL kw_section .
-
- $default reduce using rule 13 (kw_section)
diff --git a/programs/starter/parser.tab.c b/programs/starter/parser.tab.c
deleted file mode 100644
index 6e0061f89..000000000
--- a/programs/starter/parser.tab.c
+++ /dev/null
@@ -1,1832 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.2. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.2"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 0
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EQUAL = 258,
- FIRST_SPACES = 259,
- EOL = 260,
- CONFIG = 261,
- SETUP = 262,
- CONN = 263,
- CA = 264,
- INCLUDE = 265,
- VERSION = 266,
- STRING = 267
- };
-#endif
-/* Tokens. */
-#define EQUAL 258
-#define FIRST_SPACES 259
-#define EOL 260
-#define CONFIG 261
-#define SETUP 262
-#define CONN 263
-#define CA 264
-#define INCLUDE 265
-#define VERSION 266
-#define STRING 267
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 1 "parser.y"
-
-/* strongSwan config file parser (parser.y)
- * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: parser.tab.c,v 1.7 2007/01/14 18:37:25 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-#include "parser.h"
-
-#define YYERROR_VERBOSE
-#define ERRSTRING_LEN 256
-
-/**
- * Bison
- */
-static char parser_errstring[ERRSTRING_LEN+1];
-
-extern void yyerror(const char *s);
-extern int yylex (void);
-extern void _parser_y_error(char *b, int size, const char *s);
-
-/**
- * Static Globals
- */
-static int _save_errors_;
-static config_parsed_t *_parser_cfg;
-static kw_list_t **_parser_kw, *_parser_kw_last;
-static char errbuf[ERRSTRING_LEN+1];
-
-/**
- * Gperf
- */
-extern kw_entry_t *in_word_set (char *str, unsigned int len);
-
-
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 56 "parser.y"
-{ char *s; }
-/* Line 193 of yacc.c. */
-#line 177 "parser.tab.c"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 216 of yacc.c. */
-#line 190 "parser.tab.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int i)
-#else
-static int
-YYID (i)
- int i;
-#endif
-{
- return i;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
- && ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
-# endif
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss;
- YYSTYPE yyvs;
- };
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack, Stack, yysize); \
- Stack = &yyptr->Stack; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 27
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 13
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 9
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 18
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 34
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 267
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint8 yyprhs[] =
-{
- 0, 0, 3, 6, 7, 11, 12, 18, 19, 25,
- 26, 32, 33, 38, 40, 45, 46, 50, 53
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 14, 0, -1, 14, 15, -1, -1, 11, 12, 5,
- -1, -1, 6, 7, 5, 16, 20, -1, -1, 8,
- 12, 5, 17, 20, -1, -1, 9, 12, 5, 18,
- 20, -1, -1, 10, 12, 19, 5, -1, 5, -1,
- 4, 21, 5, 20, -1, -1, 12, 3, 12, -1,
- 12, 3, -1, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
-{
- 0, 67, 67, 68, 72, 77, 76, 82, 81, 99,
- 98, 115, 114, 120, 124, 125, 129, 154, 158
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "EQUAL", "FIRST_SPACES", "EOL", "CONFIG",
- "SETUP", "CONN", "CA", "INCLUDE", "VERSION", "STRING", "$accept",
- "config_file", "section_or_include", "@1", "@2", "@3", "@4",
- "kw_section", "statement_kw", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 13, 14, 14, 15, 16, 15, 17, 15, 18,
- 15, 19, 15, 15, 20, 20, 21, 21, 21
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 2, 0, 3, 0, 5, 0, 5, 0,
- 5, 0, 4, 1, 4, 0, 3, 2, 0
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 3, 0, 1, 13, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 11, 0, 5, 7, 9, 0, 4,
- 15, 15, 15, 12, 18, 6, 8, 10, 0, 0,
- 17, 15, 16, 14
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
-{
- -1, 1, 9, 20, 21, 22, 18, 25, 29
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -20
-static const yytype_int8 yypact[] =
-{
- -20, 0, -20, -20, -6, -8, -5, 1, 2, -20,
- 10, 11, 12, -20, 13, -20, -20, -20, 14, -20,
- 16, 16, 16, -20, 9, -20, -20, -20, 19, 18,
- 15, 16, -20, -20
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int8 yypgoto[] =
-{
- -20, -20, -20, -20, -20, -20, -20, -19, -20
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
-static const yytype_uint8 yytable[] =
-{
- 2, 10, 26, 27, 11, 3, 4, 12, 5, 6,
- 7, 8, 33, 13, 14, 15, 16, 17, 19, 23,
- 24, 28, 30, 31, 0, 0, 0, 32
-};
-
-static const yytype_int8 yycheck[] =
-{
- 0, 7, 21, 22, 12, 5, 6, 12, 8, 9,
- 10, 11, 31, 12, 12, 5, 5, 5, 5, 5,
- 4, 12, 3, 5, -1, -1, -1, 12
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
- 0, 14, 0, 5, 6, 8, 9, 10, 11, 15,
- 7, 12, 12, 12, 12, 5, 5, 5, 19, 5,
- 16, 17, 18, 5, 4, 20, 20, 20, 12, 21,
- 3, 5, 12, 20
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-
-#define YYFAIL goto yyerrlab
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
-#else
-# define YYLEX yylex ()
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
-#endif
-{
- if (!yyvaluep)
- return;
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- const YYSTYPE * const yyvaluep;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-#else
-static void
-yy_stack_print (bottom, top)
- yytype_int16 *bottom;
- yytype_int16 *top;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; bottom <= top; ++bottom)
- YYFPRINTF (stderr, " %d", *bottom);
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp,
- int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule
- )
- YYSTYPE *yyvsp;
-
- int yyrule;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- fprintf (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
- fprintf (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYSIZE_T yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
-
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
-
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
-
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
-
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
- }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- YYUSE (yyvaluep);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-/* The look-ahead symbol. */
-int yychar;
-
-/* The semantic value of the look-ahead symbol. */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far. */
-int yynerrs;
-
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-
- int yystate;
- int yyn;
- int yyresult;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
- /* Look-ahead token as an internal (translated) token number. */
- int yytoken = 0;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
- /* Three stacks and their tools:
- `yyss': related to states,
- `yyvs': related to semantic values,
- `yyls': related to locations.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss = yyssa;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs = yyvsa;
- YYSTYPE *yyvsp;
-
-
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
-
- YYSIZE_T yystacksize = YYINITDEPTH;
-
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss;
- yyvsp = yyvs;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
-
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
-
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss);
- YYSTACK_RELOCATE (yyvs);
-
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
-
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- look-ahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to look-ahead token. */
- yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
- goto yydefault;
-
- /* Not known => get a look-ahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the look-ahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
-
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
-
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 4:
-#line 73 "parser.y"
- {
- free((yyvsp[(2) - (3)].s));
- ;}
- break;
-
- case 5:
-#line 77 "parser.y"
- {
- _parser_kw = &(_parser_cfg->config_setup);
- _parser_kw_last = NULL;
- ;}
- break;
-
- case 7:
-#line 82 "parser.y"
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
-
- section->name = clone_str((yyvsp[(2) - (3)].s), "conn section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->conn_first)
- _parser_cfg->conn_first = section;
- if (_parser_cfg->conn_last)
- _parser_cfg->conn_last->next = section;
- _parser_cfg->conn_last = section;
- _parser_kw_last = NULL;
- free((yyvsp[(2) - (3)].s));
- ;}
- break;
-
- case 9:
-#line 99 "parser.y"
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
- section->name = clone_str((yyvsp[(2) - (3)].s), "ca section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->ca_first)
- _parser_cfg->ca_first = section;
- if (_parser_cfg->ca_last)
- _parser_cfg->ca_last->next = section;
- _parser_cfg->ca_last = section;
- _parser_kw_last = NULL;
- free((yyvsp[(2) - (3)].s));
- ;}
- break;
-
- case 11:
-#line 115 "parser.y"
- {
- extern void _parser_y_include (const char *f);
- _parser_y_include((yyvsp[(2) - (2)].s));
- free((yyvsp[(2) - (2)].s));
- ;}
- break;
-
- case 16:
-#line 130 "parser.y"
- {
- kw_list_t *new;
- kw_entry_t *entry = in_word_set((yyvsp[(1) - (3)].s), strlen((yyvsp[(1) - (3)].s)));
-
- if (entry == NULL)
- {
- snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", (yyvsp[(1) - (3)].s));
- yyerror(errbuf);
- }
- else if (_parser_kw)
- {
- new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
- new->entry = entry;
- new->value = clone_str((yyvsp[(3) - (3)].s), "kw_list value");
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw)
- *_parser_kw = new;
- }
- free((yyvsp[(1) - (3)].s));
- free((yyvsp[(3) - (3)].s));
- ;}
- break;
-
- case 17:
-#line 155 "parser.y"
- {
- free((yyvsp[(1) - (2)].s));
- ;}
- break;
-
-
-/* Line 1267 of yacc.c. */
-#line 1496 "parser.tab.c"
- default: break;
- }
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
-#else
- {
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
- }
-#endif
- }
-
-
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse look-ahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval);
- yychar = YYEMPTY;
- }
- }
-
- /* Else will try to reuse look-ahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
-
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- *++yyvsp = yylval;
-
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#ifndef yyoverflow
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEOF && yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- return yyresult;
-}
-
-
-#line 161 "parser.y"
-
-
-void
-yyerror(const char *s)
-{
- if (_save_errors_)
- _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
-}
-
-config_parsed_t *
-parser_load_conf(const char *file)
-{
- config_parsed_t *cfg = NULL;
- int err = 0;
- FILE *f;
-
- extern void _parser_y_init (const char *f);
- extern FILE *yyin;
-
- memset(parser_errstring, 0, ERRSTRING_LEN+1);
-
- cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
- if (cfg)
- {
- memset(cfg, 0, sizeof(config_parsed_t));
- f = fopen(file, "r");
- if (f)
- {
- yyin = f;
- _parser_y_init(file);
- _save_errors_ = 1;
- _parser_cfg = cfg;
-
- if (yyparse() !=0 )
- {
- if (parser_errstring[0] == '\0')
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
- }
- _save_errors_ = 0;
- while (yyparse() != 0);
- err++;
- }
- else if (parser_errstring[0] != '\0')
- {
- err++;
- }
- else
- {
- /**
- * Config valid
- */
- }
-
- fclose(f);
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
- err++;
- }
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
- err++;
- }
-
- if (err)
- {
- plog("%s", parser_errstring);
-
- if (cfg)
- parser_free_conf(cfg);
- cfg = NULL;
- }
-
- return cfg;
-}
-
-static void
-parser_free_kwlist(kw_list_t *list)
-{
- kw_list_t *elt;
-
- while (list)
- {
- elt = list;
- list = list->next;
- if (elt->value)
- pfree(elt->value);
- pfree(elt);
- }
-}
-
-void
-parser_free_conf(config_parsed_t *cfg)
-{
- section_list_t *sec;
- if (cfg)
- {
- parser_free_kwlist(cfg->config_setup);
- while (cfg->conn_first)
- {
- sec = cfg->conn_first;
- cfg->conn_first = cfg->conn_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- while (cfg->ca_first)
- {
- sec = cfg->ca_first;
- cfg->ca_first = cfg->ca_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- pfree(cfg);
- }
-}
-
diff --git a/programs/starter/parser.tab.h b/programs/starter/parser.tab.h
deleted file mode 100644
index b6a810f51..000000000
--- a/programs/starter/parser.tab.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.2. */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EQUAL = 258,
- FIRST_SPACES = 259,
- EOL = 260,
- CONFIG = 261,
- SETUP = 262,
- CONN = 263,
- CA = 264,
- INCLUDE = 265,
- VERSION = 266,
- STRING = 267
- };
-#endif
-/* Tokens. */
-#define EQUAL 258
-#define FIRST_SPACES 259
-#define EOL 260
-#define CONFIG 261
-#define SETUP 262
-#define CONN 263
-#define CA 264
-#define INCLUDE 265
-#define VERSION 266
-#define STRING 267
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 56 "parser.y"
-{ char *s; }
-/* Line 1528 of yacc.c. */
-#line 75 "parser.tab.h"
- YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYSTYPE yylval;
-
diff --git a/programs/starter/parser.y b/programs/starter/parser.y
deleted file mode 100644
index 159bbc651..000000000
--- a/programs/starter/parser.y
+++ /dev/null
@@ -1,283 +0,0 @@
-%{
-/* strongSwan config file parser (parser.y)
- * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: parser.y,v 1.6 2006/01/17 23:43:36 as Exp $
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-#include "parser.h"
-
-#define YYERROR_VERBOSE
-#define ERRSTRING_LEN 256
-
-/**
- * Bison
- */
-static char parser_errstring[ERRSTRING_LEN+1];
-
-extern void yyerror(const char *s);
-extern int yylex (void);
-extern void _parser_y_error(char *b, int size, const char *s);
-
-/**
- * Static Globals
- */
-static int _save_errors_;
-static config_parsed_t *_parser_cfg;
-static kw_list_t **_parser_kw, *_parser_kw_last;
-static char errbuf[ERRSTRING_LEN+1];
-
-/**
- * Gperf
- */
-extern kw_entry_t *in_word_set (char *str, unsigned int len);
-
-%}
-
-%union { char *s; };
-%token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN CA INCLUDE VERSION
-%token <s> STRING
-
-%%
-
-/*
- * Config file
- */
-
-config_file:
- config_file section_or_include
- | /* NULL */
- ;
-
-section_or_include:
- VERSION STRING EOL
- {
- free($2);
- }
- | CONFIG SETUP EOL
- {
- _parser_kw = &(_parser_cfg->config_setup);
- _parser_kw_last = NULL;
- } kw_section
- | CONN STRING EOL
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
-
- section->name = clone_str($2, "conn section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->conn_first)
- _parser_cfg->conn_first = section;
- if (_parser_cfg->conn_last)
- _parser_cfg->conn_last->next = section;
- _parser_cfg->conn_last = section;
- _parser_kw_last = NULL;
- free($2);
- } kw_section
- | CA STRING EOL
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
- section->name = clone_str($2, "ca section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->ca_first)
- _parser_cfg->ca_first = section;
- if (_parser_cfg->ca_last)
- _parser_cfg->ca_last->next = section;
- _parser_cfg->ca_last = section;
- _parser_kw_last = NULL;
- free($2);
- } kw_section
- | INCLUDE STRING
- {
- extern void _parser_y_include (const char *f);
- _parser_y_include($2);
- free($2);
- } EOL
- | EOL
- ;
-
-kw_section:
- FIRST_SPACES statement_kw EOL kw_section
- |
- ;
-
-statement_kw:
- STRING EQUAL STRING
- {
- kw_list_t *new;
- kw_entry_t *entry = in_word_set($1, strlen($1));
-
- if (entry == NULL)
- {
- snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
- yyerror(errbuf);
- }
- else if (_parser_kw)
- {
- new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
- new->entry = entry;
- new->value = clone_str($3, "kw_list value");
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw)
- *_parser_kw = new;
- }
- free($1);
- free($3);
- }
- | STRING EQUAL
- {
- free($1);
- }
- |
- ;
-
-%%
-
-void
-yyerror(const char *s)
-{
- if (_save_errors_)
- _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
-}
-
-config_parsed_t *
-parser_load_conf(const char *file)
-{
- config_parsed_t *cfg = NULL;
- int err = 0;
- FILE *f;
-
- extern void _parser_y_init (const char *f);
- extern FILE *yyin;
-
- memset(parser_errstring, 0, ERRSTRING_LEN+1);
-
- cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
- if (cfg)
- {
- memset(cfg, 0, sizeof(config_parsed_t));
- f = fopen(file, "r");
- if (f)
- {
- yyin = f;
- _parser_y_init(file);
- _save_errors_ = 1;
- _parser_cfg = cfg;
-
- if (yyparse() !=0 )
- {
- if (parser_errstring[0] == '\0')
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
- }
- _save_errors_ = 0;
- while (yyparse() != 0);
- err++;
- }
- else if (parser_errstring[0] != '\0')
- {
- err++;
- }
- else
- {
- /**
- * Config valid
- */
- }
-
- fclose(f);
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
- err++;
- }
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
- err++;
- }
-
- if (err)
- {
- plog("%s", parser_errstring);
-
- if (cfg)
- parser_free_conf(cfg);
- cfg = NULL;
- }
-
- return cfg;
-}
-
-static void
-parser_free_kwlist(kw_list_t *list)
-{
- kw_list_t *elt;
-
- while (list)
- {
- elt = list;
- list = list->next;
- if (elt->value)
- pfree(elt->value);
- pfree(elt);
- }
-}
-
-void
-parser_free_conf(config_parsed_t *cfg)
-{
- section_list_t *sec;
- if (cfg)
- {
- parser_free_kwlist(cfg->config_setup);
- while (cfg->conn_first)
- {
- sec = cfg->conn_first;
- cfg->conn_first = cfg->conn_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- while (cfg->ca_first)
- {
- sec = cfg->ca_first;
- cfg->ca_first = cfg->ca_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- pfree(cfg);
- }
-}
diff --git a/programs/starter/starter.8 b/programs/starter/starter.8
deleted file mode 100644
index e69de29bb..000000000
--- a/programs/starter/starter.8
+++ /dev/null
diff --git a/programs/starter/starter.c b/programs/starter/starter.c
deleted file mode 100644
index 0b2c83369..000000000
--- a/programs/starter/starter.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* strongSwan IPsec starter
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: starter.c,v 1.23 2006/02/15 18:37:46 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-
-#include "confread.h"
-#include "files.h"
-#include "starterwhack.h"
-#include "invokepluto.h"
-#include "klips.h"
-#include "netkey.h"
-#include "cmp.h"
-#include "interfaces.h"
-
-#define FLAG_ACTION_START_PLUTO 0x01
-#define FLAG_ACTION_UPDATE 0x02
-#define FLAG_ACTION_RELOAD 0x04
-#define FLAG_ACTION_QUIT 0x08
-#define FLAG_ACTION_LISTEN 0x10
-
-static unsigned int _action_ = 0;
-
-static void
-fsig(int signal)
-{
- switch (signal)
- {
- case SIGCHLD:
- {
- int status;
- pid_t pid;
- char *name = NULL;
-
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
- {
- if (pid == starter_pluto_pid())
- name = " (Pluto)";
- if (WIFSIGNALED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has been killed by sig %d\n",
- pid, name?name:"", WTERMSIG(status))
- )
- else if (WIFSTOPPED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has been stopped by sig %d\n",
- pid, name?name:"", WSTOPSIG(status))
- )
- else if (WIFEXITED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has quit (exit code %d)\n",
- pid, name?name:"", WEXITSTATUS(status))
- )
- else
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has quit", pid, name?name:"")
- )
-
- if (pid == starter_pluto_pid())
- starter_pluto_sigchild(pid);
- }
- }
- break;
-
- case SIGPIPE:
- /** ignore **/
- break;
-
- case SIGALRM:
- _action_ |= FLAG_ACTION_START_PLUTO;
- break;
-
- case SIGHUP:
- _action_ |= FLAG_ACTION_UPDATE;
- break;
-
- case SIGTERM:
- case SIGQUIT:
- case SIGINT:
- _action_ |= FLAG_ACTION_QUIT;
- break;
-
- case SIGUSR1:
- _action_ |= FLAG_ACTION_RELOAD;
- _action_ |= FLAG_ACTION_UPDATE;
- break;
-
- default:
- plog("fsig(): unknown signal %d -- investigate", signal);
- break;
- }
-}
-
-static void
-usage(char *name)
-{
- fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
- "[--debug|--debug-more|--debug-all]\n");
- exit(1);
-}
-
-int main (int argc, char **argv)
-{
- starter_config_t *cfg = NULL;
- starter_config_t *new_cfg;
- starter_conn_t *conn, *conn2;
- starter_ca_t *ca, *ca2;
-
- struct stat stb;
-
- char *err = NULL;
- int i;
- int id = 1;
- struct timeval tv;
- unsigned long auto_update = 0;
- time_t last_reload;
- bool has_netkey;
- bool no_fork = FALSE;
-
- /* global variables defined in log.h */
- log_to_stderr = TRUE;
- base_debugging = DBG_NONE;
-
- /* parse command line */
- for (i = 1; i < argc; i++)
- {
- if (streq(argv[i], "--debug"))
- {
- base_debugging |= DBG_CONTROL;
- }
- else if (streq(argv[i], "--debug-more"))
- {
- base_debugging |= DBG_CONTROLMORE;
- }
- else if (streq(argv[i], "--debug-all"))
- {
- base_debugging |= DBG_ALL;
- }
- else if (streq(argv[i], "--nofork"))
- {
- no_fork = TRUE;
- }
- else if (streq(argv[i], "--auto-update") && i+1 < argc)
- {
- auto_update = atoi(argv[++i]);
- if (!auto_update)
- usage(argv[0]);
- }
- else
- {
- usage(argv[0]);
- }
- }
-
- /* Init */
- init_log("ipsec_starter");
- cur_debugging = base_debugging;
-
- signal(SIGHUP, fsig);
- signal(SIGCHLD, fsig);
- signal(SIGPIPE, fsig);
- signal(SIGINT, fsig);
- signal(SIGTERM, fsig);
- signal(SIGQUIT, fsig);
- signal(SIGALRM, fsig);
- signal(SIGUSR1, fsig);
-
- /* verify that we can start */
- if (getuid() != 0)
- {
- plog("permission denied (must be superuser)");
- exit(1);
- }
-
- if (stat(PID_FILE, &stb) == 0)
- {
- plog("pluto is already running (%s exists) -- aborting", PID_FILE);
- exit(1);
- }
-
- if (stat(DEV_RANDOM, &stb) != 0)
- {
- plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
- exit(1);
- }
-
- if (stat(DEV_URANDOM, &stb)!= 0)
- {
- plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
- exit(1);
- }
-
- cfg = confread_load(CONFIG_FILE);
- if (!cfg)
- {
- plog("unable to start strongSwan -- errors in config");
- exit(1);
- }
-
- /* determine if we have a native netkey IPsec stack */
- has_netkey = starter_netkey_init();
-
- if (!has_netkey)
- {
- /* determine if we have a KLIPS IPsec stack instead */
- if (starter_klips_init())
- {
- starter_klips_set_config(cfg);
- starter_ifaces_init();
- starter_ifaces_clear();
- }
- else
- {
- plog("neither netkey nor KLIPS IPSec stack detected");
- exit(1);
- }
- }
-
- last_reload = time(NULL);
-
- plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
-
- /* fork if we're not debugging stuff */
- if (!no_fork)
- {
- log_to_stderr = FALSE;
-
- switch (fork())
- {
- case 0:
- {
- int fnull = open("/dev/null", O_RDWR);
-
- if (fnull >= 0)
- {
- dup2(fnull, STDIN_FILENO);
- dup2(fnull, STDOUT_FILENO);
- dup2(fnull, STDERR_FILENO);
- close(fnull);
- }
- }
- break;
- case -1:
- plog("can't fork: %s", strerror(errno));
- break;
- default:
- exit(0);
- }
- }
-
- /* save pid file in /var/run/starter.pid */
- {
- FILE *fd = fopen(MY_PID_FILE, "w");
-
- if (fd)
- {
- fprintf(fd, "%u\n", getpid());
- fclose(fd);
- }
- }
-
- if (!has_netkey)
- {
- starter_ifaces_load(cfg->setup.interfaces
- , cfg->setup.overridemtu
- , cfg->setup.nat_traversal
- , &cfg->defaultroute);
- }
-
- _action_ = FLAG_ACTION_START_PLUTO;
-
- for (;;)
- {
- /*
- * Stop pluto (if started) and exit
- */
- if (_action_ & FLAG_ACTION_QUIT)
- {
- if (starter_pluto_pid())
- starter_stop_pluto();
- if (has_netkey)
- starter_netkey_cleanup();
- else
- {
- starter_ifaces_clear();
- starter_klips_cleanup();
- }
- confread_free(cfg);
- unlink(MY_PID_FILE);
- unlink(INFO_FILE);
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- plog("ipsec starter stopped");
- exit(0);
- }
-
- /*
- * Delete all connections. Will be added below
- */
- if (_action_ & FLAG_ACTION_RELOAD)
- {
- if (starter_pluto_pid())
- {
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
- {
- starter_whack_del_conn(conn);
- conn->state = STATE_TO_ADD;
- }
- }
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
- {
- starter_whack_del_ca(ca);
- ca->state = STATE_TO_ADD;
- }
- }
- }
- _action_ &= ~FLAG_ACTION_RELOAD;
- }
-
- /*
- * Update configuration
- */
- if (_action_ & FLAG_ACTION_UPDATE)
- {
- err = NULL;
- DBG(DBG_CONTROL,
- DBG_log("Reloading config...")
- )
- new_cfg = confread_load(CONFIG_FILE);
-
- if (new_cfg)
- {
- /* Switch to new config. New conn will be loaded below */
- if (has_netkey)
- {
- if (!starter_cmp_defaultroute(&new_cfg->defaultroute
- , &cfg->defaultroute))
- {
- _action_ |= FLAG_ACTION_LISTEN;
- }
- }
- else
- {
- if (!starter_cmp_klips(cfg, new_cfg))
- {
- plog("KLIPS has changed");
- starter_klips_set_config(new_cfg);
- }
-
- if (starter_ifaces_load(new_cfg->setup.interfaces
- , new_cfg->setup.overridemtu
- , new_cfg->setup.nat_traversal
- , &new_cfg->defaultroute))
- {
- _action_ |= FLAG_ACTION_LISTEN;
- }
- }
-
- if (!starter_cmp_pluto(cfg, new_cfg))
- {
- plog("Pluto has changed");
- if (starter_pluto_pid())
- starter_stop_pluto();
- _action_ &= ~FLAG_ACTION_LISTEN;
- _action_ |= FLAG_ACTION_START_PLUTO;
- }
- else
- {
- /* Only reload conn and ca sections if pluto is not killed */
-
- /* Look for new connections that are already loaded */
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
- {
- for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
- {
- if (conn2->state == STATE_TO_ADD
- && starter_cmp_conn(conn, conn2))
- {
- conn->state = STATE_REPLACED;
- conn2->state = STATE_ADDED;
- conn2->id = conn->id;
- break;
- }
- }
- }
- }
-
- /* Remove conn sections that have become unused */
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
- starter_whack_del_conn(conn);
- }
-
- /* Look for new ca sections that are already loaded */
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
- {
- for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
- {
- if (ca2->state == STATE_TO_ADD
- && starter_cmp_ca(ca, ca2))
- {
- ca->state = STATE_REPLACED;
- ca2->state = STATE_ADDED;
- break;
- }
- }
- }
- }
-
- /* Remove ca sections that have become unused */
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
- starter_whack_del_ca(ca);
- }
- }
- confread_free(cfg);
- cfg = new_cfg;
- }
- else
- {
- plog("can't reload config file: %s -- keeping old one");
- }
- _action_ &= ~FLAG_ACTION_UPDATE;
- last_reload = time(NULL);
- }
-
- /*
- * Start pluto
- */
- if (_action_ & FLAG_ACTION_START_PLUTO)
- {
- if (starter_pluto_pid() == 0)
- {
- DBG(DBG_CONTROL,
- DBG_log("Attempting to start pluto...")
- )
- if (!has_netkey)
- starter_klips_clear();
-
- if (starter_start_pluto(cfg, no_fork) == 0)
- {
- starter_whack_listen();
- }
- else
- {
- /* schedule next try */
- alarm(PLUTO_RESTART_DELAY);
- }
- }
- _action_ &= ~FLAG_ACTION_START_PLUTO;
-
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
- ca->state = STATE_TO_ADD;
- }
-
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
- conn->state = STATE_TO_ADD;
- }
- }
-
- /*
- * Tell pluto to reread its interfaces
- */
- if (_action_ & FLAG_ACTION_LISTEN)
- {
- starter_whack_listen();
- _action_ &= ~FLAG_ACTION_LISTEN;
- }
-
- /*
- * Add stale conn and ca sections
- */
- if (starter_pluto_pid() != 0)
- {
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_TO_ADD)
- {
- starter_whack_add_ca(ca);
- ca->state = STATE_ADDED;
- }
- }
-
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_TO_ADD)
- {
- if (conn->id == 0)
- {
- /* affect new unique id */
- conn->id = id++;
- }
- starter_whack_add_conn(conn);
- conn->state = STATE_ADDED;
- if (conn->startup == STARTUP_START)
- starter_whack_initiate_conn(conn);
- else if (conn->startup == STARTUP_ROUTE)
- starter_whack_route_conn(conn);
- }
- }
- }
-
- /*
- * If auto_update activated, when to stop select
- */
- if (auto_update)
- {
- time_t now = time(NULL);
- tv.tv_sec = (now < last_reload + auto_update)
- ? (last_reload + auto_update-now) : 0;
- tv.tv_usec = 0;
- }
-
- /*
- * Wait for something to happen
- */
- if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
- {
- /* timeout -> auto_update */
- _action_ |= FLAG_ACTION_UPDATE;
- }
- }
-
- return 0;
-}
-
diff --git a/programs/starter/starterwhack.c b/programs/starter/starterwhack.c
deleted file mode 100644
index cb3e02172..000000000
--- a/programs/starter/starterwhack.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/* strongSwan whack functions to communicate with pluto (whack.c)
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: starterwhack.c,v 1.20 2007/01/18 21:16:45 as Exp $
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/log.h"
-#include "../pluto/whack.h"
-
-#include "starterwhack.h"
-#include "confread.h"
-#include "files.h"
-
-static int
-pack_str (char **p, char **next, char **roof)
-{
- const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
- size_t len = strlen(s) + 1;
-
- if ((*roof - *next) < len)
- {
- return 0; /* not enough space */
- }
- else
- {
- strcpy(*next, s);
- *next += len;
- *p = NULL; /* don't send pointers on the wire! */
- return 1;
- }
-}
-
-static int
-send_whack_msg (whack_message_t *msg)
-{
- struct sockaddr_un ctl_addr = { AF_UNIX, CTL_FILE };
- int sock;
- ssize_t len;
- char *str_next, *str_roof;
-
- /* pack strings */
- str_next = (char *)msg->string;
- str_roof = (char *)&msg->string[sizeof(msg->string)];
-
- if (!pack_str(&msg->name, &str_next, &str_roof)
- || !pack_str(&msg->left.id, &str_next, &str_roof)
- || !pack_str(&msg->left.cert, &str_next, &str_roof)
- || !pack_str(&msg->left.ca, &str_next, &str_roof)
- || !pack_str(&msg->left.groups, &str_next, &str_roof)
- || !pack_str(&msg->left.updown, &str_next, &str_roof)
-#ifdef VIRTUAL_IP
- || !pack_str(&msg->left.virt, &str_next, &str_roof)
-#endif
- || !pack_str(&msg->right.id, &str_next, &str_roof)
- || !pack_str(&msg->right.cert, &str_next, &str_roof)
- || !pack_str(&msg->right.ca, &str_next, &str_roof)
- || !pack_str(&msg->right.groups, &str_next, &str_roof)
- || !pack_str(&msg->right.updown, &str_next, &str_roof)
-#ifdef VIRTUAL_IP
- || !pack_str(&msg->right.virt, &str_next, &str_roof)
-#endif
- || !pack_str(&msg->keyid, &str_next, &str_roof)
- || !pack_str(&msg->myid, &str_next, &str_roof)
- || !pack_str(&msg->cacert, &str_next, &str_roof)
- || !pack_str(&msg->ldaphost, &str_next, &str_roof)
- || !pack_str(&msg->ldapbase, &str_next, &str_roof)
- || !pack_str(&msg->crluri, &str_next, &str_roof)
- || !pack_str(&msg->crluri2, &str_next, &str_roof)
- || !pack_str(&msg->ocspuri, &str_next, &str_roof)
- || !pack_str(&msg->ike, &str_next, &str_roof)
- || !pack_str(&msg->esp, &str_next, &str_roof)
- || !pack_str(&msg->sc_data, &str_next, &str_roof)
- || (str_roof - str_next < msg->keyval.len))
- {
- plog("send_wack_msg(): can't pack strings");
- return -1;
- }
- if (msg->keyval.ptr)
- memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
- msg->keyval.ptr = NULL;
- str_next += msg->keyval.len;
- len = str_next - (char *)msg;
-
- /* connect to pluto ctl */
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0)
- {
- plog("socket() failed: %s", strerror(errno));
- return -1;
- }
- if (connect(sock, (struct sockaddr *)&ctl_addr,
- offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- {
- plog("connect(pluto_ctl) failed: %s", strerror(errno));
- close(sock);
- return -1;
- }
-
- /* send message */
- if (write(sock, msg, len) != len)
- {
- plog("write(pluto_ctl) failed: %s", strerror(errno));
- close(sock);
- return -1;
- }
-
- /* TODO: read reply */
- close(sock);
- return 0;
-}
-
-static void
-init_whack_msg(whack_message_t *msg)
-{
- memset(msg, 0, sizeof(whack_message_t));
- msg->magic = WHACK_MAGIC;
-}
-
-static char *
-connection_name(starter_conn_t *conn)
-{
- /* if connection name is '%auto', create a new name like conn_xxxxx */
- static char buf[32];
-
- if (streq(conn->name, "%auto"))
- {
- sprintf(buf, "conn_%ld", conn->id);
- return buf;
- }
- return conn->name;
-}
-
-static void
-set_whack_end(whack_end_t *w, starter_end_t *end)
-{
- w->id = end->id;
- w->cert = end->cert;
- w->ca = end->ca;
- w->groups = end->groups;
- w->host_addr = end->addr;
- w->host_nexthop = end->nexthop;
- w->host_srcip = end->srcip;
- w->has_client = end->has_client;
-
- if (w->has_client)
- w->client = end->subnet;
- else
- w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
-
- w->has_client_wildcard = end->has_client_wildcard;
- w->has_port_wildcard = end->has_port_wildcard;
- w->has_srcip = end->has_srcip;
- w->has_natip = end->has_natip;
- w->modecfg = end->modecfg;
- w->hostaccess = end->hostaccess;
- w->sendcert = end->sendcert;
- w->updown = end->updown;
- w->host_port = IKE_UDP_PORT;
- w->port = end->port;
- w->protocol = end->protocol;
- w->virt = end->virt;
-
- if (w->port != 0)
- {
- int port = htons(w->port);
-
- setportof(port, &w->host_addr);
- setportof(port, &w->client.addr);
- }
-}
-
-static int
-starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
-, const char *lr)
-{
- const char *err;
- static char keyspace[1024 + 4];
- whack_message_t msg;
-
- init_whack_msg(&msg);
-
- msg.whack_key = TRUE;
- msg.pubkey_alg = PUBKEY_ALG_RSA;
- if (end->id && end->rsakey)
- {
- /* special values to ignore */
- if (streq(end->rsakey, "")
- || streq(end->rsakey, "%none")
- || streq(end->rsakey, "%cert")
- || streq(end->rsakey, "0x00"))
- {
- return 0;
- }
- msg.keyid = end->id;
- err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
- if (err)
- {
- plog("conn %s/%s: rsakey malformed [%s]", connection_name(conn), lr, err);
- return 1;
- }
- else
- {
- msg.keyval.ptr = keyspace;
- return send_whack_msg(&msg);
- }
- }
- return 0;
-}
-
-int
-starter_whack_add_conn(starter_conn_t *conn)
-{
- whack_message_t msg;
- int r;
-
- init_whack_msg(&msg);
-
- msg.whack_connection = TRUE;
- msg.name = connection_name(conn);
-
- msg.addr_family = conn->addr_family;
- msg.tunnel_addr_family = conn->tunnel_addr_family;
- msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
- msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
- msg.sa_rekey_margin = conn->sa_rekey_margin;
- msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
- msg.sa_keying_tries = conn->sa_keying_tries;
- msg.policy = conn->policy;
-
- set_whack_end(&msg.left, &conn->left);
- set_whack_end(&msg.right, &conn->right);
-
- msg.esp = conn->esp;
- msg.ike = conn->ike;
- msg.pfsgroup = conn->pfsgroup;
-
- /* taken from pluto/whack.c */
- if (msg.pfsgroup)
- {
- char esp_buf[256];
-
- snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
- , msg.esp ? msg.esp : ""
- , msg.pfsgroup ? msg.pfsgroup : "");
- msg.esp = esp_buf;
-
- DBG(DBG_CONTROL,
- DBG_log("Setting --esp=%s", msg.esp)
- )
- }
- msg.dpd_delay = conn->dpd_delay;
- msg.dpd_timeout = conn->dpd_timeout;
- msg.dpd_action = conn->dpd_action;
-/* msg.dpd_count = conn->dpd_count; not supported yet by strongSwan */
-
- r = send_whack_msg(&msg);
-
- if (r == 0 && (conn->policy & POLICY_RSASIG))
- {
- r += starter_whack_add_pubkey (conn, &conn->left, "left");
- r += starter_whack_add_pubkey (conn, &conn->right, "right");
- }
-
- return r;
-}
-
-int
-starter_whack_del_conn(starter_conn_t *conn)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
- msg.whack_delete = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
-}
-
-int
-starter_whack_route_conn(starter_conn_t *conn)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
- msg.whack_route = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
-}
-
-int
-starter_whack_initiate_conn(starter_conn_t *conn)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
- msg.whack_initiate = TRUE;
- msg.whack_async = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
-}
-
-int
-starter_whack_listen(void)
-{
- whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_listen = TRUE;
- return send_whack_msg(&msg);
-}
-
-int starter_whack_shutdown(void)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
- msg.whack_shutdown = TRUE;
- return send_whack_msg(&msg);
-}
-
-int
-starter_whack_add_ca(starter_ca_t *ca)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
-
- msg.whack_ca = TRUE;
- msg.name = ca->name;
- msg.cacert = ca->cacert;
- msg.ldaphost = ca->ldaphost;
- msg.ldapbase = ca->ldapbase;
- msg.crluri = ca->crluri;
- msg.crluri2 = ca->crluri2;
- msg.ocspuri = ca->ocspuri;
- msg.whack_strict = ca->strict;
-
- return send_whack_msg(&msg);
-}
-
-int
-starter_whack_del_ca(starter_ca_t *ca)
-{
- whack_message_t msg;
-
- init_whack_msg(&msg);
-
- msg.whack_delete = TRUE;
- msg.whack_ca = TRUE;
- msg.name = ca->name;
-
- return send_whack_msg(&msg);
-}
diff --git a/programs/starter/starterwhack.h b/programs/starter/starterwhack.h
deleted file mode 100644
index 2e79c0715..000000000
--- a/programs/starter/starterwhack.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* FreeS/WAN whack functions to communicate with pluto (whack.h)
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: starterwhack.h,v 1.6 2006/01/03 18:37:03 as Exp $
- */
-
-#ifndef _STARTER_WHACK_H_
-#define _STARTER_WHACK_H_
-
-#include "confread.h"
-
-extern int starter_whack_add_conn(starter_conn_t *conn);
-extern int starter_whack_del_conn(starter_conn_t *conn);
-extern int starter_whack_route_conn(starter_conn_t *conn);
-extern int starter_whack_initiate_conn(starter_conn_t *conn);
-extern int starter_whack_listen(void);
-extern int starter_whack_shutdown(void);
-extern int starter_whack_add_ca(starter_ca_t *ca);
-extern int starter_whack_del_ca(starter_ca_t *ca);
-
-#endif /* _STARTER_WHACK_H_ */
-
diff --git a/programs/tncfg/.cvsignore b/programs/tncfg/.cvsignore
deleted file mode 100644
index c05ca8d9a..000000000
--- a/programs/tncfg/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-tncfg
diff --git a/programs/tncfg/Makefile b/programs/tncfg/Makefile
deleted file mode 100644
index ded364dbf..000000000
--- a/programs/tncfg/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# Makefile for the KLIPS interface utilities
-# Copyright (C) 1998, 1999 Henry Spencer.
-# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:31 as Exp $
-
-FREESWANSRCDIR=../..
-include ${FREESWANSRCDIR}/Makefile.inc
-
-PROGRAM:=tncfg
-EXTRA5PROC=${PROGRAM}.5
-
-LIBS:=${FREESWANLIB}
-
-include ../Makefile.program
-
-#
-# $Log: Makefile,v $
-# Revision 1.1 2004/03/15 20:35:31 as
-# added files from freeswan-2.04-x509-1.5.3
-#
-# Revision 1.4 2002/06/03 20:25:31 mcr
-# man page for files actually existant in /proc/net changed back to
-# ipsec_foo via new EXTRA5PROC process.
-#
-# Revision 1.3 2002/06/02 21:51:41 mcr
-# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
-# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
-# kernel sense.)
-#
-# Revision 1.2 2002/04/26 01:21:26 mcr
-# while tracking down a missing (not installed) /etc/ipsec.conf,
-# MCR has decided that it is not okay for each program subdir to have
-# some subset (determined with -f) of possible files.
-# Each subdir that defines $PROGRAM, MUST have a PROGRAM.8 file as well as a PROGRAM file.
-# Optional PROGRAM.5 files have been added to the makefiles.
-#
-# Revision 1.1 2002/04/24 07:55:32 mcr
-# #include patches and Makefiles for post-reorg compilation.
-#
-#
-#
diff --git a/programs/tncfg/tncfg.5 b/programs/tncfg/tncfg.5
deleted file mode 100644
index e4de862c6..000000000
--- a/programs/tncfg/tncfg.5
+++ /dev/null
@@ -1,109 +0,0 @@
-.TH IPSEC_TNCFG 5 "27 Jun 2000"
-.\"
-.\" RCSID $Id: tncfg.5,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec_tncfg \- lists IPSEC virtual interfaces attached to real interfaces
-.SH SYNOPSIS
-.B ipsec
-.B tncfg
-.PP
-.B cat
-.B /proc/net/ipsec_tncfg
-.SH DESCRIPTION
-.I /proc/net/ipsec_tncfg
-is a read-only file which lists which IPSEC virtual interfaces are
-attached to which real interfaces, through which packets will be
-forwarded once processed by IPSEC.
-.PP
-Each line lists one ipsec I/F.
-A table entry consists of:
-.IP + 3
-an ipsec virtual I/F name
-.IP +
-a visual and machine parsable separator '->', separating the virtual I/F
-and the physical I/F,
-.IP +
-a physical I/F name, to which the ipsec virtual I/F is attached or NULL
-if it is not attached,
-.IP +
-the keyword
-.BR mtu= ,
-.IP +
-the MTU of the ipsec virtual I/F,
-.IP +
-the automatically adjusted effective MTU for PMTU discovery, in brackets,
-.IP +
-a visual and machine parsable separator '->', separating the virtual I/F
-MTU and the physical I/F MTU,
-.IP +
-the MTU of the attached physical I/F.
-.BR
-.SH EXAMPLES
-.TP
-.B ipsec2 -> eth3 mtu=16260(1443) -> 1500
-.LP
-shows that virtual device
-.B ipsec2
-with an MTU of
-.B 16260
-is connected to physical device
-.B eth3
-with an MTU of
-.B 1500
-and that the effective MTU as a result of PMTU discovery has been
-automatically set to
-.BR 1443.
-.TP
-.B ipsec0 \-> wvlan0 mtu=1400(16260) \-> 1500
-.LP
-shows that virtual device
-.B ipsec0
-with an MTU of
-.B 1400
-is connected to physical device
-.B wvlan0
-with an MTU of
-.B 1500
-and no PMTU packets have gotten far enough to bump down the effective MTU
-from its default of 16260.
-.TP
-.B ipsec3 \-> NULL mtu=0(0) \-> 0
-.LP
-shows that virtual device
-.B ipsec3
-is not connected to any physical device.
-.LP
-.SH "FILES"
-/proc/net/ipsec_tncfg, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_eroute(5), ipsec_spi(5),
-ipsec_spigrp(5), ipsec_klipsdebug(5), ipsec_tncfg(8), ipsec_version(5),
-ipsec_pf_key(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: tncfg.5,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.5 2002/04/24 07:35:41 mcr
-.\" Moved from ./klips/utils/tncfg.5,v
-.\"
-.\" Revision 1.4 2001/05/29 05:15:53 rgb
-.\" Added PMTU to output format.
-.\"
-.\" Revision 1.3 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.2 2000/06/28 12:44:12 henry
-.\" format touchup
-.\"
-.\" Revision 1.1 2000/06/28 05:43:01 rgb
-.\" Added manpages for all 5 klips utils.
-.\"
-.\"
diff --git a/programs/tncfg/tncfg.8 b/programs/tncfg/tncfg.8
deleted file mode 100644
index f888f2539..000000000
--- a/programs/tncfg/tncfg.8
+++ /dev/null
@@ -1,113 +0,0 @@
-.TH IPSEC_TNCFG 8 "21 Jun 2000"
-.\"
-.\" RCSID $Id: tncfg.8,v 1.1 2004/03/15 20:35:31 as Exp $
-.\"
-.SH NAME
-ipsec tncfg \- associate IPSEC virtual interface with physical interface
-.SH SYNOPSIS
-.B ipsec
-.B tncfg
-.PP
-.B ipsec
-.B tncfg
-.B \-\-attach
-.B \-\-virtual
-virtual
-.B \-\-physical
-physical
-.PP
-.B ipsec
-.B tncfg
-.B \-\-detach
-.B \-\-virtual
-virtual
-.PP
-.B ipsec
-.B tncfg
-.B \-\-clear
-.PP
-.B ipsec
-.B tncfg
-.B \-\-version
-.PP
-.B ipsec
-.B tncfg
-.B \-\-help
-.SH DESCRIPTION
-.I Tncfg
-attaches/detaches IPSEC virtual interfaces to/from
-physical interfaces,
-through which packets will be forwarded once processed by IPSEC.
-.PP
-The form with no additional arguments lists the contents of
-/proc/net/ipsec_tncfg. The format of /proc/net/ipsec_tncfg is discussed
-in ipsec_tncfg(5).
-The
-.B \-\-attach
-form attaches the
-.I virtual
-interface to the
-.I physical
-one.
-The
-.B \-\-detach
-form detaches the
-.I virtual
-interface from whichever physical interface it is attached to.
-The
-.B \-\-clear
-form clears all the
-.I virtual
-interfaces from whichever physical interfaces they were attached to.
-.PP
-Virtual interfaces typically have names like
-.BR ipsec0 ,
-while physical interfaces typically have names like
-.B eth0
-or
-.BR ppp0 .
-.SH EXAMPLES
-.TP
-.B ipsec tncfg \-\-attach \-\-virtual ipsec0 \-\-physical eth0
-attaches the
-.B ipsec0
-virtual device to the
-.B eth0
-physical device.
-.LP
-.SH "FILES"
-/proc/net/ipsec_tncfg, /usr/local/bin/ipsec
-.SH "SEE ALSO"
-ipsec(8), ipsec_manual(8), ipsec_eroute(8), ipsec_spi(8),
-ipsec_spigrp(8), ipsec_klipsdebug(8), ipsec_tncfg(5)
-.SH HISTORY
-Written for the Linux FreeS/WAN project
-<http://www.freeswan.org/>
-by Richard Guy Briggs.
-.\"
-.\" $Log: tncfg.8,v $
-.\" Revision 1.1 2004/03/15 20:35:31 as
-.\" added files from freeswan-2.04-x509-1.5.3
-.\"
-.\" Revision 1.15 2002/04/24 07:35:41 mcr
-.\" Moved from ./klips/utils/tncfg.8,v
-.\"
-.\" Revision 1.14 2000/09/12 13:09:04 rgb
-.\" Fixed real/physical discrepancy between tncfg.8 and tncfg.c.
-.\"
-.\" Revision 1.13 2000/06/30 18:21:55 rgb
-.\" Update SEE ALSO sections to include ipsec_version(5) and ipsec_pf_key(5)
-.\" and correct FILES sections to no longer refer to /dev/ipsec which has
-.\" been removed since PF_KEY does not use it.
-.\"
-.\" Revision 1.12 2000/06/21 16:54:58 rgb
-.\" Added 'no additional args' text for listing contents of
-.\" /proc/net/ipsec_* files.
-.\"
-.\" Revision 1.11 1999/07/19 18:47:25 henry
-.\" fix slightly-misformed comments
-.\"
-.\" Revision 1.10 1999/04/06 04:54:39 rgb
-.\" Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-.\" patch shell fixes.
-.\"
diff --git a/programs/tncfg/tncfg.c b/programs/tncfg/tncfg.c
deleted file mode 100644
index f6aeae0e2..000000000
--- a/programs/tncfg/tncfg.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * IPSEC interface configuration
- * Copyright (C) 1996 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-char tncfg_c_version[] = "RCSID $Id: tncfg.c,v 1.1 2004/03/15 20:35:31 as Exp $";
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h> /* system(), strtoul() */
-#include <unistd.h> /* getuid() */
-#include <linux/types.h>
-#include <sys/ioctl.h> /* ioctl() */
-
-#include <freeswan.h>
-#ifdef NET_21 /* from freeswan.h */
-#include <linux/sockios.h>
-#include <sys/socket.h>
-#endif /* NET_21 */ /* from freeswan.h */
-
-#if 0
-#include <linux/if.h>
-#else
-#include <net/if.h>
-#endif
-#include <sys/types.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "freeswan/ipsec_tunnel.h"
-
-static void
-usage(char *name)
-{
- fprintf(stdout,"%s --attach --virtual <virtual-device> --physical <physical-device>\n",
- name);
- fprintf(stdout,"%s --detach --virtual <virtual-device>\n",
- name);
- fprintf(stdout,"%s --clear\n",
- name);
- fprintf(stdout,"%s --help\n",
- name);
- fprintf(stdout,"%s --version\n",
- name);
- fprintf(stdout,"%s\n",
- name);
- fprintf(stdout, " [ --debug ] is optional to any %s command.\n", name);
- fprintf(stdout, " [ --label <label> ] is optional to any %s command.\n", name);
- exit(1);
-}
-
-static struct option const longopts[] =
-{
- {"virtual", 1, 0, 'V'},
- {"physical", 1, 0, 'P'},
- {"attach", 0, 0, 'a'},
- {"detach", 0, 0, 'd'},
- {"clear", 0, 0, 'c'},
- {"help", 0, 0, 'h'},
- {"version", 0, 0, 'v'},
- {"label", 1, 0, 'l'},
- {"optionsfrom", 1, 0, '+'},
- {"debug", 0, 0, 'g'},
- {0, 0, 0, 0}
-};
-
-int
-main(int argc, char *argv[])
-{
- struct ifreq ifr;
- struct ipsectunnelconf *shc=(struct ipsectunnelconf *)&ifr.ifr_data;
- int s;
- int c, previous = -1;
- char *program_name;
- int debug = 0;
- int argcount = argc;
-
- memset(&ifr, 0, sizeof(ifr));
- program_name = argv[0];
-
- while((c = getopt_long_only(argc, argv, ""/*"adchvV:P:l:+:"*/, longopts, 0)) != EOF) {
- switch(c) {
- case 'g':
- debug = 1;
- argcount--;
- break;
- case 'a':
- if(shc->cf_cmd) {
- fprintf(stderr, "%s: exactly one of '--attach', '--detach' or '--clear' options must be specified.\n", program_name);
- exit(1);
- }
- shc->cf_cmd = IPSEC_SET_DEV;
- break;
- case 'd':
- if(shc->cf_cmd) {
- fprintf(stderr, "%s: exactly one of '--attach', '--detach' or '--clear' options must be specified.\n", program_name);
- exit(1);
- }
- shc->cf_cmd = IPSEC_DEL_DEV;
- break;
- case 'c':
- if(shc->cf_cmd) {
- fprintf(stderr, "%s: exactly one of '--attach', '--detach' or '--clear' options must be specified.\n", program_name);
- exit(1);
- }
- shc->cf_cmd = IPSEC_CLR_DEV;
- break;
- case 'h':
- usage(program_name);
- break;
- case 'v':
- if(optarg) {
- fprintf(stderr, "%s: warning; '-v' and '--version' options don't expect arguments, arg '%s' found, perhaps unintended.\n",
- program_name, optarg);
- }
- fprintf(stdout, "%s, %s\n", program_name, tncfg_c_version);
- exit(1);
- break;
- case 'V':
- strcpy(ifr.ifr_name, optarg);
- break;
- case 'P':
- strcpy(shc->cf_name, optarg);
- break;
- case 'l':
- program_name = malloc(strlen(argv[0])
- + 10 /* update this when changing the sprintf() */
- + strlen(optarg));
- sprintf(program_name, "%s --label %s",
- argv[0],
- optarg);
- argcount -= 2;
- break;
- case '+': /* optionsfrom */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* no return on error */
- break;
- default:
- usage(program_name);
- break;
- }
- previous = c;
- }
-
- if(argcount == 1) {
- system("cat /proc/net/ipsec_tncfg");
- exit(0);
- }
-
- switch(shc->cf_cmd) {
- case IPSEC_SET_DEV:
- if(!shc->cf_name) {
- fprintf(stderr, "%s: physical I/F parameter missing.\n",
- program_name);
- exit(1);
- }
- case IPSEC_DEL_DEV:
- if(!ifr.ifr_name) {
- fprintf(stderr, "%s: virtual I/F parameter missing.\n",
- program_name);
- exit(1);
- }
- break;
- case IPSEC_CLR_DEV:
- strcpy(ifr.ifr_name, "ipsec0");
- break;
- default:
- fprintf(stderr, "%s: exactly one of '--attach', '--detach' or '--clear' options must be specified.\n"
- "Try %s --help' for usage information.\n",
- program_name, program_name);
- exit(1);
- }
-
- s=socket(AF_INET, SOCK_DGRAM,0);
- if(s==-1)
- {
- fprintf(stderr, "%s: Socket creation failed -- ", program_name);
- switch(errno)
- {
- case EACCES:
- if(getuid()==0)
- fprintf(stderr, "Root denied permission!?!\n");
- else
- fprintf(stderr, "Run as root user.\n");
- break;
- case EPROTONOSUPPORT:
- fprintf(stderr, "Internet Protocol not enabled");
- break;
- case EMFILE:
- case ENFILE:
- case ENOBUFS:
- fprintf(stderr, "Insufficient system resources.\n");
- break;
- case ENODEV:
- fprintf(stderr, "No such device. Is the virtual device valid? Is the ipsec module linked into the kernel or loaded as a module?\n");
- break;
- default:
- fprintf(stderr, "Unknown socket error %d.\n", errno);
- }
- exit(1);
- }
- if(ioctl(s, shc->cf_cmd, &ifr)==-1)
- {
- if(shc->cf_cmd == IPSEC_SET_DEV) {
- fprintf(stderr, "%s: Socket ioctl failed on attach -- ", program_name);
- switch(errno)
- {
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "No such device. Is the virtual device valid? Is the ipsec module linked into the kernel or loaded as a module?\n");
- break;
- case ENXIO:
- fprintf(stderr, "No such device. Is the physical device valid?\n");
- break;
- case EBUSY:
- fprintf(stderr, "Device busy. Virtual device %s is already attached to a physical device -- Use detach first.\n",
- ifr.ifr_name);
- break;
- default:
- fprintf(stderr, "Unknown socket error %d.\n", errno);
- }
- exit(1);
- }
- if(shc->cf_cmd == IPSEC_DEL_DEV) {
- fprintf(stderr, "%s: Socket ioctl failed on detach -- ", program_name);
- switch(errno)
- {
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "No such device. Is the virtual device valid? The ipsec module may not be linked into the kernel or loaded as a module.\n");
- break;
- case ENXIO:
- fprintf(stderr, "Device requested is not linked to any physical device.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket error %d.\n", errno);
- }
- exit(1);
- }
- if(shc->cf_cmd == IPSEC_CLR_DEV) {
- fprintf(stderr, "%s: Socket ioctl failed on clear -- ", program_name);
- switch(errno)
- {
- case EINVAL:
- fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
- break;
- case ENODEV:
- fprintf(stderr, "Failed. Is the ipsec module linked into the kernel or loaded as a module?.\n");
- break;
- default:
- fprintf(stderr, "Unknown socket error %d.\n", errno);
- }
- exit(1);
- }
- }
- exit(0);
-}
-
-/*
- * $Log: tncfg.c,v $
- * Revision 1.1 2004/03/15 20:35:31 as
- * added files from freeswan-2.04-x509-1.5.3
- *
- * Revision 1.30 2002/04/24 07:55:32 mcr
- * #include patches and Makefiles for post-reorg compilation.
- *
- * Revision 1.29 2002/04/24 07:35:41 mcr
- * Moved from ./klips/utils/tncfg.c,v
- *
- * Revision 1.28 2002/03/08 21:44:05 rgb
- * Update for all GNU-compliant --version strings.
- *
- * Revision 1.27 2001/06/14 19:35:15 rgb
- * Update copyright date.
- *
- * Revision 1.26 2001/05/21 02:02:55 rgb
- * Eliminate 1-letter options.
- *
- * Revision 1.25 2001/05/16 05:07:20 rgb
- * Fixed --label option in KLIPS manual utils to add the label to the
- * command name rather than replace it in error text.
- * Fix 'print table' non-option in KLIPS manual utils to deal with --label
- * and --debug options.
- *
- * Revision 1.24 2000/09/12 13:09:05 rgb
- * Fixed real/physical discrepancy between tncfg.8 and tncfg.c.
- *
- * Revision 1.23 2000/08/27 01:48:30 rgb
- * Update copyright.
- *
- * Revision 1.22 2000/07/26 03:41:46 rgb
- * Changed all printf's to fprintf's. Fixed tncfg's usage to stderr.
- *
- * Revision 1.21 2000/06/21 16:51:27 rgb
- * Added no additional argument option to usage text.
- *
- * Revision 1.20 2000/01/21 06:26:31 rgb
- * Added --debug switch to command line.
- *
- * Revision 1.19 1999/12/08 20:32:41 rgb
- * Cleaned out unused cruft.
- * Changed include file, limiting scope, to avoid conflicts in 2.0.xx
- * kernels.
- *
- * Revision 1.18 1999/12/07 18:27:10 rgb
- * Added headers to silence fussy compilers.
- * Converted local functions to static to limit scope.
- *
- * Revision 1.17 1999/11/18 04:09:21 rgb
- * Replaced all kernel version macros to shorter, readable form.
- *
- * Revision 1.16 1999/05/25 01:45:36 rgb
- * Fix version macros for 2.0.x as a module.
- *
- * Revision 1.15 1999/05/05 22:02:34 rgb
- * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
- *
- * Revision 1.14 1999/04/15 15:37:28 rgb
- * Forward check changes from POST1_00 branch.
- *
- * Revision 1.10.6.2 1999/04/13 20:58:10 rgb
- * Add argc==1 --> /proc/net/ipsec_*.
- *
- * Revision 1.10.6.1 1999/03/30 17:01:36 rgb
- * Make main() return type explicit.
- *
- * Revision 1.13 1999/04/11 00:12:09 henry
- * GPL boilerplate
- *
- * Revision 1.12 1999/04/06 04:54:39 rgb
- * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
- * patch shell fixes.
- *
- * Revision 1.11 1999/03/17 15:40:54 rgb
- * Make explicit main() return type of int.
- *
- * Revision 1.10 1998/11/12 21:08:04 rgb
- * Add --label option to identify caller from scripts.
- *
- * Revision 1.9 1998/10/09 18:47:30 rgb
- * Add 'optionfrom' to get more options from a named file.
- *
- * Revision 1.8 1998/10/09 04:36:55 rgb
- * Changed help output from stderr to stdout.
- * Deleted old commented out cruft.
- *
- * Revision 1.7 1998/08/28 03:15:14 rgb
- * Add some manual long options to the usage text.
- *
- * Revision 1.6 1998/08/05 22:29:00 rgb
- * Change includes to accomodate RH5.x.
- * Force long option names.
- * Add ENXIO error return code to narrow down error reporting.
- *
- * Revision 1.5 1998/07/29 21:45:28 rgb
- * Convert to long option names.
- *
- * Revision 1.4 1998/07/09 18:14:11 rgb
- * Added error checking to IP's and keys.
- * Made most error messages more specific rather than spamming usage text.
- * Added more descriptive kernel error return codes and messages.
- * Converted all spi translations to unsigned.
- * Removed all invocations of perror.
- *
- * Revision 1.3 1998/05/27 18:48:20 rgb
- * Adding --help and --version directives.
- *
- * Revision 1.2 1998/04/23 21:11:39 rgb
- * Fixed 0 argument usage case to prevent sigsegv.
- *
- * Revision 1.1.1.1 1998/04/08 05:35:09 henry
- * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
- *
- * Revision 0.5 1997/06/03 04:31:55 ji
- * New file.
- *
- */