]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
MemBuf implements Packable interface
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 27 Apr 2015 05:31:56 +0000 (22:31 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 27 Apr 2015 05:31:56 +0000 (22:31 -0700)
... detatch it from Packer wrapper class

109 files changed:
CONTRIBUTORS
CREDITS
ChangeLog
INSTALL
QUICKSTART
SPONSORS.list
acinclude/krb5.m4
acinclude/lib-checks.m4
compat/testPreCompiler.cc
compat/types.h
configure.ac
doc/release-notes/Makefile
doc/release-notes/release-3.5.sgml
doc/release-notes/release-4.html [moved from doc/release-notes/release-3.6.html with 55% similarity]
doc/release-notes/release-4.sgml [moved from doc/release-notes/release-3.6.sgml with 93% similarity]
doc/rfc/1-index.txt
doc/rfc/rfc7538.txt [moved from doc/rfc/rfc7238.txt with 57% similarity]
errors/COPYRIGHT
helpers/basic_auth/modules.m4
helpers/digest_auth/eDirectory/Makefile.am
helpers/digest_auth/eDirectory/required.m4
helpers/digest_auth/modules.m4
helpers/external_acl/kerberos_ldap_group/required.m4
helpers/external_acl/kerberos_ldap_group/support.h
helpers/external_acl/kerberos_ldap_group/support_ldap.cc
helpers/external_acl/modules.m4
helpers/log_daemon/modules.m4
helpers/negotiate_auth/kerberos/negotiate_kerberos.h
helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc
helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc
helpers/negotiate_auth/modules.m4
helpers/ntlm_auth/fake/ntlm_fake_auth.cc
helpers/ntlm_auth/modules.m4
helpers/storeid_rewrite/modules.m4
helpers/url_rewrite/modules.m4
src/AclRegs.cc
src/FwdState.cc
src/FwdState.h
src/HttpMsg.cc
src/HttpMsg.h
src/HttpReply.cc
src/HttpReply.h
src/HttpRequest.cc
src/HttpRequest.h
src/PeerPoolMgr.cc
src/PeerPoolMgr.h
src/SBuf.cc
src/SBuf.h
src/SBufStatsAction.cc
src/SBufStatsAction.h
src/String.cci
src/URL.h
src/acl/DomainData.h
src/acl/Makefile.am
src/acl/ServerName.cc [new file with mode: 0644]
src/acl/ServerName.h [new file with mode: 0644]
src/adaptation/ecap/MessageRep.cc
src/adaptation/icap/ModXact.cc
src/adaptation/icap/OptXact.cc
src/adaptation/icap/Xaction.cc
src/adaptation/icap/Xaction.h
src/auth/UserRequest.h
src/auth/negotiate/UserRequest.cc
src/auth/ntlm/UserRequest.cc
src/base/Lock.h
src/base/RefCount.h
src/cbdata.cc
src/cbdata.h
src/cf.data.pre
src/client_side.cc
src/client_side.h
src/client_side_request.cc
src/comm.cc
src/comm/ModEpoll.cc
src/err_detail_type.h
src/errorpage.cc
src/fd.cc
src/fs/ufs/RebuildState.h
src/http.cc
src/http.h
src/http/StatusCode.h
src/http/one/Parser.cc
src/http/one/ResponseParser.h
src/log/access_log.cc
src/main.cc
src/parser/Tokenizer.cc
src/peer_proxy_negotiate_auth.cc
src/peer_select.cc
src/security/EncryptorAnswer.cc [new file with mode: 0644]
src/security/EncryptorAnswer.h [new file with mode: 0644]
src/security/Makefile.am
src/security/PeerOptions.h
src/security/forward.h [new file with mode: 0644]
src/ssl/PeerConnector.cc
src/ssl/PeerConnector.h
src/ssl/bio.cc
src/ssl/bio.h
src/ssl/certificate_db.cc
src/ssl/context_storage.cc
src/ssl/support.cc
src/tests/stub_HttpReply.cc
src/tests/stub_HttpRequest.cc
src/tests/stub_cbdata.cc
src/tests/stub_libsecurity.cc
src/tests/testHttpReply.cc
src/tests/testHttpRequest.cc
src/tunnel.cc
src/url.cc
tools/squidclient/gssapi_support.h

index 7e04143e8f842700452c6d9b3c90a72c26c04e59..1c987c138024b3d558a2409927e14d485caee3c1 100644 (file)
@@ -4,93 +4,134 @@ Thank you!
 
     Adam Ciarcinski
     Adrian Chadd <adrian@squid-cache.org>
+    Aecio F. <aecioneto@gmail.com>
     Alan Mizrahi <alan@mizrahi.com.ve>
+    Alan Nastac <mrness@gentoo.org>
+    Aleksa <susulic@gmail.com>
+    Aleksa ??u??uli?? <susulic@gmail.com>
     Alexander B. Demenshin <aldem@barnet.kharkov.ua>
     Alexander Komyagin <komyagin@altell.ru>
+    Alexander Lukyanov <lav@netis.ru>
     Alexander Lukyanov <lav@yar.ru>
     Alexandre Chappaz <alexandrechappaz@gmail.com>
+    Alexandre SIMON <alexandre.simon@ciril.fr>
+    Alex Dowad <alexinbeijing@gmail.com>
     Alexey Veselovsky <alexey.veselovsky@eykontech.com>
     Alexis Robert <alexis.robert@gmail.com>
     Alex Rousskov <rousskov@measurement-factory.com>
+    Alex Rousskov <rousskov@squid-cache.org>
     Alin Nastac <mrness@gentoo.org>
     Alter <alter@alter.org.ua>
     Amos Jeffries <amosjeffries@squid-cache.org>
     Amos Jeffries <squid3@treenet.co.nz>
+    Amos <squid3@treenet.co.nz>
     Anatoli <me@anatoli.ws>
     Andrea Gagliardi <andrea@netlite.it>
     Andreas Jaeger <aj@suse.com>
     Andreas Lamprecht <Andreas.Lamprecht@siemens.at>
     Andres Kroonmaa <andre@ml.ee>
+    Andrew Balabohin
     Andrew Beverley <andy@andybev.com>
     Andrew Doran <ad@interlude.eu.org>
+    Andrew Evdokimov <ae@elahi.ru>
     Andrew Hoying <andrew_hoying@blm.gov>
     Andrew Tridgell
     Andrey Shorin <tolsty@tushino.com>
+    Anonymous Pootle User
     Anonymous <redskilldough@gmail.com>
     Ansgar Hockmann <Ansgar.Hockmann@hrz.uni-dortmund.de>
     Anthony Baxter <arb@connect.com.au>
     Antonino Iannella
+    Arjan de Vet <Arjan.deVet@adv.IAEhv.nl>
     Arjan de Vet <Arjan.deVet@adv.iae.nl>
     Arkin <arkin.yang@gmail.com>
     Arno Streuli <astreuli@gmail.com>
+    Arthur <arthur@psw.ro>
+    Arthur <arthurtumanyan@yahoo.com>
     Arthur Tumanyan <arthurtumanyan@yahoo.com>
     Assar Westerlund <assar@pdc.kth.se>
     Automatic source maintenance <squidadm@squid-cache.org>
     Axel Westerhold <ml.awesterhold@dts.de>
+    Barry Dobyns <barry@dobyns.com>
     Benjamin Kerensa <bkerensa@ubuntu.com>
-    benno@jeamland.net
+    Benno Rice <benno@jeamland.net>
     Benno Rice <benno@squid-cache.org>
     Bernard <fli4l.charrier@free.fr>
     Bertrand Jacquin <beber@meleeweb.net>
     Bill Welliver
     Bojan Smojver <bojan@rexursive.com>
     Brad Smith <brad@comstyle.com>
+    Bratislav <batailic@gmail.com>
     Brian Degenhardt <bmd@mp3.com>
     Brian Denehy <B-Denehy@adfa.oz.au>
     Brian <hiryuu@envisiongames.net>
     Bruce Murphy <pack-squid@rattus.net>
     Carson Gaspar (carson@lehman.com, carson@cs.columbia.edu)
+    Cephas <squidwin@gmail.com>
+    Chad E. Naugle <chad.naugle@travimp.com>
+    Chad Naugle <chad.naugle@travimp.com>
     Changming <me@sunchangming.com>
+    Chao <chao_83@126.com>
     Chris Hills <chaz@chaz6.com>
+    Christian Wittmer <chris@computersalat.de>
     Christopher Kerr
+    Christophe Saout <christophe@saout.de>
     Christoph Lechleitner <lech@ibcl.at>
+    Christos Tsantilas <christos@chtsanti.net>
     Christos Tsantilas <chtsanti@users.sourceforge.net>
     Cloyce <cloyce.spradling@sun.com>
+    Clytie Siddall <clytie@riverland.net.au>
+    Colin Coe <colin.coe@gmail.com>
     Constantin Rack
     Cord Beermann <cord@cc.fh-lippe.de>
     Daniel Beschorner <daniel.beschorner@evlks.de>
     Daniel O'Callaghan <danny@miriworld.its.unimelb.EDU.AU>
+    Daniel Walter <d.walter@0x90.at>
+    Dan Searle <dan.searle@censornet.com>
+    David Hill <david.hill@ubisoft.com>
     David Isaacs <david.isaacs@sbhs.nsw.edu.au>
     David J N Begley
     David Luyer <david@luyer.net>
     David Luyer <luyer@ucs.uwa.edu.au>
+    David Parks <davidparks21@yahoo.com>
+    Declan White <declanw@is.bbc.co.uk>
+    Dennis Felippa <dennis@infologika.com.br>
     Dennis Glatting
-    Dhaval Varia
+    Dhaval Varia <dhavalkvaria@gmail.com>
     Diego Woitasen <diegows@xtech.com.ar>
-    Dmitry Kurochkin
+    D Kazarov <d.y.kazarov@mail.ru>
+    Dmitry Kurochkin <dmitry.kurochkin@measurement-factory.com>
     Don Hopkins <dhopkins@DonHopkins.com>
     Doug Dixon <doug.dixon@gmail.com>
     Doug Urner <dlu@bsdi.com>
     Dragutin Cirkovic <painkiller@gromnet.net>
+    drserge <drserge@inbox.ru>
     Dr. Tilmann Bubeck <t.bubeck@reinform.de>
     Duane Wessels <wessels@squid-cache.org>
     Dustin J. Mitchell
     Ed Knowles <ed@fatboy.geog.unsw.edu.au>
+    Edward Chernenko <edwardspec@gmail.com>
     Edward Moy <moy@parc.xerox.com>
+    Eldar Akchurin <al.akchurin@googlemail.com>
     Eliezer Croitoru <eliezer@ngtech.co.il>
     Elmar Vonlanthen <Elmar.Vonlanthen@united-security-providers.ch>
     Emilio Casbas <ecasbas@unav.es>
     Endre Balint Nagy <bne@CareNet.hu>
+    Eray Aslan <eraya@a21an.org>
     Eray Aslan <eray.aslan@caf.com.tr>
     Eric Stern <estern@logisense.com>
     Erik Hofman <erik.hofman@a1.nl>
     Eugene Gladchenko <eugene@donpac.ru>
     Evan Jones <ejones@uwaterloo.ca>
+    Evgeni <etg@setcom.bg>
     Eygene Ryabinkin <rea@freebsd.org>
+    Fabian Hugelshofer <fh@open.ch>
     fancyrabbit <fancyrabbit@gmail.com>
     Felix Meschberger <felix.meschberger@day.com>
+    Feshchuk Yuriy <swopster@meta.ua>
     Finn Thain <fthain@telegraphics.com.au>
     Flavio Pescuma <flavio@marasystems.com>
+    Florent <fcarli@gmail.com>
     folkert <folkert@vanheusden.com>
     Francesco Chemolli <kinkie@squid-cache.org>
     Francesco <kinkie@squid-cache.org>
@@ -100,13 +141,18 @@ Thank you!
     Frank Balluffi
     Frank Schmirler <squid@schmirler.de>
     Frederic Bourgeois <fredbmail@free.fr>
+    Fred <fred.maranhao@gmail.com>
+    F Wolff <friedel@translate.org.za>
+    Fyodor <fygrave@gmail.com>
     Geoff Keating <Geoff.Keating@anu.edu.au>
     George Michaelson <ggm@connect.com.au>
     Georgy Salnikov <sge@nmr.nioch.nsc.ru>
     Gerard Eviston
     Gerben Wierda <Gerben_Wierda@RnA.nl>
+    Gergely <mail.gery@gmail.com>
     Giancarlo Razzolini <linux-fan@onda.com.br>
     Gilles Espinasse <g.esp@free.fr>
+    gkeeling <grm___k@hotmail.com>
     Glen Gibb <grg@ridley.unimelb.edu.au>
     Glenn Chisholm <glenn@ircache.net>
     Glen Newton <glen.newton@nrc.ca>
@@ -116,21 +162,29 @@ Thank you!
     Graham Keeling <graham@equiinet.com>
     Guido Serassio <guido.serassio@acmeconsulting.it>
     Guido Serassio <serassio@squid-cache.org>
+    Gustavo Zacarias <gustavo@zacarias.com.ar>
+    Guy Helmer <ghelmer@palisadesys.com>
     Hank Hampel <hh@nr-city.net>
     Hasso Tepper <hasso@estpak.ee>
-    Henrik Nordstr?m <henrik@hlaptop.localdomain>
+    helix84 <helix84@centrum.sk>
     Henrik Nordstrom <henrik@henriknordstrom.net>
     Henrik Nordstrom <hno@squid-cache.org>
     Hide Nagaoka <hide@cc.meisei-u.ac.jp>
-    hno
+    HONDA Hirofumi <honda.hirofumi@nttcom.co.jp>
+    Hussam Al-Tayeb <hussam@visp.net.lb>
     Ian Castle <ian.castle@coldcomfortfarm.net>
     Ian Turner <vectro@pipeline.com>
     Igor Vinokurov <igor@cs.ibank.ru>
+    IIDA Yosiaki <y-iida@secom.co.jp>
+    isaac <isaacarsenal@gmail.com>
     Isnard <isnardjaquet@gmail.com>
+    Ivan Mas??r <helix84@centrum.sk>
     Jakob Bohm <jb-debbugs@wisemo.com>
     Jakub Wilk <ubanus@users.sf.net>
+    James Bowe <minijb@gmail.com>
     James Brotchie <brotchie@gmail.com>
     James R Grinter <jrg@demon.net>
+    Jan Klemkow <j.klemkow@wemelug.de>
     Jan Niehusmann <jan@anduin.gondor.mcs.de>
     Jan Sievers <sievers@zedat.fu-berlin.de>
     Jean-Francois Micouleau <Jean-Francois.Micouleau@utc.fr>
@@ -139,26 +193,35 @@ Thank you!
     Jens-S. V?ckler <voeckler@rvs.uni-hannover.de>
     Jeremy Allison
     Jerry Murdock <jmurdock@itraktech.com>
+    Jiri Skala <jaskalnik@gmail.com>
+    Jiri Skala <jskala@redhat.com>
     Joachim Bauch <jojo@fistofbenztown.de>
     Joachim Bauch (mail@joachim-bauch.de)
     Joao Alves Neto <alves_joao@hotmail.com>
     Jochen Obalek
     Jochen Voss <voss@seehuhn.de>
+    Joe Crayne <oh.hellojoe@gmail.com>
     Joe Ramey <ramey@csc.ti.com>
     Joe Ramey <ramey@jello.csc.ti.com>
+    Joerg Lehrke <jlehrke@noc.de>
     Johnathan Conley <johnathan.conley@gmail.com>
     John Dilley <jad@hpl.hp.com>
     John Saunders <johns@rd.scitec.com.au>
     John Xue <xgxjohn@gmail.com>
     Jonathan Larmour <JLarmour@origin-at.co.uk>
+    Jonathan Wolfe <jonathan.wolfe@gmail.com>
     Jon Kinred
     Jon Thackray <jrmt@uk.gdscorp.com>
+    Jorge Ivan Burgos Aguilar <jorgeivanburgosaguilar@gmail.com>
+    Jose-Marcio Martins da Cruz <Jose-Marcio.Martins@mines-paristech.fr>
+    Joshua Root <jmr@macports.org>
     Joshua Root <josh+squid@root.id.au>
     JPP <jpp1@frws.com>
+    Juan <jdsq12@yahoo.es>
     Juerg Michel
+    Julien Pinon <jpinon@olfeo.com>
+    Karl Benoit <karl.isatwork@gmail.com>
     Kieran Whitbread <k.j.whitbread@qmul.ac.uk>
-    Kinkie <kinkie@squid-cache.org>
-    kinkie@squid-cache.org
     Klaubert Herr <klaubert@gmail.com>
     Klaus Singvogel <kssingvo@suse.de>
     Kolics Bertold <bertold@tohotom.vein.hu>
@@ -166,12 +229,18 @@ Thank you!
     Lab10 <lab10@bt-anlagenbau.at>
     Laszlo Attilla Toth <panther@balabit.hu>
     Leeann Bent <lbent@cs.ucsd.edu>
+    Leonid Evdokimov <leon@darkk.net.ru>
     libit <sambabug.lb@gmail.com>
     Luigi Gangitano <luigi@debian.org>
+    Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>
+    Lukas B??gelei <unknown>
     Luke Howard <lukeh@vurt.schnet.edu.au>
     Lutz Donnerhacke <lutz@iks-jena.de>
     Manu Garg <manugarg@gmail.com>
-    Marcus Kool
+    Marcello Romani <marcello.romani@libero.it>
+    Marcin Wisnicki <mwisnicki@gmail.com>
+    Marco Beck <mbeck@miamod.de>
+    Marcus Kool <marcus.kool@urlfilterdb.com>
     Marc van Selm <selm@cistron.nl>
     Marin Stavrev <mstavrev@gmail.com>
     Marios Makassikis <mmakassikis@gmail.com>
@@ -182,16 +251,20 @@ Thank you!
     Mark Treacy <mark@aone.com.au>
     Markus Gyger <mgyger@itr.ch>
     Markus Moeller <huaraz@moeller.plus.com>
+    Markus Moeller (markus_moeller at compuserve.com)
     Markus Rietzler <markus.rietzler@rzf.fin-nrw.de>
     Markus Stumpf <maex@Space.NET>
     Martin Hamilton <martinh@gnu.org>
     Martin Hamilton <martin@mrrl.lut.ac.uk>
+    Martin Huter <mhuter@barracuda.com>
     Martin Huter <m.huter@phion.com>
     Martin Stolle <martin.stolle@ekom21.de>
     Masashi Fujita <objectx@bandit.co.jp>
     Massimo Zito <zmax.linkedin at gmail dot com>
+    Mathias Fischer <maf@open.ch>
     Matthew Morgan <atcs.matthew@gmail.com>
     Matthias Pitzl <silamael@coronamundi.de>
+    Matthias "Silamael" <Silamael@coronamundi.de>
     Max Okumoto <okumoto@ucsd.edu>
     Merik Karman
     <mgd@swarm.org>
@@ -201,41 +274,54 @@ Thank you!
     Michael O'Reilly <michael@metal.iinet.net.au>
     Michael Pelletier <mikep@comshare.com>
     Michael van Elst
+    Michael Weiser <michael@weiser.dinsnail.net>
     Michal Luscon <mluscon@redhat.com>
     Miguel A.L. Paraz <map@iphil.net>
     Mike Groeneweg <mikeg@scorpion.murdoch.edu.au>
+    Mike Mitchell <mike.mitchell@sas.com>
     Mike Mitchell <Mike.Mitchell@sas.com>
     Mikio Kishi <mkishi@104.net>
+    Milen Pankov <mail@milen.pankov.eu>
     Ming Fu <mfu@watchguard.com>
     Miquel van Smoorenburg <miquels@cistron.nl>
     Moez Mahfoudh <moez.mahfoudh@imag.fr>
+    Mohsen Saeedi <mohsen.saeedi@gmail.com>
     Mukaigawa Shin'ichi <shin@nff.ncl.omron.co.jp>
     Nathan Hoad <nathan@getoffmalawn.com>
     Neil Murray <neil@aone.com.au>
+    nglnx - Rosetta Project
     Niall Doherty <ndoherty@eei.ericsson.se>
     Nick Rogers <ncrogers@gmail.com>
     Nikolai Gorchilov <niki@x3me.net>
     'noloader' <noloader@gmail.com>
+    Ole Christensen <olechristensende@aol.de>
+    Oliver Dumschat <necromot@googlemail.com>
     Oliver Hookins
     Olivier Montanuy
+    Olivier W.
+    OpenSolaris Project
     Oskar Pearson <oskar@is.co.za>
     Paul Z <paulz42@gmail.com>
+    Pavel Timofeev
     Pawel Worach <pawel.worach@gmail.com>
     Pedro Lineu Orso <orso@pop.hsbcbamerindus.com.br>
     Pedro Ribeiro <pribeiro@isel.pt>
     Pete Bentley <pete@demon.net>
-    Peter Eisenhauer <pe@pipetronix.de>
     Peter Hidas <peter.hidas@safeland.hu>
+    Peter Payne
     Peter Pramberger <peter@pramberger.at>
     Philip Allison <philip.allison@smoothwall.net>
     Philippe Lantin <plantin@cobaltgroup.com>
+    Phil Oester <kernel@linuxace.com>
     Pierangelo Masarati <ando@sys-net.it>
+    Pierre LALET <pierre.lalet@cea.fr>
     Pierre-Louis Brenac <brenacp@esiee.fr>
     Pierre-Louis BRENAC <brenacp@esiee.fr>
     Poul-Henning Kamp <phk@login.dknet.dk>
     Priyanka Gupta <priyanka@icelero.com>
     Przemek Czerkas <pczerkas@mgmnet.pl>
     Rabellino Sergio (rabellino@di.unito.it)
+    Rafael Martinez <rmartine@fdi.ucm.es>
     Rafael Martinez Torres <rmartine@fdi.ucm.es>
     Rafal Ramocki <maniac@sistbg.net>
     Rajiv Desai <rajiv@maginatics.com>
@@ -244,8 +330,10 @@ Thank you!
     Ramon de Carvalho <ramondecarvalho@yahoo.com.br>
     Regardt van de Vyver <squid@vdvyver.net>
     Regents of the University of California (UCSD)
+    Reinhard Posmyk <Reinhard.Posmyk@arxes.de>
     Reinhard Sojka <reinhard.sojka@parlament.gv.at>
     Rene Geile <rene.geile@t-online.de>
+    Ren? Geile <rene.geile@t-online.de>
     Reuben Farrelly <reuben@reub.net>
     Richard Huveneers <richard@hekkihek.hacom.nl>
     Richard Huveneers <Richard.Huveneers@hekkihek.hacom.nl>
@@ -253,58 +341,85 @@ Thank you!
     Richard Wall <richard.wall@appliansys.com>
     Robert Collins <rbtcollins@hotmail.com>
     Robert Collins <robertc@robertcollins.net>
+    Robert <Dessa@gmake.de>
     Robert Forster
+    Robert Walsh <robert.walsh@bbn.com>
     Robin Elfrink <robin@a1.nl>
     Rodrigo Campos <rodrigo@geekbunker.org>
     Rodrigo Campos (rodrigo@geekbunker.org)
     Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
     Rodrigo Rubira Branco <rrbranco@br.ibm.com>
     Ron Gomes <rrg@ny.ubs.com>
-    rousskov
+    R Phillips <r.phillips@uq.edu.au>
     Russell Street <r.street@auckland.ac.nz>
     Russell Vincent <vincent@ucthpx.uct.ac.za>
     Ryan Troll <ryan+@andrew.cmu.edu>
     Samba Project
+    Santiago Garcia Mantinan <manty@debian.org>
+    Scott James Remnant <scott@netsplit.com>
     Scott Schram <scott@schram.net>
+    Sean Critica <sean.critica@gmail.com>
+    Sebastian Krahmer <krahmer@suse.com>
     Sebastien Wenske <sebastien@wenske.fr>
+    Sergey Merzlikin <sm@smsoft.ru>
     Sergio Rabellino <rabellino@di.unito.it>
     Shigechika Aikawa <shige@luck.imasy.or.jp>
     Silamael <Silamael@coronamundi.de>
-    squidadm@squid-cache.org
     Stefan Fritsch <sf@sfritsch.de>
     Stefano Cordibella <stefano.cordibella@edalab.it>
     Stephen R. van den Berg <srb@cuci.nl>
+    Stephen Thorne <stephen@thorne.id.au>
     Steve Bennett <S.Bennett@lancaster.ac.uk>
     Steve Hill <steve@opendium.com>
+    Steven Lawrance <squid@moonlightdesign.org>
     Steven Wilton <swilton@q-net.net.au>
     Steve Snyder <swsnyder@snydernet.net>
     Stewart Forster <slf@connect.com.au>
     Stuart Henderson <sthen@openbsd.org>
+    Stuart Henderson <stu@spacehopper.org>
     Susant Sahani <ssahani@redhat.com>
     Svenx <svensven@gmail.com>
     Taavi Talvik <taavi@uninet.ee>
     Taketo Kabe <kabe@shiratori.riec.tohoku.ac.jp>
     The Measurement Factory <info@measurement-factory.com>
+    The Squid Software Foundation
     Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
     Thomas Hozza <thozza@redhat.com>
     Thomas-Martin Seck <tmseck@netcologne.de>
     Thomas Ristic <thr@bootet.net>
     Thomas Weber <x@4t2.com>
     Tianyin Xu <tixu@cs.ucsd.edu>
+    Tilmann Bubeck <t.bubeck@reinform.de>
+    Tim Brown <squid-cache@machine.org.uk>
+    Timo Teras <timo.teras@iki.fi>
+    Timo Tseras <timo.teras@iki.fi>
     Tim Starling <tstarling@wikimedia.org>
     Todd C. Miller <Todd.Miller@courtesan.com>
     Tomas Hozza <thozza@redhat.com>
     Tony Lorimer <tlorimer@au.mdis.com>
+    Tsantilas Christos <chtsanti@users.sourceforge.net>
+    Unknown
     Unknown FreeBSD Contributor
     Unknown - NetBSD Project
+    Various
+    Various Translators
+    Victor Jose Hernandez Gomez <vjhergom@cic.upo.es>
     Vince Brimhall
     Vincent Regnard
     Vitaliy Matytsyn (main) <vm@if.bank.gov.ua>
     Vitaliy Matytsyn <vm@if.bank.gov.ua>
     vollkommen <vollkommen@gmx.net>
+    Walter <bundestrojaner2@googlemail.com>
+    Wang DaQing <wdq@bigfoot.com>
+    Warren Baker <warren@decoy.co.za>
     Wesha <wesha@iname.com>
     Will Roberts <squid@bigwillystyle42.com>
+    Wojciech Zatorski <zator@bg.szczecin.pl>
     Wojtek Sylwestrzak <W.Sylwestrzak@icm.edu.pl>
     Wolfgang Breyha <wbreyha@gmx.net>
     Wolfgang Nothdurft <wolfgang@linogate.de>
+    Xavier Redon <xavier.redon@polytech-lille.fr>
+    yabuki <yabuki@sraoss.co.jp>
+    Yannick Bergeron <yaberger@ca.ibm.com>
+    Yuhua Wu <ywu@bitglass.com>
     Zhanpeng Chen <lowstz@gmail.com>
diff --git a/CREDITS b/CREDITS
index 2938d3516befad9356eee0985bdf53af1a48fd4e..9c4d74f55fa4066e4cd8e23924c6d388ca4310c5 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -617,6 +617,45 @@ compat/xstrto.cc:
 
 ==============================================================================
 
+errors/:
+
+ *  Translation Snippets provided by Squid Project Translators held in
+ *  copyright for open distribution.
+ *
+ *  Translation Snippets provided by Rosetta Project Translators held in
+ *  copyright for open distribution.
+ *
+ *  Copyright 2009
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+
+see TRANSLATORS file for current contributing translators holding copyrights.
+
+==============================================================================
+
 errors/errorpage.css:
 
  Stylesheet for Squid Error pages
index 65da2352ed3edae5ad52196ce3b6e0c7f4f20195..37818e6d1660109a641fdb8951d762fa0c6e3ef9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Changes to squid-3.5.3 (28 Mar 2015):
+
+       - Regression Bug 4213: negotiate_kerberos_auth: freeing non-dynamic memory
+       - Regression Bug 4206: Incorrect connection close on expect:100-continue
+       - Bug 4204: ./configure does not abort when required helpers cannot be built
+       - Bug 3805: support shared memory on MacOS X in Mem::IPC::Segment
+       - Bug 2907: high CPU usage on CONNECT when using delay pools
+       - basic_getpwnam_auth: fail authentication on crypt() failures
+       - basic_nis_auth: fail authentication on crypt() failures
+       - ext_kerberos_ldap_group_acl: Heimdal support improvements
+       - ext_wbinfo_group_acl: Perl 5.20 support
+       - ... and several compile issues
+
 Changes to squid-3.5.2 (18 Feb 2015):
 
        - Regression Bug 4176: Digest auth too many helper lookups
diff --git a/INSTALL b/INSTALL
index c6731faee9b1be57a9825a8a5ddbef8490e69505..97721c110685619ee3e96781aa8d0954bc3a7cfb 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
 To build and install the Squid Cache, type:
 
        % ./configure --prefix=/usr/local/squid
@@ -16,5 +24,5 @@ To run a Cache, you will need to:
              % /usr/local/squid/sbin/squid
 
 If you want to use the WWW interface to the Cache Manager, copy
-the cachemgr.cgi program into your httpd server's cgi-bin
+the tools/cachemgr.cgi program into your httpd server's cgi-bin
 directory.
index 06c6bda296548cc1da7b61a3d24d17375b4c0817..f0294bab5f289af5b44ff3b300389b16e5aa2369 100644 (file)
@@ -20,40 +20,38 @@ Uncomment and edit the following lines in /usr/local/squid/etc/squid.conf:
 acl, http_access
 
     Access control lists.  This is important because it prevents people
-    from stealing your network resources.  To fill in the
-    "localnet" ACL, use your network address (for instance 192.168.10.0
-    your CIDR network mask (for instance 255.255.255.0 or /24):
+    from stealing your network resources.
+
+    Edit the "localnet" ACL definition to be your LAN network address
+    ranges in CIDR format. For instance:
 
-        acl manager proto cache_object
-        acl localhost src 127.0.0.1
         acl localnet src 192.168.10.0/24
 
-        http_access deny manager all
-        http_access allow localnet
-        http_access deny all
+    Add any other ACLs and edit the http_access lines to match your policy
+    requirements for use of the proxy. See Squid FAQ for more details.
 
 cache_mgr
 
-    Put here the e-mail address of the manager:
+    Put here the e-mail address of the manager.
+
+==============================================================================
+
+Some configuration lines which are optional but may be needed.
 
 visible_hostname
 
-    The host name you advertise for the cache.
+    The publicly visible host name advertised for the cache. This will
+    be used for URLs generated by Squid for clients to fetch certain
+    objects from.
 
 cache_effective_user
 
     If building your own squid; use ./configure --with-default-user=X
 
-    If you must start Squid as root, find a safe user and group to run
+    You must start Squid as root, with a safe user and group to run
     as after startup (typically "nobody" and "nogroup").  Do not use
     "root", for security reasons.
 
-
-==============================================================================
-
-Some configuration lines which are optional but may be needed.
-
-
 cache_dir ufs /usr/local/squid/var/cache 100 16 256
 
     Add here (first number, here 100) the amount of hard disk space 
@@ -98,5 +96,15 @@ Once you have Squid working from the command line, tell your Unix to
 start Squid at startup (it depends heavily on the Unix you use, you'll
 typically have to modify something in a /etc/rc_something).
 
-This quick start file written by: Stephane Bortzmeyer and Duane
-Wessels.
+==============================================================================
+
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+This quick start file written by:
+    Stephane Bortzmeyer and Duane Wessels.
index 0d6288b74a11eb4d1db4b03e5014f450dddde7bf..75bd6dff91d7fb7611dcab46ee3c12f01cea0b4a 100644 (file)
@@ -1,34 +1,49 @@
 The following organizations have supported the Squid Project by providing
 their resources or funding various Squid development activities:
 
-@Squid-3.4:
+@Squid-4:
 LaunchPad - http://launchpad.net/
 
-       Provide Bazaar mirroring services and host the Squid-3 developer
+       Provide Bazaar mirroring services and host the Squid-3+ developer
        project code.
 
-Messagenet - http://messagenet.it/
-
-       Messagenet donated hardware and bandwidth for the wiki server
-       and most continuous integration testing.
-
 RackSpace - http://www.rackspace.com/
 
        RackSpace donated a number of virtual machines from their cloud
        infrastructure to support and extend the continuous integration
-       testing infrastructure.
+       testing infrastructure, and since late 2014 to host many of the
+       Squid Project services.
+
+Squid Software Foundation - http://foundation.squid-cache.org/
+
+       The Foundation governs and facilitates Squid project activities,
+       providing the infrastructure and support framework for Squid
+       developers and users.
 
 The Measurement Factory - http://www.measurement-factory.com/
 
        Measurement Factory has constributed significant resources
-       toward Squid-3 development and server maintenance.
+       toward Squid-3+ development and server maintenance.
 
 Treehouse Networks, NZ - http://treenet.co.nz/
 
        Treehouse Networks has contributed significant resources
-       toward Squid-3 development and maintenance for their customer
+       toward Squid-3+ development and maintenance for their customer
        gateways and CDN.
 
+@Squid-3.5:
+Messagenet - http://messagenet.it/
+
+       Messagenet donated hardware and bandwidth for the wiki server
+       and most continuous integration testing until late 2014 when
+       it was converted to a Squid Project core mirror server.
+
+@Squid-3.4:
+anonymoX GmbH - http://anonymox.net/
+
+       anonymoX contributed sponsorship and resources towards resolving
+       and testing bug fixes in high performance Squid-3.4 proxies.
+
 @Squid-3.3:
 iCelero - http://icelero.com/
 
@@ -54,7 +69,8 @@ iiNet Ltd - http://www.iinet.net.au/
 
 Palisade Systems - http://www.palisadesys.com/
 
-       Palisade Systems funded SSL Bump feature development in Squid3.
+       Palisade Systems funded initial SSL Bump feature development
+       in Squid-3.2.
 
 @Squid-3.1:
 Barefruit - http://www.barefruit.com/
index 8f15b9a2152d9d2cae600d5aaba41e5d2c13c419..e7611109a28d272ad6e26b7d32627d907dc4029e 100644 (file)
@@ -79,6 +79,9 @@ AC_DEFUN([SQUID_CHECK_MAX_SKEW_IN_KRB5_CONTEXT],[
 KRB5INT_BEGIN_DECLS
 #endif
 #endif
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#endif
 #include <krb5.h>
 krb5_context kc; kc->max_skew = 1;
       ]])
@@ -100,6 +103,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_CONTEXT_MEMORY_CACHE],[
 KRB5INT_BEGIN_DECLS
 #endif
 #endif
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#endif
 #include <krb5.h>
 int main(int argc, char *argv[])
 {
@@ -127,6 +133,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_CONTEXT_MEMORY_KEYTAB],[
 KRB5INT_BEGIN_DECLS
 #endif
 #endif
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#endif
 #include <krb5.h>
 int main(int argc, char *argv[])
 {
@@ -157,6 +166,9 @@ AC_DEFUN([SQUID_CHECK_WORKING_GSSAPI], [
 #include <gss.h>
 #endif
 #else
+#if USE_APPLE_KRB5
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
 #if HAVE_GSSAPI_GSSAPI_H
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
@@ -200,6 +212,9 @@ AC_DEFUN([SQUID_CHECK_SPNEGO_SUPPORT], [
 #include <gss.h>
 #endif
 #else
+#if USE_APPLE_KRB5
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
 #if HAVE_GSSAPI_GSSAPI_H
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
@@ -239,6 +254,9 @@ dnl checks that krb5 is functional. Sets squid_cv_working_krb5
 AC_DEFUN([SQUID_CHECK_WORKING_KRB5],[
   AC_CACHE_CHECK([for working krb5], squid_cv_working_krb5, [
     AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#endif
 #if HAVE_KRB5_H
 #if HAVE_BROKEN_SOLARIS_KRB5_H
 #if defined(__cplusplus)
@@ -338,6 +356,9 @@ AC_DEFUN([SQUID_CHECK_KRB5_FUNCS],[
       [Define to 1 if you have krb5_get_init_creds_opt_alloc]),)
   AC_MSG_CHECKING([for krb5_get_init_creds_free requires krb5_context])
   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #if USE_APPLE_KRB5
+        #define KERBEROS_APPLE_DEPRECATED(x)
+        #endif
        #include <krb5.h>
     ]],[[krb5_context context;
         krb5_get_init_creds_opt *options;
index d1f2d2e946204ce5927c53a4dc2d4e459378ec78..57932b1fb627c33ad583286b3582ccdd63f1e2c4 100644 (file)
@@ -106,7 +106,10 @@ AC_DEFUN([SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS],[
    AC_DEFINE(SQUID_SSLGETCERTIFICATE_BUGGY, 1)
    AC_MSG_RESULT([yes])
   ],
-  [])
+  [
+   AC_DEFINE(SQUID_SSLGETCERTIFICATE_BUGGY, 0)
+   AC_MSG_RESULT([cross-compile, assuming no])
+  ])
 
   AC_MSG_CHECKING(whether the workaround for SSL_get_certificate works)
   AC_RUN_IFELSE([
@@ -132,7 +135,10 @@ AC_DEFUN([SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS],[
   [
    AC_MSG_RESULT([no])
   ],
-[])
+  [
+   AC_DEFINE(SQUID_USE_SSLGETCERTIFICATE_HACK, 0)
+   AC_MSG_RESULT([cross-compile, assuming no])
+  ])
 
 SQUID_STATE_ROLLBACK(check_SSL_get_certificate)
 ])
index eac4bb749e97ba06b2b732ec38d26fd13625660b..e713ccedc4e8718ef0e0262011b174a094f05d5b 100644 (file)
@@ -108,6 +108,19 @@ testPreCompiler::testIfDefAnd()
 #endif
     CPPUNIT_ASSERT(undefinedAndFalseB);
     CPPUNIT_ASSERT(!undefinedAndTrueB);
+
+#if UNDEFINED_FOO && UNDEFINED_FOO
+    bool undefinedAndUndefinedC = true;
+#else
+    bool undefinedAndUndefinedC = false;
+#endif
+#if !UNDEFINED_FOO && !UNDEFINED_FOO
+    bool notUndefinedAndNotUndefinedC = true;
+#else
+    bool notUndefinedAndNotUndefinedC = false;
+#endif
+    CPPUNIT_ASSERT(!undefinedAndUndefinedC);
+    CPPUNIT_ASSERT(notUndefinedAndNotUndefinedC);
 }
 
 /**
@@ -149,5 +162,17 @@ testPreCompiler::testIfDefOr()
     CPPUNIT_ASSERT(undefinedOrFalseB);
     CPPUNIT_ASSERT(!undefinedOrTrueB);
 
+#if UNDEFINED_FOO || UNDEFINED_FOO
+    bool undefinedOrUndefinedC = true;
+#else
+    bool undefinedOrUndefinedC = false;
+#endif
+#if !UNDEFINED_FOO || !UNDEFINED_FOO
+    bool notUndefinedOrNotUndefinedC = true;
+#else
+    bool notUndefinedOrNotUndefinedC = false;
+#endif
+    CPPUNIT_ASSERT(notUndefinedOrNotUndefinedC);
+    CPPUNIT_ASSERT(!undefinedOrUndefinedC);
 }
 
index 3833bfa285fd255ad29cea880a4e55e078dafd61..50211aa31091e2d4c732cf1b3fa0527687482e61 100644 (file)
 /* Typedefs for missing entries on a system           */
 /******************************************************/
 
+/*
+ * Ensure that standard type limits are defined for use
+ */
+#if __cplusplus >= 201103L
+#include <cstdint>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* explicit bit sizes */
+#if !defined(UINT32_MIN)
+#define UINT32_MIN    0x00000000L
+#endif
+#if !defined(UINT32_MAX)
+#define UINT32_MAX    0xFFFFFFFFL
+#endif
+
+#if !defined(INT_MAX)
+#define INT_MAX    0x7FFFFFFFL // hack but a safe bet (32-bit signed integer)
+#endif
+
+#if !defined(INT64_MIN)
+/* Native 64 bit system without strtoll() */
+#if defined(LONG_MIN) && (SIZEOF_LONG == 8)
+#define INT64_MIN    LONG_MIN
+#else
+/* 32 bit system */
+#define INT64_MIN    (-9223372036854775807LL-1LL)
+#endif
+#endif
+
+#if !defined(INT64_MAX)
+/* Native 64 bit system without strtoll() */
+#if defined(LONG_MAX) && (SIZEOF_LONG == 8)
+#define INT64_MAX    LONG_MAX
+#else
+/* 32 bit system */
+#define INT64_MAX    9223372036854775807LL
+#endif
+#endif
+
 /*
  * ISO C99 Standard printf() macros for 64 bit integers
  * On some 64 bit platform, HP Tru64 is one, for printf must be used
index 5b43401b5ba043d1222ea1eced983b3eece768e4..acd081743794e3cafe777c35fe67dc35cec51bc8 100644 (file)
@@ -5,7 +5,7 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-AC_INIT([Squid Web Proxy],[3.HEAD-BZR],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[4.0.0-BZR],[http://bugs.squid-cache.org/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -419,27 +419,39 @@ SQUID_DEFINE_BOOL(_USE_INLINE_,$enable_inline,
 # to be used by sub-commands
 export enable_inline
 
-dnl
-dnl Check for atomic operations support in the compiler
-dnl
-AC_MSG_CHECKING([for GNU atomic operations support])
+# Check for atomic operations support in the compiler
+AC_CACHE_CHECK([for GNU atomic operations support],[squid_cv_gnu_atomics],[
 AC_RUN_IFELSE([AC_LANG_PROGRAM([[
-    int n = 0;
+#include <cstdint>
+    int32_t n_32 = 0;
+    uint64_t n_64 = 0;
 ]],[[
-    __sync_add_and_fetch(&n, 10); // n becomes 10
-    __sync_fetch_and_add(&n, 20); // n becomes 30
-    __sync_sub_and_fetch(&n, 15); // n becomes 15
-    __sync_bool_compare_and_swap(&n, 15, 201); // n becomes 201
-    __sync_fetch_and_and(&n, 200); // n becomes 200
-    return (n == 200) ? 0 : -1;
+    // 32-bit
+    __sync_add_and_fetch(&n_32, 10); // n becomes 10
+    __sync_fetch_and_add(&n_32, 20); // n becomes 30
+    __sync_sub_and_fetch(&n_32, 15); // n becomes 15
+    __sync_bool_compare_and_swap(&n_32, 15, 201); // n becomes 201
+    __sync_fetch_and_and(&n_32, 200); // n becomes 200
+    if (n_32 != 200) return -1;
+
+    // 64-bit
+    __sync_add_and_fetch(&n_64, 10); // n becomes 10
+    __sync_fetch_and_add(&n_64, 20); // n becomes 30
+    __sync_sub_and_fetch(&n_64, 15); // n becomes 15
+    __sync_bool_compare_and_swap(&n_64, 15, 201); // n becomes 201
+    __sync_fetch_and_and(&n_64, 200); // n becomes 200
+    if (n_64 != 200) return -1;
+
+    // seems to be okay.
+    return 0;
 ]])],
 [
-    AC_DEFINE(HAVE_ATOMIC_OPS,1,[Define to 1 if you have __sync_add_and_fetch() and such])
-    AC_MSG_RESULT(yes)
+       squid_cv_gnu_atomics=yes
 ],[
-    AC_MSG_RESULT(no)
-],[ AC_MSG_RESULT(cross-compiler cant tell)
+       squid_cv_gnu_atomics=no
 ])
+])
+SQUID_DEFINE_BOOL(HAVE_ATOMIC_OPS,${squid_cv_gnu_atomics:=yes},[Define to 1 if you have GCC __sync_add_and_fetch() and such])
 
 AC_ARG_ENABLE(debug-cbdata,
   AS_HELP_STRING([--enable-debug-cbdata],
@@ -1399,6 +1411,7 @@ case "$with_mit_krb5" in
     with_mit_krb5=yes
 esac
 ])
+AH_TEMPLATE(USE_APPLE_KRB5,[Apple Kerberos support is available])
 AH_TEMPLATE(USE_MIT_KRB5,[MIT Kerberos support is available])
 AH_TEMPLATE(USE_SOLARIS_KRB5,[Solaris Kerberos support is available])
 
@@ -1489,6 +1502,7 @@ elif test $ac_with_krb5_count -eq 0 ; then
       krb5confpath="`dirname $ac_cv_path_krb5_config`"
       ac_heimdal="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i heimdal`"
       ac_solaris="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i solaris`"
+      ac_apple="`$ac_cv_path_krb5_config --vendor 2>/dev/null | grep -c -i apple`"
       if test $ac_heimdal -gt 0 ; then
        with_heimdal_krb5=yes
         ac_with_krb5_count=1
@@ -1497,7 +1511,11 @@ elif test $ac_with_krb5_count -eq 0 ; then
        with_solaris_krb5=yes
         ac_with_krb5_count=1
       fi
-      if test $ac_heimdal -eq 0 && test $ac_solaris -eq 0 ; then
+      if test $ac_apple -gt 0 ; then
+       with_apple_krb5=yes
+        ac_with_krb5_count=1
+      fi
+      if test $ac_heimdal -eq 0 && test $ac_solaris -eq 0 && test $ac_apple -eq 0; then
        with_mit_krb5=yes
         ac_with_krb5_count=1
       fi
@@ -1507,7 +1525,7 @@ elif test $ac_with_krb5_count -eq 0 ; then
   fi
 fi
 
-if test "x$with_mit_krb5" = "xyes"; then
+if test "x$with_mit_krb5" = "xyes" || test "x$with_apple_krb5" = "xyes" ; then
   SQUID_STATE_SAVE([squid_krb5_save])
   LIBS="$LIBS $LIB_KRB5_PATH"
 
@@ -1558,10 +1576,15 @@ if test "x$with_mit_krb5" = "xyes"; then
   ])
 
   if test "x$LIB_KRB5_LIBS" != "x"; then
+    if test "x$with_apple_krb5" = "xyes" ; then
+      AC_DEFINE(USE_APPLE_KRB5,1,[Apple Kerberos support is available])
+      KRB5_FLAVOUR="Apple" 
+    else
+      AC_DEFINE(USE_MIT_KRB5,1,[MIT Kerberos support is available])
+      KRB5_FLAVOUR="MIT" 
+    fi
     KRB5LIBS="$LIB_KRB5_PATH $LIB_KRB5_LIBS $KRB5LIBS"
     KRB5INCS="$LIB_KRB5_CFLAGS"
-    AC_DEFINE(USE_MIT_KRB5,1,[MIT Kerberos support is available])
-    KRB5_FLAVOUR="MIT" 
     
     # check for other specific broken implementations
     CXXFLAGS="$CXXFLAGS $KRB5INCS"
index 55f9821350a9891d96ffb4c0f04d17fb72227ad4..73e43125ea72e6c7879af6a88084db4054c06cee 100644 (file)
@@ -5,9 +5,9 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-all: release-3.6.html
+all: release-4.html
 
-DOC= release-3.6
+DOC= release-4
 
 $(DOC).ps: $(DOC).sgml
        linuxdoc -B latex -o ps $(DOC)
index 6988c3b7c7ecb29129b70be9824705daa86b7fb9..33161e5f14e0c8fa9fd4996869bf5e6007c4f26f 100644 (file)
@@ -1,6 +1,6 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid 3.5.2 release notes</title>
+<title>Squid 3.5.3 release notes</title>
 <author>Squid Developers</author>
 
 <abstract>
@@ -13,7 +13,7 @@ for Applied Network Research and members of the Web Caching community.
 
 <sect>Notice
 <p>
-The Squid Team are pleased to announce the release of Squid-3.5.2.
+The Squid Team are pleased to announce the release of Squid-3.5.3.
 
 This new release is available for download from <url url="http://www.squid-cache.org/Versions/v3/3.5/"> or the
  <url url="http://www.squid-cache.org/Download/http-mirrors.html" name="mirrors">.
@@ -389,6 +389,9 @@ This section gives a thorough account of those changes in three categories:
           for the HTTP transaction so far.
        <p>New type <em>at_step</em> to match the current SSL-Bump processing step.
           Never matches and should not be used outside of <em>ssl_bump</em>.
+       <p>New types <em>ssl::server_name</em> and <em>ssl::server_name_regex</em>
+          to match server name from various sources (CONNECT authority name,
+          TLS SNI domain, or X.509 certificate Subject Name).
 
        <tag>auth_param</tag>
        <p>New parameter <em>key_extras</em> to send additional parameters to
similarity index 55%
rename from doc/release-notes/release-3.6.html
rename to doc/release-notes/release-4.html
index 2f0f051934da10cd86a761838f693da549cf0def..2718fae3f27955cb6c705ec5a06ef426ce9753c9 100644 (file)
@@ -2,14 +2,14 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.69">
- <TITLE>Squid 3.6.0.0 release notes</TITLE>
+ <TITLE>Squid 4.0.0 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.6.0.0 release notes</H1>
+<H1>Squid 4.0.0 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
-<EM>This document contains the release notes for version 3.6 of Squid.
+<EM>This document contains the release notes for version 4 of Squid.
 Squid is a WWW Cache application developed by the National Laboratory
 for Applied Network Research and members of the Web Caching community.</EM>
 <HR>
@@ -18,13 +18,16 @@ for Applied Network Research and members of the Web Caching community.</EM>
 
 <UL>
 <LI><A NAME="toc1.1">1.1</A> <A HREF="#ss1.1">Known issues</A>
-<LI><A NAME="toc1.2">1.2</A> <A HREF="#ss1.2">Changes since earlier releases of Squid-3.6</A>
+<LI><A NAME="toc1.2">1.2</A> <A HREF="#ss1.2">Changes since earlier releases of Squid-4</A>
 </UL>
 <P>
 <H2><A NAME="toc2">2.</A> <A HREF="#s2">Major new features since Squid-3.5</A></H2>
 
 <UL>
 <LI><A NAME="toc2.1">2.1</A> <A HREF="#ss2.1">Configurable helper queue size</A>
+<LI><A NAME="toc2.2">2.2</A> <A HREF="#ss2.2">Helper concurrency channels changes</A>
+<LI><A NAME="toc2.3">2.3</A> <A HREF="#ss2.3">SSLv2 support removal</A>
+<LI><A NAME="toc2.4">2.4</A> <A HREF="#ss2.4">MSNT-multi-domain helper removal</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="#s3">Changes to squid.conf since Squid-3.5</A></H2>
@@ -55,10 +58,10 @@ for Applied Network Research and members of the Web Caching community.</EM>
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.6.0.0 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-4.0.0 for testing.</P>
 <P>This new release is available for download from 
-<A HREF="http://www.squid-cache.org/Versions/v3/3.6/">http://www.squid-cache.org/Versions/v3/3.6/</A> or the
-<A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
+<A HREF="http://www.squid-cache.org/Versions/v4/">http://www.squid-cache.org/Versions/v4/</A> or the
+<A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
 
 <P>While this release is not deemed ready for production use, we believe it is ready for wider testing by the community.</P>
 
@@ -70,22 +73,25 @@ for how to submit a report with a stack trace.</P>
 </H2>
 
 <P>Although this release is deemed good enough for use in many setups, please note the existence of 
-<A HREF="http://bugs.squid-cache.org/buglist.cgi?query_format=advanced&amp;product=Squid&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;version=3.6">open bugs against Squid-3.6</A>.</P>
+<A HREF="http://bugs.squid-cache.org/buglist.cgi?query_format=advanced&amp;product=Squid&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;version=4">open bugs against Squid-4</A>.</P>
 
-<H2><A NAME="ss1.2">1.2</A> <A HREF="#toc1.2">Changes since earlier releases of Squid-3.6</A>
+<H2><A NAME="ss1.2">1.2</A> <A HREF="#toc1.2">Changes since earlier releases of Squid-4</A>
 </H2>
 
-<P>The 3.6 change history can be 
-<A HREF="http://www.squid-cache.org/Versions/v3/3.6/changesets/">viewed here</A>.</P>
+<P>The Squid-4 change history can be 
+<A HREF="http://www.squid-cache.org/Versions/v4/changesets/">viewed here</A>.</P>
 
 
 <H2><A NAME="s2">2.</A> <A HREF="#toc2">Major new features since Squid-3.5</A></H2>
 
-<P>Squid 3.6 represents a new feature release above 3.5.</P>
+<P>Squid 4 represents a new feature release above 3.5.</P>
 
 <P>The most important of these new features are:
 <UL>
-<LI>BLAH</LI>
+<LI>Helper concurrency channels changes</LI>
+<LI>Configurable helper queue size</LI>
+<LI>SSLv2 support removal</LI>
+<LI>MSNT-multi-domain helper removal</LI>
 </UL>
 </P>
 <P>Most user-facing changes are reflected in squid.conf (see below).</P>
@@ -97,6 +103,43 @@ for how to submit a report with a stack trace.</P>
 <P>The new queue-size=N option to helpers configuration, allows users 
 to configure the maximum number of queued requests to busy helpers.</P>
 
+<H2><A NAME="ss2.2">2.2</A> <A HREF="#toc2.2">Helper concurrency channels changes</A>
+</H2>
+
+<P> helper-mux.pl we have been distributing for the past few years to
+encourage use of concurrency is no longer compatible with Squid. If
+used it will spawn up to 2^64 helpers and DoS the Squid server.</P>
+
+<P> Helpers utilizing arrays to handle fixed amounts of concurrency
+channels MUST be re-written to use queues and capable of handling a
+64-bit int as index or they will be vulnerable to buffer overrun and
+arbitrary memory accesses.</P>
+
+<P> 32-bit helpers need re-writing to handle the concurrency channel ID
+as a 64-bit integer value. If not updated they will cause proxies to
+return unexpected results or timeout once crossing the 32-bit wrap
+boundary. Leading to undefined behaviour in the client HTTP traffic.</P>
+
+<H2><A NAME="ss2.3">2.3</A> <A HREF="#toc2.3">SSLv2 support removal</A>
+</H2>
+
+<P>Details in 
+<A HREF="https://tools.ietf.org/html/rfc6176">RFC 6176</A></P>
+
+<P>SSLv2 is not fit for purpose. Squid no longer supports being configured with
+any settings regarding this protocol. That includes settings manually disabling
+its use since it is now forced to disable by default. Also settings enabling
+various client/server workarounds specific to SSLv2 are removed.</P>
+
+
+<H2><A NAME="ss2.4">2.4</A> <A HREF="#toc2.4">MSNT-multi-domain helper removal</A>
+</H2>
+
+<P>The <EM>basic_msnt_multi_domain_auth</EM> helper has been removed. The
+<EM>basic_smb_lm_auth</EM> helper performs the same actions without extra
+Perl and Samba dependencies.</P>
+
+
 <H2><A NAME="s3">3.</A> <A HREF="#toc3">Changes to squid.conf since Squid-3.5</A></H2>
 
 <P>There have been changes to Squid's configuration file since Squid-3.5.</P>
@@ -118,6 +161,14 @@ to configure the maximum number of queued requests to busy helpers.</P>
 
 <P>
 <DL>
+<DT><B>tls_outgoing_options</B><DD>
+<P>New tag to define TLS security context options for outgoing
+connections. For example to HTTPS servers.</P>
+
+<DT><B>url_rewrite_timeout</B><DD>
+<P>Squid times active requests to redirector. This option sets
+the timeout value and the Squid reaction to a timed out
+request.</P>
 
 </DL>
 </P>
@@ -127,29 +178,48 @@ to configure the maximum number of queued requests to busy helpers.</P>
 
 <P>
 <DL>
-<DT><B> auth_param </B><DD>
-<P> New parameter <EM>queue-size=</EM> to set the maximum number
+<DT><B>auth_param</B><DD>
+<P>New parameter <EM>queue-size=</EM> to set the maximum number
 of queued requests.</P>
 
-<DT><B>external_acl_type</B><DD>
+<DT><B>cache_peer</B><DD>
+<P>All <EM>ssloption=</EM> and <EM>sslversion=</EM> values for
+SSLv2 configuration or disabling have been removed.</P>
+<P>Manual squid.conf update may be required on upgrade.</P>
 
-<DT><B></B><DD>
-<P> New parameter <EM>queue-size=</EM> to set the maximum number
+<DT><B>external_acl_type</B><DD>
+<P>New parameter <EM>queue-size=</EM> to set the maximum number
 of queued requests.</P>
 
-<DT><B>url_rewrite_children</B><DD>
+<DT><B>http_port</B><DD>
+<P>All <EM>version=</EM> <EM>option=</EM> values for SSLv2
+configuration or disabling have been removed.</P>
+<P>Manual squid.conf update may be required on upgrade.</P>
 
-<DT><B></B><DD>
-<P> New parameter <EM>queue-size=</EM> to set the maximum number
-of queued requests.</P>
+<DT><B>https_port</B><DD>
+<P>All <EM>version=</EM> <EM>option=</EM> values for SSLv2
+configuration or disabling have been removed.</P>
+<P>Manual squid.conf update may be required on upgrade.</P>
 
 <DT><B>sslcrtd_children</B><DD>
-<P> New parameter <EM>queue-size=</EM> to set the maximum number
+<P>New parameter <EM>queue-size=</EM> to set the maximum number
 of queued requests.</P>
 
 <DT><B>sslcrtvalidator_children</B><DD>
-<P> New parameter <EM>queue-size=</EM> to set the maximum number
+<P>New parameter <EM>queue-size=</EM> to set the maximum number
 of queued requests.</P>
+
+<DT><B>sslproxy_options</B><DD>
+<P>All values for SSLv2 configuration or disabling have been removed.</P>
+<P>Manual squid.conf update may be required on upgrade.</P>
+
+<DT><B>sslproxy_version</B><DD>
+<P>Value '2' for SSLv2-only operation is no longer supported.</P>
+
+<DT><B>url_rewrite_children</B><DD>
+<P>New parameter <EM>queue-size=</EM> to set the maximum number
+of queued requests.</P>
+
 </DL>
 </P>
 
@@ -158,6 +228,38 @@ of queued requests.</P>
 
 <P>
 <DL>
+<DT><B>cache_peer_domain</B><DD>
+<P>Superceded by <EM>cache_peer_access</EM>. Use dstdomain ACL
+in the access control list to restrict domains requested.</P>
+
+<DT><B>refresh_pattern</B><DD>
+<P>Option <EM>ignore-auth</EM> removed. Its original intent was
+to improve caching. HTTP/1.1 permits caching of authenticated
+messages under conditions which Squid does check for and obey.</P>
+
+<DT><B>sslproxy_cafile</B><DD>
+<P>Replaced by <EM>tls_outgoing_options cafile=</EM>.</P>
+
+<DT><B>sslproxy_capath</B><DD>
+<P>Replaced by <EM>tls_outgoing_options capath=</EM>.</P>
+
+<DT><B>sslproxy_cipher</B><DD>
+<P>Replaced by <EM>tls_outgoing_options cipher=</EM>.</P>
+
+<DT><B>sslproxy_client_certificate</B><DD>
+<P>Replaced by <EM>tls_outgoing_options cert=</EM>.</P>
+
+<DT><B>sslproxy_client_key</B><DD>
+<P>Replaced by <EM>tls_outgoing_options key=</EM>.</P>
+
+<DT><B>sslproxy_flags</B><DD>
+<P>Replaced by <EM>tls_outgoing_options flags=</EM>.</P>
+
+<DT><B>sslproxy_options</B><DD>
+<P>Replaced by <EM>tls_outgoing_options options=</EM>.</P>
+
+<DT><B>sslproxy_version</B><DD>
+<P>Replaced by <EM>tls_outgoing_options version=</EM>.</P>
 
 </DL>
 </P>
@@ -193,6 +295,8 @@ of queued requests.</P>
 
 <P>
 <DL>
+<DT><B>--enable-auth-basic</B><DD>
+<P>The <EM>MSNT-multi-domain</EM> helper has been removed.</P>
 
 </DL>
 </P>
@@ -208,7 +312,7 @@ of queued requests.</P>
 
 <H2><A NAME="s5">5.</A> <A HREF="#toc5">Regressions since Squid-2.7</A></H2>
 
-<P>Some squid.conf options which were available in Squid-2.7 are not yet available in Squid-3.6</P>
+<P>Some squid.conf options which were available in Squid-2.7 are not yet available in Squid-4</P>
 
 <P>If you need something to do then porting one of these from Squid-2 to Squid-3 is most welcome.</P>
 
similarity index 93%
rename from doc/release-notes/release-3.6.sgml
rename to doc/release-notes/release-4.sgml
index 026700a2310d0ba4262076a5c1fa8c83767ba520..6c473bf10bf9a3a1fd7b869022a185b7287fd5af 100644 (file)
@@ -1,10 +1,10 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid 3.6.0.0 release notes</title>
+<title>Squid 4.0.0 release notes</title>
 <author>Squid Developers</author>
 
 <abstract>
-This document contains the release notes for version 3.6 of Squid.
+This document contains the release notes for version 4 of Squid.
 Squid is a WWW Cache application developed by the National Laboratory
 for Applied Network Research and members of the Web Caching community.
 </abstract>
@@ -13,9 +13,9 @@ for Applied Network Research and members of the Web Caching community.
 
 <sect>Notice
 <p>
-The Squid Team are pleased to announce the release of Squid-3.6.0.0 for testing.
+The Squid Team are pleased to announce the release of Squid-4.0.0 for testing.
 
-This new release is available for download from <url url="http://www.squid-cache.org/Versions/v3/3.6/"> or the
+This new release is available for download from <url url="http://www.squid-cache.org/Versions/v4/"> or the
  <url url="http://www.squid-cache.org/Download/http-mirrors.html" name="mirrors">.
 
 <p>While this release is not deemed ready for production use, we believe it is ready for wider testing by the community.
@@ -26,15 +26,15 @@ This new release is available for download from <url url="http://www.squid-cache
 <sect1>Known issues
 <p>
 Although this release is deemed good enough for use in many setups, please note the existence of 
-<url url="http://bugs.squid-cache.org/buglist.cgi?query_format=advanced&amp;product=Squid&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;version=3.6" name="open bugs against Squid-3.6">.
+<url url="http://bugs.squid-cache.org/buglist.cgi?query_format=advanced&amp;product=Squid&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;version=4" name="open bugs against Squid-4">.
 
-<sect1>Changes since earlier releases of Squid-3.6
+<sect1>Changes since earlier releases of Squid-4
 <p>
-The 3.6 change history can be <url url="http://www.squid-cache.org/Versions/v3/3.6/changesets/" name="viewed here">.
+The Squid-4 change history can be <url url="http://www.squid-cache.org/Versions/v4/changesets/" name="viewed here">.
 
 
 <sect>Major new features since Squid-3.5
-<p>Squid 3.6 represents a new feature release above 3.5.
+<p>Squid 4 represents a new feature release above 3.5.
 
 <p>The most important of these new features are:
 <itemize>
@@ -121,7 +121,7 @@ This section gives a thorough account of those changes in three categories:
           SSLv2 configuration or disabling have been removed.
        <p>Manual squid.conf update may be required on upgrade.
 
-       <tag>external_acl_type<tag>
+       <tag>external_acl_type</tag>
        <p>New parameter <em>queue-size=</em> to set the maximum number
           of queued requests.
 
@@ -150,7 +150,7 @@ This section gives a thorough account of those changes in three categories:
        <tag>sslproxy_version</tag>
        <p>Value '2' for SSLv2-only operation is no longer supported.
 
-       <tag>url_rewrite_children<tag>
+       <tag>url_rewrite_children</tag>
        <p>New parameter <em>queue-size=</em> to set the maximum number
           of queued requests.
 
@@ -232,7 +232,7 @@ This section gives an account of those changes in three categories:
 
 <sect>Regressions since Squid-2.7
 
-<p>Some squid.conf options which were available in Squid-2.7 are not yet available in Squid-3.6
+<p>Some squid.conf options which were available in Squid-2.7 are not yet available in Squid-4
 
 <p>If you need something to do then porting one of these from Squid-2 to Squid-3 is most welcome.
 
index f345938885323ecdac5b56ce8d991b03e1ed0015..877c67a6461891070480d9bd4010fa8e565b968a 100644 (file)
@@ -197,10 +197,10 @@ rfc7234.txt
 rfc7235.txt
        Hypertext Transfer Protocol (HTTP/1.1): Authentication
 
-rfc7238.txt
-       The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)
-
 rfc7239.txt
        Forwarded HTTP Extension
        Details the Forwarded: header replacement for X-Forwarded-For
        and other X-Forwarded-* variants
+
+rfc7538.txt
+       The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)
similarity index 57%
rename from doc/rfc/rfc7238.txt
rename to doc/rfc/rfc7538.txt
index 3ec2ce82d0524ed4caa610f0f485bddfa9ae200d..730927ee65a88edfa946408bb6fa3d649f7e791a 100644 (file)
@@ -5,8 +5,9 @@
 
 
 Internet Engineering Task Force (IETF)                        J. Reschke
-Request for Comments: 7238                                    greenbytes
-Category: Experimental                                         June 2014
+Request for Comments: 7538                                    greenbytes
+Obsoletes: 7238                                               April 2015
+Category: Standards Track
 ISSN: 2070-1721
 
 
@@ -19,25 +20,21 @@ Abstract
 
 Status of This Memo
 
-   This document is not an Internet Standards Track specification; it is
-   published for examination, experimental implementation, and
-   evaluation.
+   This is an Internet Standards Track document.
 
-   This document defines an Experimental Protocol for the Internet
-   community.  This document is a product of the Internet Engineering
-   Task Force (IETF).  It represents the consensus of the IETF
-   community.  It has received public review and has been approved for
-   publication by the Internet Engineering Steering Group (IESG).  Not
-   all documents approved by the IESG are a candidate for any level of
-   Internet Standard; see Section 2 of RFC 5741.
+   This document is a product of the Internet Engineering Task Force
+   (IETF).  It represents the consensus of the IETF community.  It has
+   received public review and has been approved for publication by the
+   Internet Engineering Steering Group (IESG).  Further information on
+   Internet Standards is available in Section 2 of RFC 5741.
 
    Information about the current status of this document, any errata,
    and how to provide feedback on it may be obtained at
-   http://www.rfc-editor.org/info/rfc7238.
+   http://www.rfc-editor.org/info/rfc7538.
 
 Copyright Notice
 
-   Copyright (c) 2014 IETF Trust and the persons identified as the
+   Copyright (c) 2015 IETF Trust and the persons identified as the
    document authors.  All rights reserved.
 
    This document is subject to BCP 78 and the IETF Trust's Legal
@@ -55,23 +52,27 @@ Copyright Notice
 
 
 
-Reschke                       Experimental                      [Page 1]
+
+
+
+Reschke                      Standards Track                    [Page 1]
 \f
-RFC 7238                  HTTP Status Code 308                 June 2014
+RFC 7538                  HTTP Status Code 308                April 2015
 
 
 Table of Contents
 
-   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . . . 2
-   2.  Notational Conventions  . . . . . . . . . . . . . . . . . . . . 2
-   3.  308 Permanent Redirect  . . . . . . . . . . . . . . . . . . . . 2
-   4.  Deployment Considerations . . . . . . . . . . . . . . . . . . . 3
-   5.  Security Considerations . . . . . . . . . . . . . . . . . . . . 4
-   6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 4
-   7.  Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . 5
-   8.  References  . . . . . . . . . . . . . . . . . . . . . . . . . . 5
-     8.1.  Normative References  . . . . . . . . . . . . . . . . . . . 5
-     8.2.  Informative References  . . . . . . . . . . . . . . . . . . 5
+   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
+   2.  Notational Conventions  . . . . . . . . . . . . . . . . . . .   2
+   3.  308 Permanent Redirect  . . . . . . . . . . . . . . . . . . .   3
+   4.  Deployment Considerations . . . . . . . . . . . . . . . . . .   3
+   5.  Security Considerations . . . . . . . . . . . . . . . . . . .   4
+   6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .   5
+   7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .   5
+     7.1.  Normative References  . . . . . . . . . . . . . . . . . .   5
+     7.2.  Informative References  . . . . . . . . . . . . . . . . .   5
+   Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .   6
+   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .   6
 
 1.  Introduction
 
@@ -93,9 +94,12 @@ Table of Contents
    | method from POST to GET                   |           |           |
    +-------------------------------------------+-----------+-----------+
 
-   Section 6.4.7 of [RFC7231] states that HTTP does not define a
-   permanent variant of status code 307; this specification adds the
-   status code 308, defining this missing variant (Section 3).
+   Section 6.4.7 of [RFC7231] states that it does not define a permanent
+   variant of status code 307; this specification adds the status code
+   308, defining this missing variant (Section 3).
+
+   This specification contains no technical changes from the
+   Experimental RFC 7238, which it obsoletes.
 
 2.  Notational Conventions
 
@@ -103,19 +107,20 @@ Table of Contents
    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
    document are to be interpreted as described in [RFC2119].
 
-3.  308 Permanent Redirect
 
-   The 308 (Permanent Redirect) status code indicates that the target
-   resource has been assigned a new permanent URI and any future
-   references to this resource ought to use one of the enclosed URIs.
 
 
 
-Reschke                       Experimental                      [Page 2]
+Reschke                      Standards Track                    [Page 2]
 \f
-RFC 7238                  HTTP Status Code 308                 June 2014
+RFC 7538                  HTTP Status Code 308                April 2015
+
 
+3.  308 Permanent Redirect
 
+   The 308 (Permanent Redirect) status code indicates that the target
+   resource has been assigned a new permanent URI and any future
+   references to this resource ought to use one of the enclosed URIs.
    Clients with link editing capabilities ought to automatically re-link
    references to the effective request URI (Section 5.5 of [RFC7230]) to
    one or more of the new references sent by the server, where possible.
@@ -138,38 +143,44 @@ RFC 7238                  HTTP Status Code 308                 June 2014
 4.  Deployment Considerations
 
    Section 6 of [RFC7231] requires recipients to treat unknown 3xx
-   status codes the same way as status code 300 Multiple Choices
+   status codes the same way as status code 300 (Multiple Choices)
    ([RFC7231], Section 6.4.1).  Thus, servers will not be able to rely
    on automatic redirection happening similar to status codes 301, 302,
    or 307.
 
-   Therefore, initial use of status code 308 will be restricted to cases
-   where the server has sufficient confidence in the client's
-   understanding the new code or when a fallback to the semantics of
-   status code 300 is not problematic.  Server implementers are advised
-   not to vary the status code based on characteristics of the request,
-   such as the User-Agent header field ("User-Agent Sniffing") -- doing
-   so usually results in code that is both hard to maintain and hard to
-   debug and would also require special attention to caching (i.e.,
-   setting a "Vary" response header field, as defined in Section 7.1.4
-   of [RFC7231]).
+   Therefore, the use of status code 308 is restricted to cases where
+   the server has sufficient confidence in the client's understanding
+   the new code or when a fallback to the semantics of status code 300
+   is not problematic.  Server implementers are advised not to vary the
+   status code based on characteristics of the request, such as the
+   User-Agent header field ("User-Agent Sniffing") -- doing so usually
+   results in code that is both hard to maintain and hard to debug and
+   would also require special attention to caching (i.e., setting a
+   "Vary" response header field, as defined in Section 7.1.4 of
+   [RFC7231]).
 
-   Note that many existing HTML-based user agents will emulate a refresh
-   when encountering an HTML <meta> refresh directive ([HTML]).  This
-   can be used as another fallback.  For example:
 
-   Client request:
 
-     GET / HTTP/1.1
-     Host: example.com
 
 
 
 
 
-Reschke                       Experimental                      [Page 3]
+
+Reschke                      Standards Track                    [Page 3]
 \f
-RFC 7238                  HTTP Status Code 308                 June 2014
+RFC 7538                  HTTP Status Code 308                April 2015
+
+
+   Note that many existing HTML-based user agents will emulate a refresh
+   when encountering an HTML <meta> refresh directive ([HTML],
+   Section 4.2.5.3).  This can be used as another fallback.  For
+   example:
+
+   Client request:
+
+     GET / HTTP/1.1
+     Host: example.com
 
 
    Server response:
@@ -177,10 +188,9 @@ RFC 7238                  HTTP Status Code 308                 June 2014
      HTTP/1.1 308 Permanent Redirect
      Content-Type: text/html; charset=UTF-8
      Location: http://example.com/new
-     Content-Length: 454
+     Content-Length: 356
 
-     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-                           "http://www.w3.org/TR/html4/strict.dtd">
+     <!DOCTYPE HTML>
      <html>
         <head>
            <title>Permanent Redirect</title>
@@ -201,19 +211,11 @@ RFC 7238                  HTTP Status Code 308                 June 2014
    All security considerations that apply to HTTP redirects apply to the
    308 status code as well (see Section 9 of [RFC7231]).
 
-6.  IANA Considerations
-
-   The registration below has been added to the "Hypertext Transfer
-   Protocol (HTTP) Status Code Registry" (defined in Section 8.2 of
-   [RFC7231] and located at
-   <http://www.iana.org/assignments/http-status-codes>):
-
-   +-------+--------------------+---------------------------------+
-   | Value | Description        | Reference                       |
-   +-------+--------------------+---------------------------------+
-   | 308   | Permanent Redirect | Section 3 of this specification |
-   +-------+--------------------+---------------------------------+
-
+   Unsecured communication over the Internet is subject to man-in-the-
+   middle modification of messages, including changing status codes or
+   redirect targets.  Use of Transport Layer Security (TLS) is one way
+   to mitigate those attacks.  See Section 9 of [RFC7230] for related
+   attacks on authority and message integrity.
 
 
 
@@ -221,68 +223,76 @@ RFC 7238                  HTTP Status Code 308                 June 2014
 
 
 
-
-
-Reschke                       Experimental                      [Page 4]
+Reschke                      Standards Track                    [Page 4]
 \f
-RFC 7238                  HTTP Status Code 308                 June 2014
+RFC 7538                  HTTP Status Code 308                April 2015
 
 
-7.  Acknowledgements
+6.  IANA Considerations
 
-   The definition for the new status code 308 reuses text from the
-   HTTP/1.1 definitions of status codes 301 and 307.
+   The "Hypertext Transfer Protocol (HTTP) Status Code Registry"
+   (defined in Section 8.2 of [RFC7231] and located at
+   <http://www.iana.org/assignments/http-status-codes>) has been updated
+   to reference this specification.
 
-   Furthermore, thanks to Ben Campbell, Cyrus Daboo, Eran Hammer-Lahav,
-   Bjoern Hoehrmann, Subramanian Moonesamy, Peter Saint-Andre, and
-   Robert Sparks for feedback on this document.
+   +-------+--------------------+----------------------------------+
+   | Value | Description        | Reference                        |
+   +-------+--------------------+----------------------------------+
+   | 308   | Permanent Redirect | Section 3 of this specification  |
+   +-------+--------------------+----------------------------------+
 
-8.  References
+7.  References
 
-8.1.  Normative References
+7.1.  Normative References
 
    [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
-              Requirement Levels", BCP 14, RFC 2119, March 1997.
+              Requirement Levels", BCP 14, RFC 2119, March 1997,
+              <http://www.rfc-editor.org/info/rfc2119>.
 
    [RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
-              Resource Identifier (URI): Generic Syntax", STD 66,
-              RFC 3986, January 2005.
+              Resource Identifier (URI): Generic Syntax", STD 66, RFC
+              3986, January 2005,
+              <http://www.rfc-editor.org/info/rfc3986>.
 
    [RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
-              Protocol (HTTP/1.1): Message Syntax and Routing",
-              RFC 7230, June 2014.
+              Protocol (HTTP/1.1): Message Syntax and Routing", RFC
+              7230, June 2014, <http://www.rfc-editor.org/info/rfc7230>.
 
    [RFC7231]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
               Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
-              June 2014.
+              June 2014, <http://www.rfc-editor.org/info/rfc7231>.
 
    [RFC7234]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
               Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
-              RFC 7234, June 2014.
-
-8.2.  Informative References
-
-   [HTML]     Raggett, D., Le Hors, A., and I. Jacobs, "HTML 4.01
-              Specification", W3C Recommendation REC-html401-19991224,
-              December 1999,
-              <http://www.w3.org/TR/1999/REC-html401-19991224>.
-
-              Latest version available at
-              <http://www.w3.org/TR/html401>.
+              RFC 7234, June 2014,
+              <http://www.rfc-editor.org/info/rfc7234>.
 
+7.2.  Informative References
 
+   [HTML]     Hickson, I., Berjon, R., Faulkner, S., Leithead, T., Doyle
+              Navara, E., O'Connor, E., and S. Pfeiffer, "HTML5", W3C
+              Recommendation REC-html5-20141028, October 2014,
+              <http://www.w3.org/TR/2014/REC-html5-20141028/>.
 
+              Latest version available at <http://www.w3.org/TR/html5/>.
 
 
 
 
+Reschke                      Standards Track                    [Page 5]
+\f
+RFC 7538                  HTTP Status Code 308                April 2015
 
 
+Acknowledgements
 
-Reschke                       Experimental                      [Page 5]
-\f
-RFC 7238                  HTTP Status Code 308                 June 2014
+   The definition for the new status code 308 reuses text from the
+   HTTP/1.1 definitions of status codes 301 and 307.
 
+   Furthermore, thanks to Ben Campbell, Cyrus Daboo, Adrian Farrell,
+   Eran Hammer-Lahav, Bjoern Hoehrmann, Barry Leiba, Subramanian
+   Moonesamy, Kathleen Moriarty, Peter Saint-Andre, Robert Sparks, and
+   Roy Fielding for feedback on this document.
 
 Author's Address
 
@@ -325,15 +335,5 @@ Author's Address
 
 
 
-
-
-
-
-
-
-
-
-
-
-Reschke                       Experimental                      [Page 6]
+Reschke                      Standards Track                    [Page 6]
 \f
index 16dbcd9106c0aa43b547d8188e36e562350dd6fc..850a8604ca486dab8a49fca13031ee6810128de9 100644 (file)
@@ -1,34 +1,10 @@
 ==============================================================================
 
-SQUID Internet Object Cache  http://www.squid-cache.org
---------------------------------------------------------
-
-  Squid is the result of efforts by numerous individuals from the
-  Internet community.  Development is led by Duane Wessels of the
-  National Laboratory for Applied Network Research and funded by
-  the National Science Foundation.
-
-  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 General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-  MA 02110-1301, USA.
-
-Squid is derived from the ``cached'' software from the ARPA-funded
-Harvest research project.  The Harvest home page is
-http://harvest.cs.colorado.edu/.
-
-Squid is originally derived from the Harvest Information Discovery and
-Access System.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
 
 ==============================================================================
 
index 192776c73f47fbaf828f13cb63535adf9dd4b4ba..8ab868b25c3b8d0275a6f8392a0aec697f6da6de 100644 (file)
@@ -19,8 +19,10 @@ if test "x$enable_auth_basic" != "xno" -a "x$enable_auth" = "xno" ; then
     AC_MSG_ERROR([Basic auth requested but auth disabled])
 fi
 #define list of modules to build
+auto_auth_basic_modules=no
 if test "x$enable_auth_basic" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/basic_auth],[enable_auth_basic])
+  auto_auth_basic_modules=yes
 fi
 #handle the "none" special case
 if test "x$enable_auth_basic" = "xnone" ; then
@@ -84,7 +86,11 @@ if test "x$enable_auth_basic" != "xno" ; then
 
       if test -d "$srcdir/helpers/basic_auth/$helper"; then
         if test "$BUILD_HELPER" != "$helper"; then
-          AC_MSG_NOTICE([Basic auth helper $helper ... found but cannot be built])
+          if test "x$auto_auth_basic_modules" = "xyes"; then
+            AC_MSG_NOTICE([Basic auth helper $helper ... found but cannot be built])
+          else
+            AC_MSG_ERROR([Basic auth helper $helper ... found but cannot be built])
+          fi
         else
           BASIC_AUTH_HELPERS="$BASIC_AUTH_HELPERS $BUILD_HELPER"
         fi
index d16c1e71c22a58df6c4526e20f0e1b3f1852790f..c99bc1d170bdb833a8d4ecc33e2deb73786acba7 100644 (file)
@@ -23,6 +23,7 @@ digest_edirectory_auth_LDADD = \
        $(COMPAT_LIB) \
        $(LDAPLIB) \
        $(LBERLIB) \
+       $(NETTLELIB) \
        $(CRYPTLIB) \
        $(SSLLIB) \
        $(XTRA_LIBS)
index 4c682492868955d75620365d4d9e073b9392f8d5..5c7c968d095ec6a2f952f2c429330bcf08b043b4 100755 (executable)
@@ -5,4 +5,4 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-AC_CHECK_HEADERS([ldap.h winldap.h],[BUILD_HELPER="LDAP"])
+AC_CHECK_HEADERS([ldap.h winldap.h],[BUILD_HELPER="eDirectory"])
index 1ad4988036ac5221ab80e5abc40c48d8a1f8a613..443c2672e758aa6561fe79f17cf009bb8e780f4c 100644 (file)
@@ -19,8 +19,10 @@ if test "x$enable_auth_digest" != "xno" -a "x$enable_auth" = "xno" ; then
     AC_MSG_ERROR([Digest auth requested but auth disabled])
 fi
 #define list of modules to build
+auto_auth_digest_modules=no
 if test "x$enable_auth_digest" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/digest_auth],[enable_auth_digest])
+  auto_auth_digest_modules=yes
 fi
 #handle the "none" special case
 if test "x$enable_auth_digest" = "xnone" ; then
@@ -53,7 +55,11 @@ if test "x$enable_auth_digest" != "xno" ; then
 
       if test -d "$srcdir/helpers/digest_auth/$helper"; then
         if test "$BUILD_HELPER" != "$helper"; then
-          AC_MSG_NOTICE([Digest auth helper $helper ... found but cannot be built])
+          if test "x$auto_auth_digest_modules" = "xyes"; then
+            AC_MSG_NOTICE([Digest auth helper $helper ... found but cannot be built])
+          else
+            AC_MSG_ERROR([Digest auth helper $helper ... found but cannot be built])
+          fi
         else
           DIGEST_AUTH_HELPERS="$DIGEST_AUTH_HELPERS $BUILD_HELPER"
         fi
index c7e64096ec9fd5d1644ca35d82d14bc963281868..f3297c5c1b75788418906884951b50b729a8d332 100644 (file)
@@ -7,5 +7,10 @@
 
 if test "x$with_krb5" == "xyes"; then
   BUILD_HELPER="kerberos_ldap_group"
+  if test "x$with_apple_krb5" = "xyes" ; then
+    AC_CHECK_LIB(resolv, [main], [XTRA_LIBS="$XTRA_LIBS -lresolv"],[
+      AC_MSG_ERROR([library 'resolv' is required for Apple Kerberos])
+    ])
+  fi
   SQUID_CHECK_SASL
 fi
index 41cab4e7582a7323ec6a0e89f8ad0698ee6a66d7..db49836df77f3422f8a24139c1abc5948e8dfe62 100644 (file)
 
 #include <cstring>
 
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#endif
+
 #if HAVE_KRB5_H
 #if HAVE_BROKEN_SOLARIS_KRB5_H
 #warn "Warning! You have a broken Solaris <krb5.h> system header"
index f6869b68352de0fd41c9eaaaa8a51a534b06d9d9..6e1eb7638f29bdad3d859266a2b9b512a4e15268 100644 (file)
@@ -114,11 +114,16 @@ ldap_simple_rebind(
     void *params)
 {
     struct ldap_creds *cp = (struct ldap_creds *) params;
+    struct berval cred;
+    if (cp->pw) {
+        cred.bv_val=cp->pw;
+        cred.bv_len=strlen(cp->pw);
+    }
     whop = whop;
     credp = credp;
     methodp = methodp;
     freeit = freeit;
-    return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE);
+    return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
 }
 #elif HAVE_LDAP_REBIND_PROC
 #if HAVE_SASL_H || HAVE_SASL_SASL_H || HAVE_SASL_DARWIN
@@ -148,7 +153,12 @@ ldap_simple_rebind(
     void *params)
 {
     struct ldap_creds *cp = (struct ldap_creds *) params;
-    return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE);
+    struct berval cred;
+    if (cp->pw) {
+        cred.bv_val=cp->pw;
+        cred.bv_len=strlen(cp->pw);
+    }
+    return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
 }
 
 #elif HAVE_LDAP_REBIND_FUNCTION
@@ -188,11 +198,16 @@ ldap_simple_rebind(
     void *params)
 {
     struct ldap_creds *cp = (struct ldap_creds *) params;
+    struct berval cred;
+    if (cp->pw) {
+        cred.bv_val=cp->pw;
+        cred.bv_len=strlen(cp->pw);
+    }
     whop = whop;
     credp = credp;
     methodp = methodp;
     freeit = freeit;
-    return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE);
+    return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
 }
 #else
 #error "No rebind functione defined"
@@ -202,7 +217,7 @@ ldap_simple_rebind(
 static LDAP_REBIND_PROC ldap_sasl_rebind;
 
 static int
-ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params)
+ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t request, ber_int_t msgid, void *params)
 {
     struct ldap_creds *cp = (struct ldap_creds *) params;
     return tool_sasl_bind(ld, cp->dn, cp->pw);
@@ -212,11 +227,16 @@ ldap_sasl_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params
 static LDAP_REBIND_PROC ldap_simple_rebind;
 
 static int
-ldap_simple_rebind(LDAP * ld, LDAP_CONST char *, ber_tag_t, ber_int_t, void *params)
+ldap_simple_rebind(LDAP *ld, LDAP_CONST char *, ber_tag_t request, ber_int_t msgid, void *params)
 {
 
     struct ldap_creds *cp = (struct ldap_creds *) params;
-    return ldap_bind_s(ld, cp->dn, cp->pw, LDAP_AUTH_SIMPLE);
+    struct berval cred;
+    if (cp->pw) {
+        cred.bv_val=cp->pw;
+        cred.bv_len=strlen(cp->pw);
+    }
+    return ldap_sasl_bind_s(ld, cp->dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
 }
 
 #endif
@@ -745,7 +765,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
     xfree(ldapuri);
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error while initialising connection to ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-        ldap_unbind(ld);
+        ldap_unbind_ext(ld,NULL,NULL);
         ld = NULL;
         return NULL;
     }
@@ -755,7 +775,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
     rc = ldap_set_defaults(ld);
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-        ldap_unbind(ld);
+        ldap_unbind_ext(ld, NULL, NULL);
         ld = NULL;
         return NULL;
     }
@@ -767,7 +787,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
         rc = ldap_set_ssl_defaults(margs);
         if (rc != LDAP_SUCCESS) {
             error((char *) "%s| %s: ERROR: Error while setting SSL default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-            ldap_unbind(ld);
+            ldap_unbind_ext(ld, NULL, NULL);
             ld = NULL;
             return NULL;
         }
@@ -778,7 +798,7 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
         rc = ldap_start_tls_s(ld, NULL, NULL);
         if (rc != LDAP_SUCCESS) {
             error((char *) "%s| %s: ERROR: Error while setting start_tls for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-            ldap_unbind(ld);
+            ldap_unbind_ext(ld, NULL, NULL);
             ld = NULL;
             url = (LDAPURLDesc *) xmalloc(sizeof(*url));
             memset(url, 0, sizeof(*url));
@@ -810,14 +830,14 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
             xfree(ldapuri);
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while initialising connection to ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-                ldap_unbind(ld);
+                ldap_unbind_ext(ld, NULL, NULL);
                 ld = NULL;
                 return NULL;
             }
             rc = ldap_set_defaults(ld);
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-                ldap_unbind(ld);
+                ldap_unbind_ext(ld, NULL, NULL);
                 ld = NULL;
                 return NULL;
             }
@@ -826,14 +846,14 @@ tool_ldap_open(struct main_args * margs, char *host, int port, char *ssl)
         ld = ldapssl_init(host, port, 1);
         if (!ld) {
             error((char *) "%s| %s: ERROR: Error while setting SSL for ldap server: %s\n", LogTime(), PROGRAM, ldapssl_err2string(rc));
-            ldap_unbind(ld);
+            ldap_unbind_ext(ld, NULL, NULL);
             ld = NULL;
             return NULL;
         }
         rc = ldap_set_defaults(ld);
         if (rc != LDAP_SUCCESS) {
             error((char *) "%s| %s: ERROR: Error while setting default options for ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-            ldap_unbind(ld);
+            ldap_unbind_ext(ld, NULL, NULL);
             ld = NULL;
             return NULL;
         }
@@ -940,7 +960,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
             rc = tool_sasl_bind(ld, bindp, margs->ssl);
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while binding to ldap server with SASL/GSSAPI: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-                ldap_unbind(ld);
+                ldap_unbind_ext(ld, NULL, NULL);
                 ld = NULL;
                 continue;
             }
@@ -953,7 +973,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
                 break;
             }
 #else
-            ldap_unbind(ld);
+            ldap_unbind_ext(ld, NULL, NULL);
             ld = NULL;
             error((char *) "%s| %s: ERROR: SASL not supported on system\n", LogTime(), PROGRAM);
             continue;
@@ -993,7 +1013,11 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
         nhosts = get_hostname_list(&hlist, 0, host);
         xfree(host);
         for (size_t i = 0; i < nhosts; ++i) {
-
+            struct berval cred;
+            if (margs->lpass) {
+                cred.bv_val=margs->lpass;
+                cred.bv_len=strlen(margs->lpass);
+            }
             ld = tool_ldap_open(margs, hlist[i].host, port, ssl);
             if (!ld)
                 continue;
@@ -1002,10 +1026,10 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
              */
 
             debug((char *) "%s| %s: DEBUG: Bind to ldap server with Username/Password\n", LogTime(), PROGRAM);
-            rc = ldap_simple_bind_s(ld, margs->luser, margs->lpass);
+            rc = ldap_sasl_bind_s(ld, margs->luser, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
             if (rc != LDAP_SUCCESS) {
                 error((char *) "%s| %s: ERROR: Error while binding to ldap server with Username/Password: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-                ldap_unbind(ld);
+                ldap_unbind_ext(ld, NULL, NULL);
                 ld = NULL;
                 continue;
             }
@@ -1040,7 +1064,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
     rc = check_AD(margs, ld);
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error determining ldap server type: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-        ldap_unbind(ld);
+        ldap_unbind_ext(ld, NULL, NULL);
         ld = NULL;
         retval = 0;
         goto cleanup;
@@ -1066,7 +1090,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
 
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error searching ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
-        ldap_unbind(ld);
+        ldap_unbind_ext(ld, NULL, NULL);
         ld = NULL;
         retval = 0;
         goto cleanup;
@@ -1151,7 +1175,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
         ldap_msgfree(res);
     } else if (ldap_count_entries(ld, res) == 0 && margs->AD) {
         ldap_msgfree(res);
-        ldap_unbind(ld);
+        ldap_unbind_ext(ld, NULL, NULL);
         ld = NULL;
         retval = 0;
         goto cleanup;
@@ -1363,7 +1387,7 @@ get_memberof(struct main_args *margs, char *user, char *domain, char *group)
             safe_free(attr_value);
         }
     }
-    rc = ldap_unbind(ld);
+    rc = ldap_unbind_ext(ld, NULL, NULL);
     ld = NULL;
     if (rc != LDAP_SUCCESS) {
         error((char *) "%s| %s: ERROR: Error unbind ldap server: %s\n", LogTime(), PROGRAM, ldap_err2string(rc));
index b8d15891c342db1998f6f0c44670e7d868d52bc0..8c658e734cc8f5f1bb427a8670b218fb513059a6 100644 (file)
 # FIXME: de-duplicate $enable_external_acl_helpers list containing double entries.
 
 #define list of modules to build
+auto_ext_acl_modules=no
 if test "x${enable_external_acl_helpers:=yes}" = "xyes" ;then
   SQUID_LOOK_FOR_MODULES([$srcdir/helpers/external_acl],[enable_external_acl_helpers])
+  auto_ext_acl_modules=yes
 fi
 if test "x$enable_external_acl_helpers" = "xnone" ; then
   enable_external_acl_helpers=""
@@ -68,7 +70,11 @@ if test "x$enable_external_acl_helpers" != "xno" ; then
 
       if test -d "$srcdir/helpers/external_acl/$helper"; then
         if test "$BUILD_HELPER" != "$helper"; then
-          AC_MSG_NOTICE([external acl helper $helper ... found but cannot be built])
+          if test "x$auto_ext_acl_modules" = "xyes"; then
+            AC_MSG_NOTICE([external acl helper $helper ... found but cannot be built])
+          else
+            AC_MSG_ERROR([external acl helper $helper ... found but cannot be built])
+          fi
         else
           EXTERNAL_ACL_HELPERS="$EXTERNAL_ACL_HELPERS $BUILD_HELPER"
         fi
index 9a2c4c8cf22ae5cd0b10579880d38f6323efed33..83214e6a400fea2b3c08c96c212dbc3ffb808dd6 100644 (file)
 # FIXME: de-duplicate $enable_log_daemon_helpers list containing double entries.
 
 #define list of modules to build
+auto_logdaemon_modules=no
 if test "x${enable_log_daemon_helpers:=yes}" = "xyes" ;then
   enable_log_daemon_helpers=""
   SQUID_LOOK_FOR_MODULES([$srcdir/helpers/log_daemon],[enable_log_daemon_helpers])
+  auto_logdaemon_modules=yes
 fi
 if test "x$enable_log_daemon_helpers" = "xnone" ; then
   enable_log_daemon_helpers=""
@@ -40,7 +42,11 @@ if test "x$enable_log_daemon_helpers" != "xno"; then
 
     if test -d "$srcdir/helpers/log_daemon/$helper"; then
       if test "$BUILD_HELPER" != "$helper"; then
-        AC_MSG_NOTICE([Log daemon helper $helper ... found but cannot be built])
+        if test "x$auto_logdaemon_modules" = "xyes"; then
+          AC_MSG_NOTICE([Log daemon helper $helper ... found but cannot be built])
+        else
+          AC_MSG_ERROR([Log daemon helper $helper ... found but cannot be built])
+        fi
       else
        LOG_DAEMON_HELPERS="$LOG_DAEMON_HELPERS $BUILD_HELPER"
       fi
index 48a9ac893a4cc00f07aa34d8ab70b31160bdac16..d853859acdf9189443f00dd1806d5ede469bdc24 100644 (file)
 #include "base64.h"
 #include "util.h"
 
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
+
 #if HAVE_KRB5_H
 #if HAVE_BROKEN_SOLARIS_KRB5_H
 #warn "Warning! You have a broken Solaris <krb5.h> system header"
@@ -144,7 +149,6 @@ typedef struct {
     uint32_t pointer;
 } RPC_UNICODE_STRING;
 
-int check_k5_err(krb5_context context, const char *msg, krb5_error_code code);
 void align(int n);
 void getustr(RPC_UNICODE_STRING *string);
 char **getgids(char **Rids, uint32_t GroupIds, uint32_t GroupCount);
@@ -161,4 +165,5 @@ char *get_ad_groups(char *ad_groups, krb5_context context, krb5_pac pac);
 #else
 #define HAVE_PAC_SUPPORT 0
 #endif
+int check_k5_err(krb5_context context, const char *msg, krb5_error_code code);
 
index 6799ae3db404d112e6a3de25557442ca974c6199..a251c82a20c8a948ebf8a274464d6102d00c3e31 100644 (file)
@@ -65,7 +65,6 @@ krb5_error_code krb5_read_keytab(krb5_context context,
                                  krb5_kt_list *kt_list);
 #endif /* HAVE_KRB5_MEMORY_KEYTAB */
 
-#if HAVE_PAC_SUPPORT || HAVE_KRB5_MEMORY_KEYTAB
 int
 check_k5_err(krb5_context context, const char *function, krb5_error_code code)
 {
@@ -85,7 +84,6 @@ check_k5_err(krb5_context context, const char *function, krb5_error_code code)
     }
     return code;
 }
-#endif
 
 char *
 gethost_name(void)
@@ -540,7 +538,7 @@ main(int argc, char *const argv[])
             if (!check_k5_err(context, "krb5_init_context", ret)) {
                 krb5_kt_default_name(context, default_keytab, MAXPATHLEN);
             }
-            keytab_name = default_keytab;
+            keytab_name = xstrdup(default_keytab);
             krb5_free_context(context);
         } else
             keytab_name = xstrdup(keytab_name_env);
index 467a234432194d14764110500d0e459f93e278c4..1ac8b6da092a40fa70c8baca989b13e469844897 100644 (file)
@@ -33,6 +33,9 @@
 #include "squid.h"
 
 #if HAVE_GSSAPI
+#if USE_APPLE_KRB5
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
 
 #include <cerrno>
 #include <cstring>
index 5871f9388f46dc84f018ad83676556bc4a4bc78d..3fcc678ce8e4dab3852a3db8a54ff02088a72524 100644 (file)
@@ -19,8 +19,10 @@ if test "x$enable_auth_negotiate" != "xno" -a "x$enable_auth" = "xno" ; then
     AC_MSG_ERROR([Negotiate auth requested but auth disabled])
 fi
 #define list of modules to build
+auto_auth_negotiate_modules=no
 if test "x$enable_auth_negotiate" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/negotiate_auth],[enable_auth_negotiate])
+  auto_auth_negotiate_modules=yes
 fi
 #handle the "none" special case
 if test "x$enable_auth_negotiate" = "xnone" ; then
@@ -53,7 +55,11 @@ if test "x$enable_auth_negotiate" != "xno" ; then
 
       if test -d "$srcdir/helpers/negotiate_auth/$helper"; then
         if test "$BUILD_HELPER" != "$helper"; then
-          AC_MSG_NOTICE([Negotiate auth helper $helper ... found but cannot be built])
+          if test "x$auto_auth_negotiate_modules" = "xyes"; then
+            AC_MSG_NOTICE([Negotiate auth helper $helper ... found but cannot be built])
+          else
+            AC_MSG_ERROR([Negotiate auth helper $helper ... found but cannot be built])
+          fi
         else
           NEGOTIATE_AUTH_HELPERS="$NEGOTIATE_AUTH_HELPERS $BUILD_HELPER"
         fi
index 38b0f7729dc29405928c75814638c907906ad993..026484fc21433fdf27734e78c5a178d04f7780dc 100644 (file)
 #if HAVE_GETOPT_H
 #include <getopt.h>
 #endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
 
 /* A couple of harmless helper macros */
 #define SEND(X) {debug("sending '%s' to squid\n",X); printf(X "\n");}
index d73ec2b172227222720d992e68b1056b0b2b4f68..54cfb30f004e44c26b8c6da1b161796d218b5171 100644 (file)
@@ -19,8 +19,10 @@ if test "x$enable_auth_ntlm" != "xno" -a "x$enable_auth" = "xno" ; then
     AC_MSG_ERROR([NTLM auth requested but auth disabled])
 fi
 #define list of modules to build
+auto_auth_ntlm_modules=no
 if test "x$enable_auth_ntlm" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/ntlm_auth],[enable_auth_ntlm])
+  auto_auth_ntlm_modules=yes
 fi
 #handle the "none" special case
 if test "x$enable_auth_ntlm" = "xnone" ; then
@@ -54,7 +56,11 @@ if test "x$enable_auth_ntlm" != "xno" ; then
 
       if test -d "$srcdir/helpers/ntlm_auth/$helper"; then
         if test "$BUILD_HELPER" != "$helper"; then
-          AC_MSG_NOTICE([NTLM auth helper $helper ... found but cannot be built])
+          if test "x$auto_auth_ntlm_modules" = "xyes"; then
+            AC_MSG_NOTICE([NTLM auth helper $helper ... found but cannot be built])
+          else
+            AC_MSG_ERROR([NTLM auth helper $helper ... found but cannot be built])
+          fi
         else
           NTLM_AUTH_HELPERS="$NTLM_AUTH_HELPERS $BUILD_HELPER"
         fi
index 7aef8c2b33150c54e603c2a7d22992cd7c7ea001..7ad38a55e79ac181b4ec54c8a8a3c1691c57fef9 100644 (file)
 # FIXME: de-duplicate $enable_storeid_rewrite_helpers list containing double entries.
 
 #define list of modules to build
+auto_storeid_modules=no
 if test "x${enable_storeid_rewrite_helpers:=yes}" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/storeid_rewrite],[enable_storeid_rewrite_helpers])
+  auto_storeid_modules=yes
 fi
 
 enable_storeid_rewrite_helpers="`echo $enable_storeid_rewrite_helpers| sed -e 's/,/ /g;s/  */ /g'`"
@@ -34,7 +36,11 @@ if test "x$enable_storeid_rewrite_helpers" != "xno" ; then
 
     if test -d "$srcdir/helpers/storeid_rewrite/$helper"; then
       if test "$BUILD_HELPER" != "$helper"; then
-        AC_MSG_NOTICE([Store-ID rewrite helper $helper ... found but cannot be built])
+        if test "x$auto_storeid_modules" = "xyes"; then
+          AC_MSG_NOTICE([Store-ID rewrite helper $helper ... found but cannot be built])
+        else
+          AC_MSG_ERROR([Store-ID rewrite helper $helper ... found but cannot be built])
+        fi
       else
         STOREID_REWRITE_HELPERS="$STOREID_REWRITE_HELPERS $BUILD_HELPER"
       fi
index 31a5cf8a1277485e7a7c4a89060f54c6fcf0e40d..af097bd8f4f2385cc0922ea4c33ea1fb858664fd 100644 (file)
 # FIXME: de-duplicate $enable_url_rewrite_helpers list containing double entries.
 
 #define list of modules to build
+auto_urlrewrite_modules=no
 if test "x${enable_url_rewrite_helpers:=yes}" = "xyes" ; then
     SQUID_LOOK_FOR_MODULES([$srcdir/helpers/url_rewrite],[enable_url_rewrite_helpers])
+  auto_urlrewrite_modules=yes
 fi
 
 enable_url_rewrite_helpers="`echo $enable_url_rewrite_helpers| sed -e 's/,/ /g;s/  */ /g'`"
@@ -37,7 +39,11 @@ if test "x$enable_url_rewrite_helpers" != "xno" ; then
 
     if test -d "$srcdir/helpers/url_rewrite/$helper"; then
       if test "$BUILD_HELPER" != "$helper"; then
-        AC_MSG_NOTICE([URL rewrite helper $helper ... found but cannot be built])
+        if test "x$auto_urlrewrite_modules" = "xyes"; then
+          AC_MSG_NOTICE([URL rewrite helper $helper ... found but cannot be built])
+        else
+          AC_MSG_ERROR([URL rewrite helper $helper ... found but cannot be built])
+        fi
       else
         URL_REWRITE_HELPERS="$URL_REWRITE_HELPERS $BUILD_HELPER"
       fi
index 0b129a521417fd9e43157304cf39ebdb7a3c43d3..9be5e3e052a34ec7b8f0328d85c799957f838a3f 100644 (file)
@@ -74,6 +74,7 @@
 #if USE_OPENSSL
 #include "acl/Certificate.h"
 #include "acl/CertificateData.h"
+#include "acl/ServerName.h"
 #include "acl/SslError.h"
 #include "acl/SslErrorData.h"
 #endif
@@ -177,6 +178,12 @@ ACLStrategised<X509 *> ACLServerCertificate::X509FingerprintRegistryEntry_(new A
 
 ACL::Prototype ACLAtStep::RegistryProtoype(&ACLAtStep::RegistryEntry_, "at_step");
 ACLStrategised<Ssl::BumpStep> ACLAtStep::RegistryEntry_(new ACLAtStepData, ACLAtStepStrategy::Instance(), "at_step");
+
+ACL::Prototype ACLServerName::LiteralRegistryProtoype(&ACLServerName::LiteralRegistryEntry_, "ssl::server_name");
+ACLStrategised<char const *> ACLServerName::LiteralRegistryEntry_(new ACLServerNameData, ACLServerNameStrategy::Instance(), "ssl::server_name");
+ACL::Prototype ACLServerName::RegexRegistryProtoype(&ACLServerName::RegexRegistryEntry_, "ssl::server_name_regex");
+ACLFlag  ServerNameRegexFlags[] = {ACL_F_REGEX_CASE, ACL_F_END};
+ACLStrategised<char const *> ACLServerName::RegexRegistryEntry_(new ACLRegexData, ACLServerNameStrategy::Instance(), "ssl::server_name_regex", ServerNameRegexFlags);
 #endif
 
 #if USE_SQUID_EUI
index 18a967bc3851ce62bfe01a2f659e5d005dc5cf60..8a23111de1208f978ec2309155556c5e371bbe09 100644 (file)
@@ -58,6 +58,8 @@
 #include "ssl/PeerConnector.h"
 #include "ssl/ServerBump.h"
 #include "ssl/support.h"
+#else
+#include "security/EncryptorAnswer.h"
 #endif
 
 #include <cerrno>
@@ -78,7 +80,7 @@ CBDATA_CLASS_INIT(FwdState);
 class FwdStatePeerAnswerDialer: public CallDialer, public Ssl::PeerConnector::CbDialer
 {
 public:
-    typedef void (FwdState::*Method)(Ssl::PeerConnectorAnswer &);
+    typedef void (FwdState::*Method)(Security::EncryptorAnswer &);
 
     FwdStatePeerAnswerDialer(Method method, FwdState *fwd):
         method_(method), fwd_(fwd), answer_() {}
@@ -91,12 +93,12 @@ public:
     }
 
     /* Ssl::PeerConnector::CbDialer API */
-    virtual Ssl::PeerConnectorAnswer &answer() { return answer_; }
+    virtual Security::EncryptorAnswer &answer() { return answer_; }
 
 private:
     Method method_;
     CbcPointer<FwdState> fwd_;
-    Ssl::PeerConnectorAnswer answer_;
+    Security::EncryptorAnswer answer_;
 };
 #endif
 
@@ -701,16 +703,13 @@ FwdState::connectDone(const Comm::ConnectionPointer &conn, Comm::Flag status, in
     }
 #endif
 
-    // should reach ConnStateData before the dispatched Client job starts
-    CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
-                 ConnStateData::notePeerConnection, serverConnection());
-
-    dispatch();
+    // if not encrypting just run the post-connect actions
+    Security::EncryptorAnswer nil;
+    connectedToPeer(nil);
 }
 
-#if USE_OPENSSL
 void
-FwdState::connectedToPeer(Ssl::PeerConnectorAnswer &answer)
+FwdState::connectedToPeer(Security::EncryptorAnswer &answer)
 {
     if (ErrorState *error = answer.error.get()) {
         fail(error);
@@ -719,9 +718,12 @@ FwdState::connectedToPeer(Ssl::PeerConnectorAnswer &answer)
         return;
     }
 
+    // should reach ConnStateData before the dispatched Client job starts
+    CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
+                 ConnStateData::notePeerConnection, serverConnection());
+
     dispatch();
 }
-#endif
 
 void
 FwdState::connectTimeout(int fd)
index 988a3a0eb50e8c60aed3df4279c720e27f663063..ff47632f28957882a84b09d4b94037f4b0671116 100644 (file)
@@ -16,6 +16,7 @@
 #include "fde.h"
 #include "http/StatusCode.h"
 #include "ip/Address.h"
+#include "security/forward.h"
 #if USE_OPENSSL
 #include "ssl/support.h"
 #endif
@@ -34,7 +35,6 @@ namespace Ssl
 {
 class ErrorDetail;
 class CertValidationResponse;
-class PeerConnectorAnswer;
 };
 #endif
 
@@ -114,9 +114,7 @@ private:
     void completed();
     void retryOrBail();
     ErrorState *makeConnectingError(const err_type type) const;
-#if USE_OPENSSL
-    void connectedToPeer(Ssl::PeerConnectorAnswer &answer);
-#endif
+    void connectedToPeer(Security::EncryptorAnswer &answer);
     static void RegisterWithCacheManager(void);
 
     /// stops monitoring server connection for closure and updates pconn stats
index 231c5c6000beb390df4acfc244cdf06d978a56a6..3055e838e05605c49ae8479220deca153e902409 100644 (file)
@@ -125,16 +125,13 @@ httpMsgIsolateStart(const char **parse_start, const char **blk_start, const char
 // zero return means need more data
 // positive return is the size of parsed headers
 bool
-HttpMsg::parse(MemBuf *buf, bool eof, Http::StatusCode *error)
+HttpMsg::parse(const char *buf, const size_t sz, bool eof, Http::StatusCode *error)
 {
     assert(error);
     *error = Http::scNone;
 
-    // httpMsgParseStep() and debugging require 0-termination, unfortunately
-    buf->terminate(); // does not affect content size
-
     // find the end of headers
-    const size_t hdr_len = headersEnd(buf->content(), buf->contentSize());
+    const size_t hdr_len = headersEnd(buf, sz);
 
     // sanity check the start line to see if this is in fact an HTTP message
     if (!sanityCheckStartLine(buf, hdr_len, error)) {
@@ -146,15 +143,14 @@ HttpMsg::parse(MemBuf *buf, bool eof, Http::StatusCode *error)
         return false;
     }
 
-    // TODO: move to httpReplyParseStep()
-    if (hdr_len > Config.maxReplyHeaderSize || (hdr_len <= 0 && (size_t)buf->contentSize() > Config.maxReplyHeaderSize)) {
+    if (hdr_len > Config.maxReplyHeaderSize || (hdr_len <= 0 && sz > Config.maxReplyHeaderSize)) {
         debugs(58, DBG_IMPORTANT, "HttpMsg::parse: Too large reply header (" << hdr_len << " > " << Config.maxReplyHeaderSize);
         *error = Http::scHeaderTooLarge;
         return false;
     }
 
     if (hdr_len <= 0) {
-        debugs(58, 3, "HttpMsg::parse: failed to find end of headers (eof: " << eof << ") in '" << buf->content() << "'");
+        debugs(58, 3, "HttpMsg::parse: failed to find end of headers (eof: " << eof << ") in '" << buf << "'");
 
         if (eof) // iff we have seen the end, this is an error
             *error = Http::scInvalidHeader;
@@ -162,22 +158,22 @@ HttpMsg::parse(MemBuf *buf, bool eof, Http::StatusCode *error)
         return false;
     }
 
-    const int res = httpMsgParseStep(buf->content(), buf->contentSize(), eof);
+    const int res = httpMsgParseStep(buf, sz, eof);
 
     if (res < 0) { // error
-        debugs(58, 3, "HttpMsg::parse: cannot parse isolated headers in '" << buf->content() << "'");
+        debugs(58, 3, "HttpMsg::parse: cannot parse isolated headers in '" << buf << "'");
         *error = Http::scInvalidHeader;
         return false;
     }
 
     if (res == 0) {
-        debugs(58, 2, "HttpMsg::parse: strange, need more data near '" << buf->content() << "'");
+        debugs(58, 2, "HttpMsg::parse: strange, need more data near '" << buf << "'");
         *error = Http::scInvalidHeader;
         return false; // but this should not happen due to headersEnd() above
     }
 
     assert(res > 0);
-    debugs(58, 9, "HttpMsg::parse success (" << hdr_len << " bytes) near '" << buf->content() << "'");
+    debugs(58, 9, "HttpMsg::parse success (" << hdr_len << " bytes) near '" << buf << "'");
 
     if (hdr_sz != (int)hdr_len) {
         debugs(58, DBG_IMPORTANT, "internal HttpMsg::parse vs. headersEnd error: " <<
index 275b260591671e9b3188d2143ad0b144451720f0..065820dddb6de19b00759d9278be9cf8de64d54c 100644 (file)
@@ -67,7 +67,7 @@ public:
     // returns true and sets hdr_sz on success
     // returns false and sets *error to zero when needs more data
     // returns false and sets *error to a positive Http::StatusCode on error
-    bool parse(MemBuf *buf, bool eol, Http::StatusCode *error);
+    bool parse(const char *buf, const size_t sz, bool eol, Http::StatusCode *error);
 
     bool parseCharBuf(const char *buf, ssize_t end);
 
@@ -89,7 +89,7 @@ protected:
      * \retval true   Status line has no serious problems.
      * \retval false  Status line has a serious problem. Correct response is indicated by error.
      */
-    virtual bool sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error) = 0;
+    virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error) = 0;
 
     virtual void packFirstLineInto(Packable * p, bool full_uri) const = 0;
 
index 98c20aebf19d81b6e04fb8987465ae3a6281bf76..64b534b30e1f25845ac62440ae1617902e1b4d28 100644 (file)
@@ -407,15 +407,15 @@ HttpReply::bodySize(const HttpRequestMethod& method) const
  * NP: not all error cases are detected yet. Some are left for detection later in parse.
  */
 bool
-HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error)
+HttpReply::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error)
 {
     // hack warning: using psize instead of size here due to type mismatches with MemBuf.
 
     // content is long enough to possibly hold a reply
     // 4 being magic size of a 3-digit number plus space delimiter
-    if ( buf->contentSize() < (protoPrefix.psize() + 4) ) {
+    if (hdr_len < (size_t)(protoPrefix.psize() + 4)) {
         if (hdr_len > 0) {
-            debugs(58, 3, HERE << "Too small reply header (" << hdr_len << " bytes)");
+            debugs(58, 3, "Too small reply header (" << hdr_len << " bytes)");
             *error = Http::scInvalidHeader;
         }
         return false;
@@ -424,13 +424,13 @@ HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusC
     int pos;
     // catch missing or mismatched protocol identifier
     // allow special-case for ICY protocol (non-HTTP identifier) in response to faked HTTP request.
-    if (strncmp(buf->content(), "ICY", 3) == 0) {
+    if (strncmp(buf, "ICY", 3) == 0) {
         protoPrefix = "ICY";
         pos = protoPrefix.psize();
     } else {
 
-        if (protoPrefix.cmp(buf->content(), protoPrefix.size()) != 0) {
-            debugs(58, 3, "HttpReply::sanityCheckStartLine: missing protocol prefix (" << protoPrefix << ") in '" << buf->content() << "'");
+        if (protoPrefix.cmp(buf, protoPrefix.size()) != 0) {
+            debugs(58, 3, "missing protocol prefix (" << protoPrefix << ") in '" << buf << "'");
             *error = Http::scInvalidHeader;
             return false;
         }
@@ -439,21 +439,21 @@ HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusC
         pos = protoPrefix.psize();
 
         // skip arbitrary number of digits and a dot in the verion portion
-        while ( pos <= buf->contentSize() && (*(buf->content()+pos) == '.' || xisdigit(*(buf->content()+pos)) ) ) ++pos;
+        while ((size_t)pos <= hdr_len && (*(buf+pos) == '.' || xisdigit(*(buf+pos)) ) ) ++pos;
 
         // catch missing version info
         if (pos == protoPrefix.psize()) {
-            debugs(58, 3, "HttpReply::sanityCheckStartLine: missing protocol version numbers (ie. " << protoPrefix << "/1.0) in '" << buf->content() << "'");
+            debugs(58, 3, "missing protocol version numbers (ie. " << protoPrefix << "/1.0) in '" << buf << "'");
             *error = Http::scInvalidHeader;
             return false;
         }
     }
 
     // skip arbitrary number of spaces...
-    while (pos <= buf->contentSize() && (char)*(buf->content()+pos) == ' ') ++pos;
+    while ((size_t)pos <= hdr_len && (char)*(buf+pos) == ' ') ++pos;
 
-    if (pos < buf->contentSize() && !xisdigit(*(buf->content()+pos))) {
-        debugs(58, 3, "HttpReply::sanityCheckStartLine: missing or invalid status number in '" << buf->content() << "'");
+    if ((size_t)pos < hdr_len && !xisdigit(*(buf+pos))) {
+        debugs(58, 3, "missing or invalid status number in '" << buf << "'");
         *error = Http::scInvalidHeader;
         return false;
     }
index cfa6cc94b18a0b57c652cf929d04bc7ede98eecb..ca043eec5f202eece664bfb57ec900eca535381e 100644 (file)
@@ -39,7 +39,7 @@ public:
      \retval false and sets *error to zero when needs more data
      \retval false and sets *error to a positive Http::StatusCode on error
      */
-    virtual bool sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error);
+    virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error);
 
     /** \par public, readable; never update these or their .hdr equivalents directly */
     time_t date;
index b0497b18e3c59ec2404bdb8011b4667ff0d790f3..edd113fbf3007c02a56428d1a5cb7168af3745b8 100644 (file)
@@ -269,11 +269,11 @@ HttpRequest::inheritProperties(const HttpMsg *aMsg)
  * NP: Other errors are left for detection later in the parse.
  */
 bool
-HttpRequest::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error)
+HttpRequest::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error)
 {
     // content is long enough to possibly hold a reply
     // 2 being magic size of a 1-byte request method plus space delimiter
-    if ( buf->contentSize() < 2 ) {
+    if (hdr_len < 2) {
         // this is ony a real error if the headers apparently complete.
         if (hdr_len > 0) {
             debugs(58, 3, HERE << "Too large request header (" << hdr_len << " bytes)");
@@ -284,7 +284,7 @@ HttpRequest::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::Statu
 
     /* See if the request buffer starts with a non-whitespace HTTP request 'method'. */
     HttpRequestMethod m;
-    m.HttpRequestMethodXXX(buf->content());
+    m.HttpRequestMethodXXX(buf);
     if (m == Http::METHOD_NONE) {
         debugs(73, 3, "HttpRequest::sanityCheckStartLine: did not find HTTP request method");
         *error = Http::scInvalidHeader;
index ada6ed0560283e0041a5c51bb1d46eeab45ff676..526a16ef97e72fb3a72e4163df282b50aa2b7f9a 100644 (file)
@@ -257,7 +257,7 @@ private:
 protected:
     virtual void packFirstLineInto(Packable * p, bool full_uri) const;
 
-    virtual bool sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error);
+    virtual bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error);
 
     virtual void hdrCacheInit();
 
index 80f4cfb9c31d299f33f0f6d676e9e88fdd09d985..52d9bb236e07c710ef95f66c165ca63a5f4bcf9e 100644 (file)
 #include "SquidTime.h"
 #if USE_OPENSSL
 #include "ssl/PeerConnector.h"
+#else
+#include "security/EncryptorAnswer.h"
 #endif
 
 CBDATA_CLASS_INIT(PeerPoolMgr);
 
 #if USE_OPENSSL
 /// Gives Ssl::PeerConnector access to Answer in the PeerPoolMgr callback dialer.
-class MyAnswerDialer: public UnaryMemFunT<PeerPoolMgr, Ssl::PeerConnectorAnswer, Ssl::PeerConnectorAnswer&>,
+class MyAnswerDialer: public UnaryMemFunT<PeerPoolMgr, Security::EncryptorAnswer, Security::EncryptorAnswer&>,
     public Ssl::PeerConnector::CbDialer
 {
 public:
     MyAnswerDialer(const JobPointer &aJob, Method aMethod):
-        UnaryMemFunT<PeerPoolMgr, Ssl::PeerConnectorAnswer, Ssl::PeerConnectorAnswer&>(aJob, aMethod, Ssl::PeerConnectorAnswer()) {}
+        UnaryMemFunT<PeerPoolMgr, Security::EncryptorAnswer, Security::EncryptorAnswer&>(aJob, aMethod, Security::EncryptorAnswer()) {}
 
     /* Ssl::PeerConnector::CbDialer API */
-    virtual Ssl::PeerConnectorAnswer &answer() { return arg1; }
+    virtual Security::EncryptorAnswer &answer() { return arg1; }
 };
 #endif
 
@@ -146,9 +148,8 @@ PeerPoolMgr::pushNewConnection(const Comm::ConnectionPointer &conn)
     // push() will trigger a checkpoint()
 }
 
-#if USE_OPENSSL
 void
-PeerPoolMgr::handleSecuredPeer(Ssl::PeerConnectorAnswer &answer)
+PeerPoolMgr::handleSecuredPeer(Security::EncryptorAnswer &answer)
 {
     Must(securer != NULL);
     securer = NULL;
@@ -190,7 +191,6 @@ PeerPoolMgr::handleSecureClosure(const CommCloseCbParams &params)
     // allow the closing connection to fully close before we check again
     Checkpoint(this, "conn closure while securing");
 }
-#endif
 
 void
 PeerPoolMgr::openNewConnection()
index d199d8b1137ff4521b769dc1461b8fa2dfd9e8e9..5a6f0eb33d559d20bcda49cc45fcfbb53cc7d9fb 100644 (file)
 
 #include "base/AsyncJob.h"
 #include "comm/forward.h"
+#include "security/forward.h"
 
 class HttpRequest;
 class CachePeer;
 class CommConnectCbParams;
 
-#if USE_OPENSSL
-namespace Ssl
-{
-class PeerConnectorAnswer;
-}
-#endif
-
 /// Maintains an fixed-size "standby" PconnPool for a single CachePeer.
 class PeerPoolMgr: public AsyncJob
 {
@@ -56,12 +50,13 @@ protected:
 
     /// Comm::ConnOpener calls this when done opening a connection for us
     void handleOpenedConnection(const CommConnectCbParams &params);
-#if USE_OPENSSL
+
     /// Ssl::PeerConnector callback
-    void handleSecuredPeer(Ssl::PeerConnectorAnswer &answer);
+    void handleSecuredPeer(Security::EncryptorAnswer &answer);
+
     /// called when the connection we are trying to secure is closed by a 3rd party
     void handleSecureClosure(const CommCloseCbParams &params);
-#endif
+
     /// the final step in connection opening (and, optionally, securing) sequence
     void pushNewConnection(const Comm::ConnectionPointer &conn);
 
index ead90673c253dd0dedbb7b267d78a05645bde65d..1c40c9c95e7fff1d846c40545cc9ef8854baadc4 100644 (file)
@@ -182,7 +182,7 @@ SBuf::rawSpace(size_type minSpace)
     // it's available, we're effectively claiming ownership
     // of it. If it's not, we need to go away (realloc)
     if (store_->canAppend(off_+len_, minSpace)) {
-        debugs(24, 7, "not growing");
+        debugs(24, 7, id << " not growing");
         return bufEnd();
     }
     // TODO: we may try to memmove before realloc'ing in order to avoid
@@ -508,7 +508,7 @@ SBuf::consume(size_type n)
         n = length();
     else
         n = min(n, length());
-    debugs(24, 8, "consume " << n);
+    debugs(24, 8, id << " consume " << n);
     SBuf rv(substr(0, n));
     chop(n);
     return rv;
@@ -539,6 +539,8 @@ SBuf::rawContent() const
 void
 SBuf::forceSize(size_type newSize)
 {
+    debugs(24, 8, id << " force " << (newSize > length() ? "grow" : "shrink") << " to length=" << newSize);
+
     Must(store_->LockCount() == 1);
     if (newSize > min(maxSize,store_->capacity-off_))
         throw SBufTooBigException(__FILE__,__LINE__);
@@ -902,7 +904,7 @@ SBuf::toString() const
 void
 SBuf::reAlloc(size_type newsize)
 {
-    debugs(24, 8, "new size: " << newsize);
+    debugs(24, 8, id << " new size: " << newsize);
     if (newsize > maxSize)
         throw SBufTooBigException(__FILE__, __LINE__);
     MemBlob::Pointer newbuf = new MemBlob(newsize);
@@ -911,7 +913,7 @@ SBuf::reAlloc(size_type newsize)
     store_ = newbuf;
     off_ = 0;
     ++stats.cowSlow;
-    debugs(24, 7, "new store capacity: " << store_->capacity);
+    debugs(24, 7, id << " new store capacity: " << store_->capacity);
 }
 
 SBuf&
@@ -932,12 +934,12 @@ SBuf::lowAppend(const char * memArea, size_type areaSize)
 void
 SBuf::cow(SBuf::size_type newsize)
 {
-    debugs(24, 8, "new size:" << newsize);
+    debugs(24, 8, id << " new size:" << newsize);
     if (newsize == npos || newsize < length())
         newsize = length();
 
     if (store_->LockCount() == 1 && newsize == length()) {
-        debugs(24, 8, "no cow needed");
+        debugs(24, 8, id << " no cow needed");
         ++stats.cowFast;
         return;
     }
index 752e9a390d54a6bc67718d48150c1440a9fd39ca..6f39f4bd17a7af1b706d69dbd7e101b161f829a2 100644 (file)
@@ -138,12 +138,14 @@ public:
     /// create an empty (zero-size) SBuf
     SBuf();
     SBuf(const SBuf &S);
+#if __cplusplus >= 201103L
     SBuf(SBuf&& S) : store_(std::move(S.store_)), off_(S.off_), len_(S.len_) {
         ++stats.moves;
-        S.store_=NULL;
+        S.store_=NULL; //RefCount supports NULL, and S is about to be destructed
         S.off_=0;
-        S.len_=0; //RefCount supports NULL
+        S.len_=0;
     }
+#endif
 
     /** Constructor: import c-style string
      *
@@ -180,6 +182,7 @@ public:
      * Current SBuf will share backing store with the assigned one.
      */
     SBuf& operator =(const SBuf & S) {return assign(S);}
+#if __cplusplus >= 201103L
     SBuf& operator =(SBuf &&S) {
         ++stats.moves;
         if (this != &S) {
@@ -192,6 +195,7 @@ public:
         }
         return *this;
     }
+#endif
 
     /** Import a c-string into a SBuf, copying the data.
      *
index e4547f1f078772ed62ff6a555d7259d30821c378..154896cd2fa399441aeca1507df25cbb5b47b364 100644 (file)
@@ -82,7 +82,9 @@ SBufStatsAction::unpack(const Ipc::TypedMsgHdr& msg)
     msg.getPod(mbdata);
 }
 
-static const bool Registered = (Mgr::RegisterAction("sbuf",
-                                "String-Buffer statistics", &SBufStatsAction::Create, 0 , 1),
-                                true);
+void
+SBufStatsAction::RegisterWithCacheManager()
+{
+    Mgr::RegisterAction("sbuf", "String-Buffer statistics", &SBufStatsAction::Create, 0 , 1);
+}
 
index 20fbb376b69353c0b80544c8ac485e5068294c13..5f9653d1c1799da2be4dc365e6925e38bd3e778b 100644 (file)
@@ -21,6 +21,7 @@ class SBufStatsAction: public Mgr::Action
 public:
     /// Mgr::ClassActionCreationHandler for Mgr::RegisterAction()
     static Pointer Create(const Mgr::CommandPointer &cmd);
+    static void RegisterWithCacheManager(void);
 
 protected:
     explicit SBufStatsAction(const Mgr::CommandPointer &cmd);
index fa3fa78aefba434906f553fb239bb9d3c7d3a764..ddc65952188b4dbc51b3673f30ed057e7dea4bce 100644 (file)
 
 #include <cstring>
 
-#if HAVE_STDINT_H
-#include <stdint.h>
-#else /* HAVE_STDINT_H */
-#ifndef INT_MAX
-#define INT_MAX 1<<31 //hack but a safe bet
-#endif /* INT_MAX */
-#endif /* HAVE_STDINT_H */
-
 String::String() : size_(0), len_(0), buf_(NULL)
 {
 #if DEBUGSTRINGS
index 11d0dac61ede14df7a1bb8b0ec07e2260401c915..be66fe0dc1fcfd5af878b964989436c550700810 100644 (file)
--- a/src/URL.h
+++ b/src/URL.h
@@ -77,7 +77,38 @@ bool urlIsRelative(const char *);
 char *urlMakeAbsolute(const HttpRequest *, const char *);
 char *urlRInternal(const char *host, unsigned short port, const char *dir, const char *name);
 char *urlInternal(const char *dir, const char *name);
-int matchDomainName(const char *host, const char *domain);
+
+/**
+ * matchDomainName() compares a hostname (usually extracted from traffic)
+ * with a domainname (usually from an ACL) according to the following rules:
+ *
+ *    HOST      |   DOMAIN    |   MATCH?
+ * -------------|-------------|------
+ *    foo.com   |   foo.com   |     YES
+ *   .foo.com   |   foo.com   |     YES
+ *  x.foo.com   |   foo.com   |     NO
+ *    foo.com   |  .foo.com   |     YES
+ *   .foo.com   |  .foo.com   |     YES
+ *  x.foo.com   |  .foo.com   |     YES
+ *
+ *  We strip leading dots on hosts (but not domains!) so that
+ *  ".foo.com" is always the same as "foo.com".
+ *
+ * if honorWildcards is true then the matchDomainName() also accepts
+ * optional wildcards on hostname:
+ *
+ *    HOST      |    DOMAIN    |  MATCH?
+ * -------------|--------------|-------
+ *    *.foo.com |   x.foo.com  |   YES
+ *    *.foo.com |  .x.foo.com  |   YES
+ *    *.foo.com |    .foo.com  |   YES
+ *    *.foo.com |     foo.com  |   NO
+ *
+ * \retval 0 means the host matches the domain
+ * \retval 1 means the host is greater than the domain
+ * \retval -1 means the host is less than the domain
+ */
+int matchDomainName(const char *host, const char *domain, bool honorWildcards = false);
 int urlCheckRequest(const HttpRequest *);
 int urlDefaultPort(AnyP::ProtocolType p);
 char *urlHostname(const char *url);
index 3f5918e57b99cb89998bf5db70918eff1c17f3b3..a3af868d1d6d4fee58e0f8caa927c8e9a932c569 100644 (file)
@@ -19,7 +19,7 @@ class ACLDomainData : public ACLData<char const *>
 
 public:
     virtual ~ACLDomainData();
-    bool match(char const *);
+    virtual bool match(char const *);
     virtual SBufList dump() const;
     void parse();
     bool empty() const;
index 61117c66be555fbe2e3a41f345846c715e8be67f..0e1428a2cdb3a00e1196848c391b8175b7fda919 100644 (file)
@@ -155,6 +155,8 @@ SSL_ACLS = \
         Certificate.h  \
        ServerCertificate.cc \
        ServerCertificate.h \
+       ServerName.cc \
+       ServerName.h \
         SslError.cc \
         SslError.h \
         SslErrorData.cc \
diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc
new file mode 100644 (file)
index 0000000..27884e9
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 28    Access Control */
+
+#include "squid.h"
+#include "acl/Checklist.h"
+#include "acl/DomainData.h"
+#include "acl/RegexData.h"
+#include "acl/ServerName.h"
+#include "client_side.h"
+#include "fde.h"
+#include "HttpRequest.h"
+#include "ipcache.h"
+#include "SquidString.h"
+#include "ssl/bio.h"
+#include "ssl/ServerBump.h"
+#include "ssl/support.h"
+#include "URL.h"
+
+// Compare function for tree search algorithms
+static int
+aclHostDomainCompare( char *const &a, char * const &b)
+{
+    const char *h = static_cast<const char *>(a);
+    const char *d = static_cast<const char *>(b);
+    debugs(28, 7, "Match:" << h << " <>  " << d);
+    return matchDomainName(h, d, true);
+}
+
+bool
+ACLServerNameData::match(const char *host)
+{
+    if (host == NULL)
+        return 0;
+
+    debugs(28, 3, "checking '" << host << "'");
+
+    char *h = const_cast<char *>(host);
+    char const * const * result = domains->find(h, aclHostDomainCompare);
+
+    debugs(28, 3, "'" << host << "' " << (result ? "found" : "NOT found"));
+
+    return (result != NULL);
+
+}
+
+ACLData<char const *> *
+ACLServerNameData::clone() const
+{
+    /* Splay trees don't clone yet. */
+    assert (!domains);
+    return new ACLServerNameData;
+}
+
+/// A helper function to be used with Ssl::matchX509CommonNames().
+/// \retval 0 when the name (cn or an alternate name) matches acl data
+/// \retval 1 when the name does not match
+template<class MatchType>
+int
+check_cert_domain( void *check_data, ASN1_STRING *cn_data)
+{
+    char cn[1024];
+    ACLData<MatchType> * data = (ACLData<MatchType> *)check_data;
+
+    if (cn_data->length > (int)sizeof(cn) - 1)
+        return 1; // ignore data that does not fit our buffer
+
+    memcpy(cn, cn_data->data, cn_data->length);
+    cn[cn_data->length] = '\0';
+    debugs(28, 4, "Verifying certificate name/subjectAltName " << cn);
+    if (data->match(cn))
+        return 0;
+    return 1;
+}
+
+int
+ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
+{
+    assert(checklist != NULL && checklist->request != NULL);
+
+    if (checklist->conn() && checklist->conn()->serverBump()) {
+        if (X509 *peer_cert = checklist->conn()->serverBump()->serverCert.get()) {
+            if (Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>))
+                return 1;
+        }
+    }
+
+    const char *serverName = NULL;
+    if (checklist->conn() && !checklist->conn()->sslCommonName().isEmpty()) {
+        SBuf scn = checklist->conn()->sslCommonName();
+        serverName = scn.c_str();
+    }
+
+    if (serverName == NULL)
+        serverName = checklist->request->GetHost();
+
+    if (serverName && data->match(serverName)) {
+        return 1;
+    }
+
+    return data->match("none");
+}
+
+ACLServerNameStrategy *
+ACLServerNameStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLServerNameStrategy ACLServerNameStrategy::Instance_;
+
diff --git a/src/acl/ServerName.h b/src/acl/ServerName.h
new file mode 100644 (file)
index 0000000..fd89250
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_ACLSERVERNAME_H
+#define SQUID_ACLSERVERNAME_H
+
+#include "acl/Acl.h"
+#include "acl/Checklist.h"
+#include "acl/Data.h"
+#include "acl/DomainData.h"
+#include "acl/Strategised.h"
+
+class ACLServerNameData : public ACLDomainData {
+    MEMPROXY_CLASS(ACLServerNameData);
+public:
+    ACLServerNameData() : ACLDomainData() {}
+    virtual bool match(const char *);
+    virtual ACLData<char const *> *clone() const;
+};
+
+class ACLServerNameStrategy : public ACLStrategy<char const *>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    static ACLServerNameStrategy *Instance();
+    virtual bool requiresRequest() const {return true;}
+
+    /**
+     * Not implemented to prevent copies of the instance.
+     \par
+     * Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends
+     */
+    ACLServerNameStrategy(ACLServerNameStrategy const &);
+
+private:
+    static ACLServerNameStrategy Instance_;
+    ACLServerNameStrategy() {}
+
+    ACLServerNameStrategy&operator=(ACLServerNameStrategy const &);
+};
+
+class ACLServerName
+{
+
+private:
+    static ACL::Prototype LiteralRegistryProtoype;
+    static ACLStrategised<char const *> LiteralRegistryEntry_;
+    static ACL::Prototype RegexRegistryProtoype;
+    static ACLStrategised<char const *> RegexRegistryEntry_;
+};
+
+#endif /* SQUID_ACLSERVERNAME_H */
+
index 35b23a52426a2f3667a09e553dd267a78b5e790c..0676ea545211b4b1452d87172d6efe517caad446 100644 (file)
@@ -99,11 +99,8 @@ Adaptation::Ecap::HeaderRep::image() const
 void
 Adaptation::Ecap::HeaderRep::parse(const Area &buf)
 {
-    MemBuf mb;
-    mb.init();
-    mb.append(buf.start, buf.size);
     Http::StatusCode error;
-    Must(theMessage.parse(&mb, true, &error));
+    Must(theMessage.parse(buf.start, buf.size, true, &error));
 }
 
 http_hdr_type
index a386ca60dd07fbab13121b606ad4ca5c77847513..8de8d219462f1608a9d464f6d8b0c48caab82eb4 100644 (file)
@@ -557,10 +557,10 @@ void Adaptation::Icap::ModXact::readMore()
         return;
     }
 
-    if (readBuf.hasSpace())
+    if (readBuf.spaceSize())
         scheduleRead();
     else
-        debugs(93,3,HERE << "nothing to do because !readBuf.hasSpace()");
+        debugs(93,3,HERE << "nothing to do because !readBuf.spaceSize()");
 }
 
 // comm module read a portion of the ICAP response for us
@@ -649,9 +649,8 @@ void Adaptation::Icap::ModXact::checkConsuming()
 
 void Adaptation::Icap::ModXact::parseMore()
 {
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " bytes to parse" <<
-           status());
-    debugs(93, 5, HERE << "\n" << readBuf.content());
+    debugs(93, 5, "have " << readBuf.length() << " bytes to parse" << status());
+    debugs(93, 5, "\n" << readBuf);
 
     if (state.parsingHeaders())
         parseHeaders();
@@ -967,7 +966,8 @@ void Adaptation::Icap::ModXact::prepEchoing()
     // parse the buffer back
     Http::StatusCode error = Http::scNone;
 
-    Must(adapted.header->parse(&httpBuf, true, &error));
+    httpBuf.terminate(); // HttpMsg::parse requires nil-terminated buffer
+    Must(adapted.header->parse(httpBuf.content(), httpBuf.contentSize(), true, &error));
 
     if (HttpRequest *r = dynamic_cast<HttpRequest*>(adapted.header))
         urlCanonical(r); // parse does not set HttpRequest::canonical
@@ -1075,11 +1075,13 @@ void Adaptation::Icap::ModXact::parseHttpHead()
 bool Adaptation::Icap::ModXact::parseHead(HttpMsg *head)
 {
     Must(head);
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " head bytes to parse" <<
-           "; state: " << state.parsing);
+    debugs(93, 5, "have " << readBuf.length() << " head bytes to parse; state: " << state.parsing);
 
     Http::StatusCode error = Http::scNone;
-    const bool parsed = head->parse(&readBuf, commEof, &error);
+    // XXX: performance regression. c_str() data copies
+    // XXX: HttpMsg::parse requires a terminated string buffer
+    const char *tmpBuf = readBuf.c_str();
+    const bool parsed = head->parse(tmpBuf, readBuf.length(), commEof, &error);
     Must(parsed || !error); // success or need more data
 
     if (!parsed) { // need more data
@@ -1117,15 +1119,22 @@ void Adaptation::Icap::ModXact::parseBody()
     Must(state.parsing == State::psBody);
     Must(bodyParser);
 
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " body bytes to parse");
+    debugs(93, 5, "have " << readBuf.length() << " body bytes to parse");
 
     // the parser will throw on errors
     BodyPipeCheckout bpc(*adapted.body_pipe);
-    const bool parsed = bodyParser->parse(&readBuf, &bpc.buf);
+    // XXX: performance regression. SBuf-convert (or Parser-convert?) the chunked decoder.
+    MemBuf encodedData;
+    encodedData.init();
+    // NP: we must do this instead of pointing encodedData at the SBuf::rawContent
+    // because chunked decoder uses MemBuf::consume, which shuffles buffer bytes around.
+    encodedData.append(readBuf.rawContent(), readBuf.length());
+    const bool parsed = bodyParser->parse(&encodedData, &bpc.buf);
+    // XXX: httpChunkDecoder has consumed from MemBuf.
+    readBuf.consume(readBuf.length() - encodedData.contentSize());
     bpc.checkIn();
 
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " body bytes after " <<
-           "parse; parsed all: " << parsed);
+    debugs(93, 5, "have " << readBuf.length() << " body bytes after parsed all: " << parsed);
     replyHttpBodySize += adapted.body_pipe->buf().contentSize();
 
     // TODO: expose BodyPipe::putSize() to make this check simpler and clearer
index 103b2968fbc94e23ab5c703ac223167b2689637e..5aa1225441b0e82de2110a4c757b7b1cbc2378b2 100644 (file)
@@ -67,7 +67,8 @@ void Adaptation::Icap::OptXact::makeRequest(MemBuf &buf)
 
     // XXX: HttpRequest cannot fully parse ICAP Request-Line
     Http::StatusCode reqStatus;
-    Must(icapRequest->parse(&buf, true, &reqStatus) > 0);
+    buf.terminate(); // HttpMsg::parse requires terminated buffer
+    Must(icapRequest->parse(buf.content(), buf.contentSize(), true, &reqStatus) > 0);
 }
 
 void Adaptation::Icap::OptXact::handleCommWrote(size_t size)
@@ -99,9 +100,8 @@ void Adaptation::Icap::OptXact::handleCommRead(size_t)
 
 bool Adaptation::Icap::OptXact::parseResponse()
 {
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " bytes to parse" <<
-           status());
-    debugs(93, 5, HERE << "\n" << readBuf.content());
+    debugs(93, 5, "have " << readBuf.length() << " bytes to parse" << status());
+    debugs(93, DBG_DATA, "\n" << readBuf);
 
     HttpReply::Pointer r(new HttpReply);
     r->protoPrefix = "ICAP/"; // TODO: make an IcapReply class?
index ada97ce6871126d0478b9cc57894aebdc2b9fd0b..62afdccc7a021f06f1bb01a4f7674f9fdfe21bd4 100644 (file)
@@ -39,8 +39,6 @@ Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Icap::Serv
     attempts(0),
     connection(NULL),
     theService(aService),
-    commBuf(NULL),
-    commBufSize(0),
     commEof(false),
     reuseConnection(true),
     isRetriable(true),
@@ -95,11 +93,6 @@ void Adaptation::Icap::Xaction::disableRepeats(const char *reason)
 void Adaptation::Icap::Xaction::start()
 {
     Adaptation::Initiate::start();
-
-    readBuf.init(SQUID_TCP_SO_RCVBUF, SQUID_TCP_SO_RCVBUF);
-    commBuf = (char*)memAllocBuf(SQUID_TCP_SO_RCVBUF, &commBufSize);
-    // make sure maximum readBuf space does not exceed commBuf size
-    Must(static_cast<size_t>(readBuf.potentialSpaceSize()) <= commBufSize);
 }
 
 static void
@@ -383,17 +376,11 @@ void Adaptation::Icap::Xaction::scheduleRead()
 {
     Must(haveConnection());
     Must(!reader);
-    Must(readBuf.hasSpace());
+    Must(readBuf.length() < SQUID_TCP_SO_RCVBUF); // will expand later if needed
 
-    /*
-     * See comments in Adaptation::Icap::Xaction.h about why we use commBuf
-     * here instead of reading directly into readBuf.buf.
-     */
     typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommIoCbParams> Dialer;
-    reader = JobCallback(93, 3,
-                         Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
-
-    comm_read(connection, commBuf, readBuf.spaceSize(), reader);
+    reader = JobCallback(93, 3, Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
+    Comm::Read(connection, reader);
     updateTimeout();
 }
 
@@ -405,7 +392,32 @@ void Adaptation::Icap::Xaction::noteCommRead(const CommIoCbParams &io)
 
     Must(io.flag == Comm::OK);
 
-    if (!io.size) {
+    // TODO: tune this better to expected message sizes
+    readBuf.reserveCapacity(SQUID_TCP_SO_RCVBUF);
+
+    CommIoCbParams rd(this); // will be expanded with ReadNow results
+    rd.conn = io.conn;
+
+    switch (Comm::ReadNow(rd, readBuf)) {
+    case Comm::INPROGRESS:
+        if (readBuf.isEmpty())
+            debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
+        scheduleRead();
+        return;
+
+    case Comm::OK:
+        al.icap.bytesRead += rd.size;
+
+        updateTimeout();
+
+        debugs(93, 3, "read " << rd.size << " bytes");
+
+        disableRetries(); // because pconn did not fail
+
+        /* Continue to process previously read data */
+        break;
+
+    case Comm::ENDFILE: // close detected by 0-byte read
         commEof = true;
         reuseConnection = false;
 
@@ -415,21 +427,14 @@ void Adaptation::Icap::Xaction::noteCommRead(const CommIoCbParams &io)
             mustStop("pconn race");
             return;
         }
-    } else {
-
-        al.icap.bytesRead+=io.size;
-
-        updateTimeout();
-
-        debugs(93, 3, HERE << "read " << io.size << " bytes");
 
-        /*
-         * See comments in Adaptation::Icap::Xaction.h about why we use commBuf
-         * here instead of reading directly into readBuf.buf.
-         */
+        break;
 
-        readBuf.append(commBuf, io.size);
-        disableRetries(); // because pconn did not fail
+    // case Comm::COMM_ERROR:
+    default: // no other flags should ever occur
+        debugs(11, 2, io.conn << ": read failure: " << xstrerr(rd.xerrno));
+        mustStop("unknown ICAP I/O read error");
+        return;
     }
 
     handleCommRead(io.size);
@@ -446,10 +451,12 @@ void Adaptation::Icap::Xaction::cancelRead()
 
 bool Adaptation::Icap::Xaction::parseHttpMsg(HttpMsg *msg)
 {
-    debugs(93, 5, HERE << "have " << readBuf.contentSize() << " head bytes to parse");
+    debugs(93, 5, "have " << readBuf.length() << " head bytes to parse");
 
     Http::StatusCode error = Http::scNone;
-    const bool parsed = msg->parse(&readBuf, commEof, &error);
+    // XXX: performance regression c_str() data copies
+    const char *buf = readBuf.c_str();
+    const bool parsed = msg->parse(buf, readBuf.length(), commEof, &error);
     Must(parsed || !error); // success or need more data
 
     if (!parsed) {  // need more data
@@ -465,7 +472,7 @@ bool Adaptation::Icap::Xaction::parseHttpMsg(HttpMsg *msg)
 bool Adaptation::Icap::Xaction::mayReadMore() const
 {
     return !doneReading() && // will read more data
-           readBuf.hasSpace();  // have space for more data
+           readBuf.spaceSize();  // have space for more data
 }
 
 bool Adaptation::Icap::Xaction::doneReading() const
@@ -530,11 +537,7 @@ void Adaptation::Icap::Xaction::swanSong()
 
     closeConnection(); // TODO: rename because we do not always close
 
-    if (!readBuf.isNull())
-        readBuf.clean();
-
-    if (commBuf)
-        memFreeBuf(commBufSize, commBuf);
+    readBuf.clear();
 
     tellQueryAborted();
 
index 644449521c94dc5f7d2f18ba82484ae1291b4dba..2f5945741bb171bebd35e67d63b6b1b27f7ff248 100644 (file)
@@ -16,7 +16,9 @@
 #include "CommCalls.h"
 #include "HttpReply.h"
 #include "ipcache.h"
-#include "MemBuf.h"
+#include "SBuf.h"
+
+class MemBuf;
 
 namespace Adaptation
 {
@@ -127,20 +129,7 @@ protected:
     Comm::ConnectionPointer connection;     ///< ICAP server connection
     Adaptation::Icap::ServiceRep::Pointer theService;
 
-    /*
-     * We have two read buffers.   We would prefer to read directly
-     * into the MemBuf, but since comm_read isn't MemBuf-aware, and
-     * uses event-delayed callbacks, it leaves the MemBuf in an
-     * inconsistent state.  There would be data in the buffer, but
-     * MemBuf.size won't be updated until the (delayed) callback
-     * occurs.   To avoid that situation we use a plain buffer
-     * (commBuf) and then copy (append) its contents to readBuf in
-     * the callback.  If comm_read ever becomes MemBuf-aware, we
-     * can eliminate commBuf and this extra buffer copy.
-     */
-    MemBuf readBuf;
-    char *commBuf;
-    size_t commBufSize;
+    SBuf readBuf;
     bool commEof;
     bool reuseConnection;
     bool isRetriable;  ///< can retry on persistent connection failures
index 39701e5dd0c08db8e240c5e274fa26ac61396299..d2a412748d690b5996b5f496d07385150e63e99d 100644 (file)
@@ -27,8 +27,8 @@ class HttpRequest;
 /**
  * Maximum length (buffer size) for token strings.
  */
-// AYJ: must match re-definition in helpers/negotiate_auth/kerberos/negotiate_kerb_auth.cc
-#define MAX_AUTHTOKEN_LEN   32768
+// XXX: Keep in sync with all others: bzr grep 'define MAX_AUTHTOKEN_LEN'
+#define MAX_AUTHTOKEN_LEN   65535
 
 /**
  * Node used to link an IP address to some user credentials
index c95f8bc155548ac41538ae63d88809f9e0dc5752..5e134bd27d8bc07aeba4a6368b454761d2917bcf 100644 (file)
@@ -69,11 +69,20 @@ const char *
 Auth::Negotiate::UserRequest::credentialsStr()
 {
     static char buf[MAX_AUTHTOKEN_LEN];
+    int printResult = 0;
     if (user()->credentials() == Auth::Pending) {
-        snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+        printResult = snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
     } else {
-        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+        printResult = snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
     }
+
+    // truncation is OK because we are used only for logging
+    if (printResult < 0) {
+        debugs(29, 2, "Can not build negotiate authentication credentials.");
+        buf[0] = '\0';
+    } else if (printResult >= (int)sizeof(buf))
+        debugs(29, 2, "Negotiate authentication credentials truncated.");
+
     return buf;
 }
 
@@ -126,16 +135,26 @@ Auth::Negotiate::UserRequest::startHelperLookup(HttpRequest *, AccessLogEntry::P
     debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'");
 
     const char *keyExtras = helperRequestKeyExtras(request, al);
+    int printResult = 0;
     if (user()->credentials() == Auth::Pending) {
         if (keyExtras)
-            snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
+            printResult = snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
         else
-            snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+            printResult = snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
     } else {
         if (keyExtras)
-            snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
+            printResult = snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
         else
-            snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+            printResult = snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+    }
+
+    if (printResult < 0 || printResult >= (int)sizeof(buf)) {
+        if (printResult < 0)
+            debugs(29, DBG_CRITICAL, "ERROR: Can not build negotiate authentication helper request");
+        else
+            debugs(29, DBG_CRITICAL, "ERROR: Negotiate authentication helper request too big for the " << sizeof(buf) << "-byte buffer");
+        handler(data);
+        return;
     }
 
     waiting = 1;
index 9dbba526196fbeb07af69854e4fd35460133086c..76b76f2f3440508253b715e6e2baf670b94347e5 100644 (file)
@@ -68,11 +68,20 @@ const char *
 Auth::Ntlm::UserRequest::credentialsStr()
 {
     static char buf[MAX_AUTHTOKEN_LEN];
+    int printResult;
     if (user()->credentials() == Auth::Pending) {
-        snprintf(buf, sizeof(buf), "YR %s\n", client_blob);
+        printResult = snprintf(buf, sizeof(buf), "YR %s\n", client_blob);
     } else {
-        snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+        printResult = snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
     }
+
+    // truncation is OK because we are used only for logging
+    if (printResult < 0) {
+        debugs(29, 2, "Can not build ntlm authentication credentials.");
+        buf[0] = '\0';
+    } else if (printResult >= (int)sizeof(buf))
+        debugs(29, 2, "Ntlm authentication credentials truncated.");
+
     return buf;
 }
 
@@ -122,19 +131,29 @@ Auth::Ntlm::UserRequest::startHelperLookup(HttpRequest *, AccessLogEntry::Pointe
     debugs(29, 8, HERE << "credentials state is '" << user()->credentials() << "'");
 
     const char *keyExtras = helperRequestKeyExtras(request, al);
+    int printResult = 0;
     if (user()->credentials() == Auth::Pending) {
         if (keyExtras)
-            snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
+            printResult = snprintf(buf, sizeof(buf), "YR %s %s\n", client_blob, keyExtras);
         else
-            snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
+            printResult = snprintf(buf, sizeof(buf), "YR %s\n", client_blob); //CHECKME: can ever client_blob be 0 here?
     } else {
         if (keyExtras)
-            snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
+            printResult = snprintf(buf, sizeof(buf), "KK %s %s\n", client_blob, keyExtras);
         else
-            snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
+            printResult = snprintf(buf, sizeof(buf), "KK %s\n", client_blob);
     }
     waiting = 1;
 
+    if (printResult < 0 || printResult >= (int)sizeof(buf)) {
+        if (printResult < 0)
+            debugs(29, DBG_CRITICAL, "ERROR: Can not build ntlm authentication helper request");
+        else
+            debugs(29, DBG_CRITICAL, "ERROR: Ntlm authentication helper request too big for the " << sizeof(buf) << "-byte buffer.");
+        handler(data);
+        return;
+    }
+
     safe_free(client_blob);
     helperStatefulSubmit(ntlmauthenticators, buf, Auth::Ntlm::UserRequest::HandleReply,
                          new Auth::StateData(this, handler, data), authserver);
index d81d793619f42887ea933e794fff7417a515f6fc..8a995e59ca5487067670fc1ab4d7eadd707395f6 100644 (file)
@@ -35,12 +35,13 @@ public:
 #if defined(LOCKCOUNT_DEBUG)
         old_debug(0,1)("Incrementing this %p from count %u\n",this,count_);
 #endif
+        assert(count_ < UINT32_MAX);
         ++count_;
     }
 
     /// Clear one lock / reference against this object.
     /// All locks must be cleared before it may be destroyed.
-    unsigned unlock() const {
+    uint32_t unlock() const {
 #if defined(LOCKCOUNT_DEBUG)
         old_debug(0,1)("Decrementing this %p from count %u\n",this,count_);
 #endif
@@ -49,10 +50,10 @@ public:
     }
 
     /// Inspect the current count of references.
-    unsigned LockCount() const { return count_; }
+    uint32_t LockCount() const { return count_; }
 
 private:
-    mutable unsigned count_; ///< number of references currently being tracked
+    mutable uint32_t count_; ///< number of references currently being tracked
 };
 
 // For clarity we provide some aliases for the tracking mechanisms
index 18b6cfb9889836021095ccc703d4a5c31f62b8a0..ec2a98c9d7dfb958a6a121b8e15caed0cfc7486f 100644 (file)
@@ -39,9 +39,11 @@ public:
         reference (p);
     }
 
+#if __cplusplus >= 201103L
     RefCount (RefCount &&p) : p_(std::move(p.p_)) {
         p.p_=NULL;
     }
+#endif
 
     RefCount& operator = (const RefCount& p) {
         // DO NOT CHANGE THE ORDER HERE!!!
@@ -52,6 +54,7 @@ public:
         return *this;
     }
 
+#if __cplusplus >= 201103L
     RefCount& operator = (RefCount&& p) {
         if (this != &p) {
             dereference(p.p_);
@@ -59,6 +62,7 @@ public:
         }
         return *this;
     }
+#endif
 
     bool operator !() const { return !p_; }
 
index 390e69179b9ead1ab2fd9da5aac713fe7bb5ba82..ad3c2e9aa11734f8eec832f2600a56700de0c9cb 100644 (file)
 #include "Store.h"
 
 #include <climits>
+
 #if USE_CBDATA_DEBUG
 #include <algorithm>
 #include <vector>
 #endif
 
 #if WITH_VALGRIND
-#define HASHED_CBDATA 1
+#include <map>
 #endif
 
 static int cbdataCount = 0;
@@ -58,7 +59,7 @@ public:
  */
 class cbdata
 {
-#if !HASHED_CBDATA
+#if !WITH_VALGRIND
 public:
     void *operator new(size_t, void *where) {return where;}
     /**
@@ -73,16 +74,22 @@ public:
     /** \todo examine making cbdata templated on this - so we get type
      * safe access to data - RBC 20030902 */
 public:
-#if HASHED_CBDATA
-    hash_link hash; // Must be first
-#endif
-
 #if USE_CBDATA_DEBUG
 
     void dump(StoreEntry *)const;
 #endif
-
+    cbdata() :
+        valid(0),
+        locks(0),
+#if USE_CBDATA_DEBUG
+        file(NULL),
+        line(0),
+#endif
+        cookie(0),
+        data(NULL)
+    {}
     ~cbdata();
+
     int valid;
     int32_t locks;
     cbdata_type type;
@@ -106,18 +113,17 @@ public:
     void check(int) const {assert(cookie == ((long)this ^ Cookie));}
     static const long Cookie;
 
-#if !HASHED_CBDATA
+#if !WITH_VALGRIND
     size_t dataSize() const { return sizeof(data);}
     static long MakeOffset();
     static const long Offset;
+#endif
     /* MUST be the last per-instance member */
     void *data;
-#endif
-
 };
 
 const long cbdata::Cookie((long)0xDEADBEEF);
-#if !HASHED_CBDATA
+#if !WITH_VALGRIND
 const long cbdata::Offset(MakeOffset());
 
 long
@@ -136,26 +142,13 @@ static OBJH cbdataDumpHistory;
 
 struct CBDataIndex {
     MemAllocator *pool;
-    FREE *free_func;
 }
 *cbdata_index = NULL;
 
 int cbdata_types = 0;
 
-#if HASHED_CBDATA
-static hash_table *cbdata_htable = NULL;
-
-static int
-cbdata_cmp(const void *p1, const void *p2)
-{
-    return (char *) p1 - (char *) p2;
-}
-
-static unsigned int
-cbdata_hash(const void *p, unsigned int mod)
-{
-    return ((unsigned long) p >> 8) % mod;
-}
+#if WITH_VALGRIND
+static std::map<const void *, cbdata *> cbdata_htable;
 #endif
 
 cbdata::~cbdata()
@@ -168,21 +161,10 @@ cbdata::~cbdata()
     }
 
 #endif
-
-    FREE *free_func = cbdata_index[type].free_func;
-
-#if HASHED_CBDATA
-    void *p = hash.key;
-#else
-    void *p = &data;
-#endif
-
-    if (free_func)
-        free_func(p);
 }
 
 static void
-cbdataInternalInitType(cbdata_type type, const char *name, int size, FREE * free_func)
+cbdataInternalInitType(cbdata_type type, const char *name, int size)
 {
     char *label;
     assert (type == cbdata_types + 1);
@@ -195,30 +177,23 @@ cbdataInternalInitType(cbdata_type type, const char *name, int size, FREE * free
 
     snprintf(label, strlen(name) + 20, "cbdata %s (%d)", name, (int) type);
 
-#if !HASHED_CBDATA
+#if !WITH_VALGRIND
     assert((size_t)cbdata::Offset == (sizeof(cbdata) - ((cbdata *)NULL)->dataSize()));
     size += cbdata::Offset;
 #endif
 
     cbdata_index[type].pool = memPoolCreate(label, size);
-
-    cbdata_index[type].free_func = free_func;
-
-#if HASHED_CBDATA
-    if (!cbdata_htable)
-        cbdata_htable = hash_create(cbdata_cmp, 1 << 12, cbdata_hash);
-#endif
 }
 
 cbdata_type
-cbdataInternalAddType(cbdata_type type, const char *name, int size, FREE * free_func)
+cbdataInternalAddType(cbdata_type type, const char *name, int size)
 {
     if (type)
         return type;
 
     type = (cbdata_type)(cbdata_types + 1);
 
-    cbdataInternalInitType(type, name, size, free_func);
+    cbdataInternalInitType(type, name, size);
 
     return type;
 }
@@ -246,11 +221,11 @@ cbdataInternalAlloc(cbdata_type type, const char *file, int line)
     /* placement new: the pool alloc gives us cbdata + user type memory space
      * and we init it with cbdata at the start of it
      */
-#if HASHED_CBDATA
+#if WITH_VALGRIND
     c = new cbdata;
     p = cbdata_index[type].pool->alloc();
-    c->hash.key = p;
-    hash_join(cbdata_htable, &c->hash);
+    c->data = p;
+    cbdata_htable.emplace(p,c);
 #else
     c = new (cbdata_index[type].pool->alloc()) cbdata;
     p = (void *)&c->data;
@@ -287,6 +262,17 @@ cbdataRealFree(cbdata *c, const char *file, const int line)
     dlinkDelete(&c->link, &cbdataEntries);
 #endif
 
+#if WITH_VALGRIND
+    cbdata_htable.erase(c->data);
+#if USE_CBDATA_DEBUG
+    debugs(45, 3, "Call delete " << p << " " << file << ":" << line);
+#endif
+    delete c;
+#else
+#if USE_CBDATA_DEBUG
+    debugs(45, 3, "Call cbdata::~cbdata() " << p << " " << file << ":" << line);
+#endif
+
     /* This is ugly. But: operator delete doesn't get
      * the type parameter, so we can't use that
      * to free the memory.
@@ -298,27 +284,17 @@ cbdataRealFree(cbdata *c, const char *file, const int line)
      * and it would Just Work. RBC 20030902
      */
     cbdata_type theType = c->type;
-#if HASHED_CBDATA
-    hash_remove_link(cbdata_htable, &c->hash);
-#if USE_CBDATA_DEBUG
-    debugs(45, 3, "Call delete " << p << " " << file << ":" << line);
-#endif
-    delete c;
-#else
-#if USE_CBDATA_DEBUG
-    debugs(45, 3, "Call cbdata::~cbdata() " << p << " " << file << ":" << line);
-#endif
     c->cbdata::~cbdata();
-#endif
     cbdata_index[theType].pool->freeOne(p);
+#endif
 }
 
 void *
 cbdataInternalFree(void *p, const char *file, int line)
 {
     cbdata *c;
-#if HASHED_CBDATA
-    c = (cbdata *) hash_lookup(cbdata_htable, p);
+#if WITH_VALGRIND
+    c = cbdata_htable.at(p);
 #else
     c = (cbdata *) (((char *) p) - cbdata::Offset);
 #endif
@@ -357,8 +333,8 @@ cbdataInternalLock(const void *p)
     if (p == NULL)
         return;
 
-#if HASHED_CBDATA
-    c = (cbdata *) hash_lookup(cbdata_htable, p);
+#if WITH_VALGRIND
+    c = cbdata_htable.at(p);
 #else
     c = (cbdata *) (((char *) p) - cbdata::Offset);
 #endif
@@ -389,8 +365,8 @@ cbdataInternalUnlock(const void *p)
     if (p == NULL)
         return;
 
-#if HASHED_CBDATA
-    c = (cbdata *) hash_lookup(cbdata_htable, p);
+#if WITH_VALGRIND
+    c = cbdata_htable.at(p);
 #else
     c = (cbdata *) (((char *) p) - cbdata::Offset);
 #endif
@@ -437,8 +413,8 @@ cbdataReferenceValid(const void *p)
 
     debugs(45, 9, p);
 
-#if HASHED_CBDATA
-    c = (cbdata *) hash_lookup(cbdata_htable, p);
+#if WITH_VALGRIND
+    c = cbdata_htable.at(p);
 #else
     c = (cbdata *) (((char *) p) - cbdata::Offset);
 #endif
@@ -481,8 +457,8 @@ cbdataInternalReferenceDoneValid(void **pp, void **tp)
 void
 cbdata::dump(StoreEntry *sentry) const
 {
-#if HASHED_CBDATA
-    void *p = (void *)hash.key;
+#if WITH_VALGRIND
+    void *p = data;
 #else
     void *p = (void *)&data;
 #endif
@@ -518,7 +494,7 @@ cbdataDump(StoreEntry * sentry)
         MemAllocator *pool = cbdata_index[i].pool;
 
         if (pool) {
-#if HASHED_CBDATA
+#if WITH_VALGRIND
             int obj_size = pool->objectSize();
 #else
             int obj_size = pool->objectSize() - cbdata::Offset;
index c28c1c4b3cab0a2e8c2bb92755b153ee764c3262..5a94aebdc1dc7d84f210fde1510c3d0dcfc536db 100644 (file)
@@ -272,7 +272,7 @@ int cbdataReferenceValid(const void *p);
  *
  * \note For internal CBDATA use only.
  */
-cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func);
+cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size);
 
 /**
  * This needs to be defined FIRST in the class definition.
@@ -282,7 +282,7 @@ cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size,
     public: \
         void *operator new(size_t size) { \
           assert(size == sizeof(type)); \
-          if (!CBDATA_##type) CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), NULL); \
+          if (!CBDATA_##type) CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type)); \
           return (type *)cbdataInternalAlloc(CBDATA_##type,__FILE__,__LINE__); \
         } \
         void operator delete (void *address) { \
index 8ef042ded157af141d0ababa30ebe559612da5f2..642ca00cc4c7a90b780ff0656bdf5aad2fe99eb2 100644 (file)
@@ -1168,6 +1168,18 @@ IF USE_OPENSSL
          #   SslBump1: After getting TCP-level and HTTP CONNECT info.
          #   SslBump2: After getting SSL Client Hello info.
          #   SslBump3: After getting SSL Server Hello info.
+
+       acl aclname ssl::server_name .foo.com ...
+         # matches server name obtained from various sources [fast]
+         #
+         # The server name is obtained during Ssl-Bump steps from such sources
+         # as CONNECT request URI, client SNI, and SSL server certificate CN.
+         # During each Ssl-Bump step, Squid may improve its understanding of a
+         # "true server name". Unlike dstdomain, this ACL does not perform
+         # DNS lookups.
+
+       acl aclname ssl::server_name_regex [-i] \.foo\.com ...
+         # regex matches server name obtained from various sources [fast]
 ENDIF
        acl aclname any-of acl1 acl2 ...
          # match any one of the acls [fast or slow]
@@ -1685,14 +1697,15 @@ DEFAULT: none
 DEFAULT_DOC: Respond with an error message to unidentifiable traffic
 DOC_START
        Determines Squid behavior when encountering strange requests at the
-       beginning of an accepted TCP connection. This is especially useful in
-       interception environments where Squid is likely to see connections for
-       unsupported protocols that Squid should either terminate or tunnel at
-       TCP level.
+       beginning of an accepted TCP connection or the beginning of a bumped
+       CONNECT tunnel. Controlling Squid reaction to unexpected traffic is
+       especially useful in interception environments where Squid is likely
+       to see connections for unsupported protocols that Squid should either
+       terminate or tunnel at TCP level.
  
                on_unsupported_protocol <action> [!]acl ...
  
-       The first matching action wins.
+       The first matching action wins. Only fast ACLs are supported.
 
        Supported actions are:
  
@@ -1703,9 +1716,18 @@ DOC_START
                for the Squid port that received the request (e.g., HTTP
                for connections intercepted at the http_port). This is the
                default.
-       Currently, this directive is ignored for non-intercepted connections
-       because Squid cannot know what their intended destination is.
+
+       Squid expects the following traffic patterns:
+
+         http_port: a plain HTTP request
+         https_port: SSL/TLS handshake followed by an [encrypted] HTTP request
+         ftp_port: a plain FTP command (no on_unsupported_protocol support yet!)
+         CONNECT tunnel on http_port: same as https_port
+         CONNECT tunnel on https_port: same as https_port
+
+       Currently, this directive has effect on intercepted connections and
+       bumped tunnels only. Other cases are not supported because Squid
+       cannot know the intended destination of other traffic.
 
        For example:
          # define what Squid errors indicate receiving non-HTTP traffic:
@@ -2216,9 +2238,10 @@ DOC_START
        RFC2475, and RFC3260.
 
        The TOS/DSCP byte must be exactly that - a octet value  0 - 255, or
-       "default" to use whatever default your host has. Note that in
-       practice often only multiples of 4 is usable as the two rightmost bits
-       have been redefined for use by ECN (RFC 3168 section 23.1).
+       "default" to use whatever default your host has.
+       Note that only multiples of 4 are usable as the two rightmost bits have
+       been redefined for use by ECN (RFC 3168 section 23.1).
+       The squid parser will enforce this by masking away the ECN bits.
 
        Processing proceeds in the order specified, and stops at first fully
        matching line.
@@ -2231,7 +2254,7 @@ TYPE: acl_tos
 DEFAULT: none
 LOC: Ip::Qos::TheConfig.tosToClient
 DOC_START
-       Allows you to select a TOS/Diffserv value for packets being transmitted
+       Allows you to select a TOS/DSCP value for packets being transmitted
        on the client-side, based on an ACL.
 
        clientside_tos ds-field [!]aclname ...
@@ -2246,6 +2269,13 @@ DOC_START
 
        Note: This feature is incompatible with qos_flows. Any TOS values set here
        will be overwritten by TOS values in qos_flows.
+
+       The TOS/DSCP byte must be exactly that - a octet value  0 - 255, or
+       "default" to use whatever default your host has.
+       Note that only multiples of 4 are usable as the two rightmost bits have
+       been redefined for use by ECN (RFC 3168 section 23.1).
+       The squid parser will enforce this by masking away the ECN bits.
+
 DOC_END
 
 NAME: tcp_outgoing_mark
@@ -2317,9 +2347,10 @@ DOC_START
        know what you're specifying. For more information, see RFC2474,
        RFC2475, and RFC3260.
 
-       The TOS/DSCP byte must be exactly that - a octet value  0 - 255. Note that
-       in practice often only multiples of 4 is usable as the two rightmost bits
-       have been redefined for use by ECN (RFC 3168 section 23.1).
+       The TOS/DSCP byte must be exactly that - a octet value  0 - 255.
+       Note that only multiples of 4 are usable as the two rightmost bits have
+       been redefined for use by ECN (RFC 3168 section 23.1).
+       The squid parser will enforce this by masking away the ECN bits.
 
        Mark values can be any unsigned 32-bit integer value.
 
index 4bfdde95dbfa42e3778fb55f660aa295d96dddf1..b4f6112e5d9423eeba9ae41f7a27e34e51b98ad9 100644 (file)
@@ -235,7 +235,8 @@ ConnStateData::readSomeData()
 
     debugs(33, 4, HERE << clientConnection << ": reading request...");
 
-    if (!in.maybeMakeSpaceAvailable())
+    // we can only read if there is more than 1 byte of space free
+    if (Config.maxRequestBufferSize - in.buf.length() < 2)
         return;
 
     typedef CommCbMemFunT<ConnStateData, CommIoCbParams> Dialer;
@@ -2899,7 +2900,8 @@ ConnStateData::parseProxy1p0()
         debugs(33, 5, "PROXY/1.0 protocol on connection " << clientConnection);
         clientConnection->local = originalDest;
         clientConnection->remote = originalClient;
-        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
+        if ((clientConnection->flags & COMM_TRANSPARENT))
+            clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         debugs(33, 5, "PROXY/1.0 upgrade: " << clientConnection);
 
         // repeat fetch ensuring the new client FQDN can be logged
@@ -2989,14 +2991,16 @@ ConnStateData::parseProxy2p0()
         clientConnection->local.port(ntohs(ipu.ipv4_addr.dst_port));
         clientConnection->remote = ipu.ipv4_addr.src_addr;
         clientConnection->remote.port(ntohs(ipu.ipv4_addr.src_port));
-        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
+        if ((clientConnection->flags & COMM_TRANSPARENT))
+            clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         break;
     case 0x2: // IPv6
         clientConnection->local = ipu.ipv6_addr.dst_addr;
         clientConnection->local.port(ntohs(ipu.ipv6_addr.dst_port));
         clientConnection->remote = ipu.ipv6_addr.src_addr;
         clientConnection->remote.port(ntohs(ipu.ipv6_addr.src_port));
-        clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
+        if ((clientConnection->flags & COMM_TRANSPARENT))
+            clientConnection->flags ^= COMM_TRANSPARENT; // prevent TPROXY spoofing of this new IP.
         break;
     default: // do nothing
         break;
@@ -3110,6 +3114,7 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io)
      * Plus, it breaks our lame *HalfClosed() detection
      */
 
+    in.maybeMakeSpaceAvailable();
     CommIoCbParams rd(this); // will be expanded with ReadNow results
     rd.conn = io.conn;
     switch (Comm::ReadNow(rd, in.buf)) {
@@ -3425,9 +3430,6 @@ ConnStateData::start()
     BodyProducer::start();
     HttpControlMsgSink::start();
 
-    // ensure a buffer is present for this connection
-    in.maybeMakeSpaceAvailable();
-
     if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF &&
             (transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
@@ -3688,6 +3690,14 @@ clientNegotiateSSL(int fd, void *data)
                " has no certificate.");
     }
 
+#if defined(TLSEXT_NAMETYPE_host_name)
+    if (!conn->serverBump()) {
+        // when in bumpClientFirst mode, get the server name from SNI
+        if (const char *server = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
+            conn->resetSslCommonName(server);
+    }
+#endif
+
     conn->readSomeData();
 }
 
@@ -3696,13 +3706,13 @@ clientNegotiateSSL(int fd, void *data)
  * Otherwise, calls switchToHttps to generate a dynamic SSL_CTX.
  */
 static void
-httpsEstablish(ConnStateData *connState,  SSL_CTX *sslContext, Ssl::BumpMode bumpMode)
+httpsEstablish(ConnStateData *connState,  SSL_CTX *sslContext)
 {
     SSL *ssl = NULL;
     assert(connState);
     const Comm::ConnectionPointer &details = connState->clientConnection;
 
-    if (sslContext && !(ssl = httpsCreate(details, sslContext)))
+    if (!sslContext || !(ssl = httpsCreate(details, sslContext)))
         return;
 
     typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
@@ -3710,34 +3720,7 @@ httpsEstablish(ConnStateData *connState,  SSL_CTX *sslContext, Ssl::BumpMode bum
                                      connState, ConnStateData::requestTimeout);
     commSetConnTimeout(details, Config.Timeout.request, timeoutCall);
 
-    if (ssl)
-        Comm::SetSelect(details->fd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0);
-    else {
-        char buf[MAX_IPSTRLEN];
-        assert(bumpMode != Ssl::bumpNone && bumpMode != Ssl::bumpEnd);
-        HttpRequest::Pointer fakeRequest(new HttpRequest);
-        fakeRequest->SetHost(details->local.toStr(buf, sizeof(buf)));
-        fakeRequest->port = details->local.port();
-        fakeRequest->clientConnectionManager = connState;
-        fakeRequest->client_addr = connState->clientConnection->remote;
-#if FOLLOW_X_FORWARDED_FOR
-        fakeRequest->indirect_client_addr = connState->clientConnection->remote;
-#endif
-        fakeRequest->my_addr = connState->clientConnection->local;
-        fakeRequest->flags.interceptTproxy = ((connState->clientConnection->flags & COMM_TRANSPARENT) != 0 ) ;
-        fakeRequest->flags.intercepted = ((connState->clientConnection->flags & COMM_INTERCEPTION) != 0);
-        fakeRequest->myportname = connState->port->name;
-        if (fakeRequest->flags.interceptTproxy) {
-            if (Config.accessList.spoof_client_ip) {
-                ACLFilledChecklist checklist(Config.accessList.spoof_client_ip, fakeRequest.getRaw(), NULL);
-                fakeRequest->flags.spoofClientIp = (checklist.fastCheck() == ACCESS_ALLOWED);
-            } else
-                fakeRequest->flags.spoofClientIp = true;
-        } else
-            fakeRequest->flags.spoofClientIp = false;
-        debugs(33, 4, HERE << details << " try to generate a Dynamic SSL CTX");
-        connState->switchToHttps(fakeRequest.getRaw(), bumpMode);
-    }
+    Comm::SetSelect(details->fd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0);
 }
 
 /**
@@ -3837,7 +3820,7 @@ ConnStateData::postHttpsAccept()
         return;
     } else {
         SSL_CTX *sslContext = port->staticSslContext.get();
-        httpsEstablish(this, sslContext, Ssl::bumpNone);
+        httpsEstablish(this, sslContext);
     }
 }
 
@@ -3883,7 +3866,7 @@ ConnStateData::sslCrtdHandleReply(const Helper::Reply &reply)
 
 void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties)
 {
-    certProperties.commonName =  sslCommonName.size() > 0 ? sslCommonName.termedBuf() : sslConnectHostOrIp.termedBuf();
+    certProperties.commonName =  sslCommonName_.isEmpty() ? sslConnectHostOrIp.termedBuf() : sslCommonName_.c_str();
 
     // fake certificate adaptation requires bump-server-first mode
     if (!sslServerBump) {
@@ -4104,7 +4087,7 @@ ConnStateData::switchToHttps(HttpRequest *request, Ssl::BumpMode bumpServerMode)
     assert(!switchedToHttps_);
 
     sslConnectHostOrIp = request->GetHost();
-    sslCommonName = request->GetHost();
+    resetSslCommonName(request->GetHost());
 
     // We are going to read new request
     flags.readMore = true;
@@ -4181,8 +4164,10 @@ clientPeekAndSpliceSSL(int fd, void *data)
     if (bio->gotHello()) {
         if (conn->serverBump()) {
             Ssl::Bio::sslFeatures const &features = bio->getFeatures();
-            if (!features.serverName.isEmpty())
+            if (!features.serverName.isEmpty()) {
                 conn->serverBump()->clientSni = features.serverName;
+                conn->resetSslCommonName(features.serverName.c_str());
+            }
         }
 
         debugs(83, 5, "I got hello. Start forwarding the request!!! ");
@@ -4337,30 +4322,11 @@ ConnStateData::httpsPeeked(Comm::ConnectionPointer serverConnection)
     Must(sslServerBump != NULL);
 
     if (Comm::IsConnOpen(serverConnection)) {
-        SSL *ssl = fd_table[serverConnection->fd].ssl;
-        assert(ssl);
-        Ssl::X509_Pointer serverCert(SSL_get_peer_certificate(ssl));
-        assert(serverCert.get() != NULL);
-        sslCommonName = Ssl::CommonHostName(serverCert.get());
-        debugs(33, 5, HERE << "HTTPS server CN: " << sslCommonName <<
-               " bumped: " << *serverConnection);
-
         pinConnection(serverConnection, NULL, NULL, false);
 
         debugs(33, 5, HERE << "bumped HTTPS server: " << sslConnectHostOrIp);
     } else {
         debugs(33, 5, HERE << "Error while bumping: " << sslConnectHostOrIp);
-        Ip::Address intendedDest;
-        intendedDest = sslConnectHostOrIp.termedBuf();
-        const bool isConnectRequest = !port->flags.isIntercepted();
-
-        // Squid serves its own error page and closes, so we want
-        // a CN that causes no additional browser errors. Possible
-        // only when bumping CONNECT with a user-typed address.
-        if (intendedDest.isAnyAddr() || isConnectRequest)
-            sslCommonName = sslConnectHostOrIp;
-        else if (sslServerBump->serverCert.get())
-            sslCommonName = Ssl::CommonHostName(sslServerBump->serverCert.get());
 
         //  copy error detail from bump-server-first request to CONNECT request
         if (currentobject != NULL && currentobject->http != NULL && currentobject->http->request)
index 1e93498778da6e5121466f5a26d6c3dc375b1a4e..7a34f33b3b5ebda7fc6f03968f3773655c382d4e 100644 (file)
@@ -380,6 +380,8 @@ public:
         else
             assert(sslServerBump == srvBump);
     }
+    const SBuf &sslCommonName() const {return sslCommonName_;}
+    void resetSslCommonName(const char *name) {sslCommonName_ = name;}
     /// Fill the certAdaptParams with the required data for certificate adaptation
     /// and create the key for storing/retrieve the certificate to/from the cache
     void buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties);
@@ -471,7 +473,7 @@ private:
     bool switchedToHttps_;
     /// The SSL server host name appears in CONNECT request or the server ip address for the intercepted requests
     String sslConnectHostOrIp; ///< The SSL server host name as passed in the CONNECT request
-    String sslCommonName; ///< CN name for SSL certificate generation
+    SBuf sslCommonName_; ///< CN name for SSL certificate generation
     String sslBumpCertKey; ///< Key to use to store/retrieve generated certificate
 
     /// HTTPS server cert. fetching state for bump-ssl-server-first
index a702ea2621158c47e212127fec126f1022cb5ea9..502939236cf710ecaf85edc78523e6447ebc1c0d 100644 (file)
@@ -1413,7 +1413,8 @@ ClientRequestContext::sslBumpAccessCheck()
     if (bumpMode != Ssl::bumpEnd) {
         debugs(85, 5, HERE << "SslBump already decided (" << bumpMode <<
                "), " << "ignoring ssl_bump for " << http->getConn());
-        http->sslBumpNeed(bumpMode); // for processRequest() to bump if needed
+        if (!http->getConn()->serverBump())
+            http->sslBumpNeed(bumpMode); // for processRequest() to bump if needed and not already bumped
         http->al->ssl.bumpMode = bumpMode; // inherited from bumped connection
         return false;
     }
index 68d9a200a9707a7a5c9872e6832d14d1cc4bc98c..8a110b84d370fe52be15345c41b302bd00fadf6b 100644 (file)
@@ -581,6 +581,11 @@ commUnsetConnTimeout(const Comm::ConnectionPointer &conn)
     return commSetConnTimeout(conn, -1, nil);
 }
 
+/**
+ * Connect socket FD to given remote address.
+ * If return value is an error flag (COMM_ERROR, ERR_CONNECT, ERR_PROTOCOL, etc.),
+ * then error code will also be returned in errno.
+ */
 int
 comm_connect_addr(int sock, const Ip::Address &address)
 {
@@ -621,7 +626,7 @@ comm_connect_addr(int sock, const Ip::Address &address)
     address.getAddrInfo(AI, F->sock_family);
 
     /* Establish connection. */
-    errno = 0;
+    int xerrno = 0;
 
     if (!F->flags.called_connect) {
         F->flags.called_connect = true;
@@ -633,10 +638,8 @@ comm_connect_addr(int sock, const Ip::Address &address)
         // Async calls development will fix this.
         if (x == 0) {
             x = -1;
-            errno = EINPROGRESS;
-        }
-
-        if (x < 0) {
+            xerrno = EINPROGRESS;
+        } else if (x < 0) {
             debugs(5,5, "comm_connect_addr: sock=" << sock << ", addrinfo( " <<
                    " flags=" << AI->ai_flags <<
                    ", family=" << AI->ai_family <<
@@ -645,30 +648,28 @@ comm_connect_addr(int sock, const Ip::Address &address)
                    ", &addr=" << AI->ai_addr <<
                    ", addrlen=" << AI->ai_addrlen <<
                    " )" );
-            debugs(5, 9, "connect FD " << sock << ": (" << x << ") " << xstrerror());
+            debugs(5, 9, "connect FD " << sock << ": (" << x << ") " << xstrerr(xerrno));
             debugs(14,9, "connecting to: " << address );
         }
+
     } else {
+        errno = 0;
 #if _SQUID_NEWSOS6_
         /* Makoto MATSUSHITA <matusita@ics.es.osaka-u.ac.jp> */
+        if (connect(sock, AI->ai_addr, AI->ai_addrlen) < 0)
+            xerrno = errno;
 
-        connect(sock, AI->ai_addr, AI->ai_addrlen);
-
-        if (errno == EINVAL) {
+        if (xerrno == EINVAL) {
             errlen = sizeof(err);
             x = getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &errlen);
-
             if (x >= 0)
-                errno = x;
+                xerrno = x;
         }
-
 #else
         errlen = sizeof(err);
-
         x = getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &errlen);
-
         if (x == 0)
-            errno = err;
+            xerrno = err;
 
 #if _SQUID_SOLARIS_
         /*
@@ -677,23 +678,24 @@ comm_connect_addr(int sock, const Ip::Address &address)
         * connect and just returns EPIPE.  Create a fake
         * error message for connect.   -- fenner@parc.xerox.com
         */
-        if (x < 0 && errno == EPIPE)
-            errno = ENOTCONN;
-
+        if (x < 0 && xerrno == EPIPE)
+            xerrno = ENOTCONN;
+        else
+            xerrno = errno;
 #endif
 #endif
-
     }
 
     Ip::Address::FreeAddr(AI);
 
     PROF_stop(comm_connect_addr);
 
-    if (errno == 0 || errno == EISCONN)
+    errno = xerrno;
+    if (xerrno == 0 || xerrno == EISCONN)
         status = Comm::OK;
-    else if (ignoreErrno(errno))
+    else if (ignoreErrno(xerrno))
         status = Comm::INPROGRESS;
-    else if (errno == EAFNOSUPPORT || errno == EINVAL)
+    else if (xerrno == EAFNOSUPPORT || xerrno == EINVAL)
         return Comm::ERR_PROTOCOL;
     else
         return Comm::COMM_ERROR;
@@ -708,6 +710,7 @@ comm_connect_addr(int sock, const Ip::Address &address)
         debugs(5, DBG_DATA, "comm_connect_addr: FD " << sock << " connection pending");
     }
 
+    errno = xerrno;
     return status;
 }
 
@@ -1894,7 +1897,7 @@ comm_open_uds(int sock_type,
     debugs(50, 5, HERE << "FD " << new_socket << " is a new socket");
 
     assert(!isOpen(new_socket));
-    fd_open(new_socket, FD_MSGHDR, NULL);
+    fd_open(new_socket, FD_MSGHDR, addr->sun_path);
 
     fdd_table[new_socket].close_file = NULL;
 
index d3c731a9c6b8b05d24a06331f48c99bb648b139e..12fb2022923c1cfc4f0bf615a02a10240c27efdf 100644 (file)
@@ -49,7 +49,7 @@
 #include <sys/epoll.h>
 #endif
 
-static int kdpfd;
+static int kdpfd = -1;
 static int max_poll_time = 1000;
 
 static struct epoll_event *pevents;
@@ -109,17 +109,13 @@ Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time
     fde *F = &fd_table[fd];
     int epoll_ctl_type = 0;
 
-    struct epoll_event ev;
     assert(fd >= 0);
     debugs(5, 5, HERE << "FD " << fd << ", type=" << type <<
            ", handler=" << handler << ", client_data=" << client_data <<
            ", timeout=" << timeout);
 
-    if (RUNNING_ON_VALGRIND) {
-        /* Keep valgrind happy.. complains about uninitialized bytes otherwise */
-        memset(&ev, 0, sizeof(ev));
-    }
-    ev.events = 0;
+    struct epoll_event ev;
+    memset(&ev, 0, sizeof(ev));
     ev.data.fd = fd;
 
     if (!F->flags.open) {
index 2e099f6ac8ff707775c644d0eca129fc078bf382..a430c7af60add10ff614885b6af3106bed70e64c 100644 (file)
@@ -12,8 +12,8 @@
 typedef enum {
     ERR_DETAIL_NONE,
     ERR_DETAIL_START = 100000, // to avoid clashes with most OS error numbers
-    ERR_DETAIL_REDIRECTOR_TIMEDOUT, // External redirector request timed-out
-    ERR_DETAIL_CLT_REQMOD_ABORT = ERR_DETAIL_START, // client-facing code detected transaction abort
+    ERR_DETAIL_REDIRECTOR_TIMEDOUT = ERR_DETAIL_START, // External redirector request timed-out
+    ERR_DETAIL_CLT_REQMOD_ABORT, // client-facing code detected transaction abort
     ERR_DETAIL_CLT_REQMOD_REQ_BODY, // client-facing code detected REQMOD request body adaptation failure
     ERR_DETAIL_CLT_REQMOD_RESP_BODY, // client-facing code detected REQMOD satisfaction reply body failure
     ERR_DETAIL_SRV_REQMOD_REQ_BODY, // server-facing code detected REQMOD request body abort
index dba17cf379ea9edf4771e9a64eeebd35fc45526b..60d0ed309d7f69b66964563e11beaf3617cf5450 100644 (file)
@@ -911,7 +911,10 @@ ErrorState::Convert(char token, bool building_deny_info_url, bool allowRecursion
     case 'm':
         if (building_deny_info_url) break;
 #if USE_AUTH
-        p = auth_user_request->denyMessage("[not available]");
+        if (auth_user_request.getRaw())
+            p = auth_user_request->denyMessage("[not available]");
+        else
+            p = "[not available]";
 #else
         p = "-";
 #endif
index 31018c61ff6c25eb1327635880ef27347ee7a9d6..f4adf142f912066d2e814d688a56c7a452d3db43 100644 (file)
--- a/src/fd.cc
+++ b/src/fd.cc
@@ -242,8 +242,7 @@ fd_open(int fd, unsigned int type, const char *desc)
 
     fdUpdateBiggest(fd, 1);
 
-    if (desc)
-        xstrncpy(F->desc, desc, FD_DESC_SZ);
+    fd_note(fd, desc);
 
     ++Number_FD;
 }
@@ -252,7 +251,10 @@ void
 fd_note(int fd, const char *s)
 {
     fde *F = &fd_table[fd];
-    xstrncpy(F->desc, s, FD_DESC_SZ);
+    if (s)
+        xstrncpy(F->desc, s, FD_DESC_SZ);
+    else
+        *(F->desc) = 0; // ""-string
 }
 
 void
index 6ef4c0aba3223150d151c03ad8469b6640160e27..17256cc78e7e24c211d822a6cf548c646b6b9361 100644 (file)
@@ -21,7 +21,7 @@ namespace Fs
 namespace Ufs
 {
 
-class RebuildState : public RefCountable
+class RebuildState
 {
     CBDATA_CLASS(RebuildState);
 
@@ -29,7 +29,7 @@ public:
     static EVH RebuildStep;
 
     RebuildState(RefCount<UFSSwapDir> sd);
-    ~RebuildState();
+    virtual ~RebuildState();
 
     virtual bool error() const;
     virtual bool isDone() const;
index e162552f3e3b038b84972573d8520beaba58a22e..de27dcc2400d70a7421150b2080cc0c1e24a2198 100644 (file)
@@ -1166,6 +1166,7 @@ HttpStateData::readReply(const CommIoCbParams &io)
      * Plus, it breaks our lame *HalfClosed() detection
      */
 
+    Must(maybeMakeSpaceAvailable(true));
     CommIoCbParams rd(this); // will be expanded with ReadNow results
     rd.conn = io.conn;
     rd.size = entry->bytesWanted(Range<size_t>(0, inBuf.spaceSize()));
@@ -1191,6 +1192,7 @@ HttpStateData::readReply(const CommIoCbParams &io)
     case Comm::INPROGRESS:
         if (inBuf.isEmpty())
             debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
+        flags.do_next_read = true;
         maybeReadVirginBody();
         return;
 
@@ -1233,16 +1235,11 @@ HttpStateData::readReply(const CommIoCbParams &io)
     // case Comm::COMM_ERROR:
     default: // no other flags should ever occur
         debugs(11, 2, io.conn << ": read failure: " << xstrerr(rd.xerrno));
-
-        if (ignoreErrno(rd.xerrno)) {
-            flags.do_next_read = true;
-        } else {
-            ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scBadGateway, fwd->request);
-            err->xerrno = rd.xerrno;
-            fwd->fail(err);
-            flags.do_next_read = false;
-            io.conn->close();
-        }
+        ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scBadGateway, fwd->request);
+        err->xerrno = rd.xerrno;
+        fwd->fail(err);
+        flags.do_next_read = false;
+        io.conn->close();
 
         return;
     }
@@ -1533,6 +1530,28 @@ HttpStateData::maybeReadVirginBody()
     if (!Comm::IsConnOpen(serverConnection) || fd_table[serverConnection->fd].closing())
         return;
 
+    if (!maybeMakeSpaceAvailable(false))
+        return;
+
+    // XXX: get rid of the do_next_read flag
+    // check for the proper reasons preventing read(2)
+    if (!flags.do_next_read)
+        return;
+
+    flags.do_next_read = false;
+
+    // must not already be waiting for read(2) ...
+    assert(!Comm::MonitorsRead(serverConnection->fd));
+
+    // wait for read(2) to be possible.
+    typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
+    AsyncCall::Pointer call = JobCallback(11, 5, Dialer, this, HttpStateData::readReply);
+    Comm::Read(serverConnection, call);
+}
+
+bool
+HttpStateData::maybeMakeSpaceAvailable(bool doGrow)
+{
     // how much we are allowed to buffer
     const int limitBuffer = (flags.headers_parsed ? Config.readAheadGap : Config.maxReplyHeaderSize);
 
@@ -1542,7 +1561,7 @@ HttpStateData::maybeReadVirginBody()
         debugs(11, DBG_DATA, "buffer has {" << inBuf << "}");
         // Process next response from buffer
         processReply();
-        return;
+        return false;
     }
 
     // how much we want to read
@@ -1550,29 +1569,20 @@ HttpStateData::maybeReadVirginBody()
 
     if (!read_size) {
         debugs(11, 7, "wont read up to " << read_size << " into buffer (" << inBuf.length() << "/" << inBuf.spaceSize() << ") from " << serverConnection);
-        return;
+        return false;
     }
 
+    // just report whether we could grow or not, dont actually do it
+    if (doGrow)
+        return (read_size >= 2);
+
     // we may need to grow the buffer
     inBuf.reserveSpace(read_size);
     debugs(11, 8, (!flags.do_next_read ? "wont" : "may") <<
            " read up to " << read_size << " bytes info buf(" << inBuf.length() << "/" << inBuf.spaceSize() <<
            ") from " << serverConnection);
 
-    // XXX: get rid of the do_next_read flag
-    // check for the proper reasons preventing read(2)
-    if (!flags.do_next_read)
-        return;
-
-    flags.do_next_read = false;
-
-    // must not already be waiting for read(2) ...
-    assert(!Comm::MonitorsRead(serverConnection->fd));
-
-    // wait for read(2) to be possible.
-    typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
-    AsyncCall::Pointer call = JobCallback(11, 5, Dialer, this, HttpStateData::readReply);
-    Comm::Read(serverConnection, call);
+    return (inBuf.spaceSize() >= 2); // only read if there is 1+ bytes of space available
 }
 
 /// called after writing the very last request byte (body, last-chunk, etc)
index b3fa6ebb613c72aa0d3b8bbe55c73b9a43118e20..53f5f60d50304f30931fa158a9a3bd9930432953 100644 (file)
@@ -87,6 +87,17 @@ private:
     virtual void abortTransaction(const char *reason); // abnormal termination
     virtual bool mayReadVirginReplyBody() const;
 
+    /**
+     * determine if read buffer can have space made available
+     * for a read.
+     *
+     * \param grow  whether to actually expand the buffer
+     *
+     * \return whether the buffer can be grown to provide space
+     *         regardless of whether the grow actually happened.
+     */
+    bool maybeMakeSpaceAvailable(bool grow);
+
     // consuming request body
     virtual void handleMoreRequestBodyAvailable();
     virtual void handleRequestBodyProducerAborted();
index 7a662dafccaaf4dce9be7f5813826f39aa99f5dd..0bedf227dab1ecc1dd5fe0b82619a6a753a3eefd 100644 (file)
@@ -39,7 +39,7 @@ typedef enum {
     scNotModified = 304,
     scUseProxy = 305,
     scTemporaryRedirect = 307,
-    scPermanentRedirect = 308, /**< RFC7238 */
+    scPermanentRedirect = 308, /**< RFC7538 */
     scBadRequest = 400,
     scUnauthorized = 401,
     scPaymentRequired = 402,
index 7d74f9dd2181b815f47ab1e6ada5d019f07b9131..a3c199bbda3472e1b521f2b426ce53b2cddc83f1 100644 (file)
@@ -107,7 +107,8 @@ Http::One::Parser::getHeaderField(const char *name)
     static const SBuf crlf("\r\n");
 
     while (tok.prefix(p, iso8859Line)) {
-        tok.skipOne(CharacterSet::LF); // move tokenizer past the LF
+        if (!tok.skipOne(CharacterSet::LF)) // move tokenizer past the LF
+            break; // error. reached invalid octet or end of buffer insted of an LF ??
 
         // header lines must start with the name (case insensitive)
         if (p.substr(0, namelen).caseCmp(name, namelen))
index 489278624392318d22b3e1010100f67d9ebf24a9..f9356605bd2169577b6ffe9f0b4a2bcaa3d07a38 100644 (file)
@@ -29,7 +29,7 @@ namespace One {
 class ResponseParser : public Http1::Parser
 {
 public:
-    ResponseParser() : Parser(), completedStatus_(false) {}
+    ResponseParser() : Parser(), completedStatus_(false), statusCode_(Http::scNone) {}
     virtual ~ResponseParser() {}
 
     /* Http::One::Parser API */
index 4b383b9f16d381d252ef9a9373cc30173fd48938..9cdc2506fdd93305e618b2f4a5c95b5eb2f3c735 100644 (file)
@@ -96,6 +96,10 @@ accessLogLogTo(CustomLog* log, AccessLogEntry::Pointer &al, ACLChecklist * check
         if (log->aclList && checklist && checklist->fastCheck(log->aclList) != ACCESS_ALLOWED)
             continue;
 
+        // The special-case "none" type has no logfile object set
+        if (log->type == Log::Format::CLF_NONE)
+            return;
+
         if (log->logfile) {
             logfileLineStart(log->logfile);
 
@@ -131,9 +135,6 @@ accessLogLogTo(CustomLog* log, AccessLogEntry::Pointer &al, ACLChecklist * check
                 break;
 #endif
 
-            case Log::Format::CLF_NONE:
-                return; // abort!
-
             default:
                 fatalf("Unknown log format %d\n", log->type);
                 break;
index 76ee88b4f4d96442a280c9c3b68be496f8a2d6ca..724ae5fd5995f67ffb0f32fa292415277261ea23 100644 (file)
@@ -58,6 +58,7 @@
 #include "profiler/Profiler.h"
 #include "redirect.h"
 #include "refresh.h"
+#include "SBufStatsAction.h"
 #include "send-announce.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
@@ -1159,6 +1160,8 @@ mainInitialize(void)
         /* register the modules in the cache manager menus */
 
         cbdataRegisterWithCacheManager();
+        SBufStatsAction::RegisterWithCacheManager();
+
         /* These use separate calls so that the comm loops can eventually
          * coexist.
          */
@@ -1777,6 +1780,7 @@ watch_child(char *argv[])
     }
 
     writePidFile();
+    enter_suid(); // writePidFile() uses leave_suid()
 
 #if defined(_SQUID_LINUX_THREADS_)
     squid_signal(SIGQUIT, rotate_logs, 0);
@@ -1882,6 +1886,7 @@ watch_child(char *argv[])
             enter_suid();
 
             removePidFile();
+            enter_suid(); // removePidFile() uses leave_suid()
             if (TheKids.someSignaled(SIGINT) || TheKids.someSignaled(SIGTERM)) {
                 syslog(LOG_ALERT, "Exiting due to unexpected forced shutdown");
                 exit(1);
index 49fac70f7923a766c90167517f774da2c897e94f..68fcb7cafc9555ae51210aadc8ac3eaffad0528c 100644 (file)
 #if HAVE_CTYPE_H
 #include <ctype.h>
 #endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifndef INT64_MIN
-/* Native 64 bit system without strtoll() */
-#if defined(LONG_MIN) && (SIZEOF_LONG == 8)
-#define INT64_MIN LONG_MIN
-#else
-/* 32 bit system */
-#define INT64_MIN       (-9223372036854775807LL-1LL)
-#endif
-#endif
-
-#ifndef INT64_MAX
-/* Native 64 bit system without strtoll() */
-#if defined(LONG_MAX) && (SIZEOF_LONG == 8)
-#define INT64_MAX LONG_MAX
-#else
-/* 32 bit system */
-#define INT64_MAX       9223372036854775807LL
-#endif
-#endif
 
 /// convenience method: consumes up to n bytes, counts, and returns them
 SBuf
index 08a7a4704a6e326c481604356a2de2c3271ee43d..64a7cb6359406948403cdbf96b7e23b25bbe9d0f 100644 (file)
 #include "squid.h"
 
 #if HAVE_KRB5 && HAVE_GSSAPI
+#if USE_APPLE_KRB5
+#define KERBEROS_APPLE_DEPRECATED(x)
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
 
 #include "base64.h"
 #include "Debug.h"
index 05e1506769c356d70865273fb56131de51fe230e..ca738a44cb5778352a04c32ba53387b3e80e9d58 100644 (file)
@@ -954,6 +954,7 @@ ps_state::ps_state() : request (NULL),
     callback (NULL),
     callback_data (NULL),
     lastError(NULL),
+    paths(NULL),
     servers (NULL),
     first_parent_miss(),
     closest_parent_miss(),
diff --git a/src/security/EncryptorAnswer.cc b/src/security/EncryptorAnswer.cc
new file mode 100644 (file)
index 0000000..1220a6f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "comm/Connection.h"
+#include "errorpage.h"
+#include "security/EncryptorAnswer.h"
+
+Security::EncryptorAnswer::~EncryptorAnswer()
+{
+    delete error.get();
+}
+
+std::ostream &
+Security::operator <<(std::ostream &os, const Security::EncryptorAnswer &answer)
+{
+    return os << answer.conn << ", " << answer.error;
+}
+
diff --git a/src/security/EncryptorAnswer.h b/src/security/EncryptorAnswer.h
new file mode 100644 (file)
index 0000000..a943ecc
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SECURITY_ENCRYPTORANSWER_H
+#define SQUID_SECURITY_ENCRYPTORANSWER_H
+
+#include "base/CbcPointer.h"
+#include "comm/forward.h"
+
+class ErrorState;
+
+namespace Security {
+
+/// Peer encrypted connection setup results (supplied via a callback).
+/// The connection to peer was secured if and only if the error member is nil.
+class EncryptorAnswer
+{
+public:
+    ~EncryptorAnswer(); ///< deletes error if it is still set
+    Comm::ConnectionPointer conn; ///< peer connection (secured on success)
+
+    /// answer recepients must clear the error member in order to keep its info
+    /// XXX: We should refcount ErrorState instead of cbdata-protecting it.
+    CbcPointer<ErrorState> error; ///< problem details (nil on success)
+};
+
+std::ostream &operator <<(std::ostream &, const Security::EncryptorAnswer &);
+
+} // namepace Security
+
+#endif /* SQUID_SECURITY_ENCRYPTORANSWER_H */
+
index 9292a5a5fda5d8ce5310a2be2bbb03e17ae2b522..b483e8a2fb6a16ad2348a8fd8adec0576b0bd990 100644 (file)
@@ -12,5 +12,8 @@ noinst_LTLIBRARIES = libsecurity.la
 
 libsecurity_la_SOURCES= \
        Context.h \
+       EncryptorAnswer.cc \
+       EncryptorAnswer.h \
+       forward.h \
        PeerOptions.cc \
        PeerOptions.h
index 6e206ff623ac06e2e5a56f33ac9a4db33ca84201..c88732f512a22a93b89c0163a05af59299d06c08 100644 (file)
@@ -11,7 +11,7 @@
 
 #include "ConfigParser.h"
 #include "SBuf.h"
-#include "security/Context.h"
+#include "security/forward.h"
 
 namespace Security
 {
@@ -20,7 +20,7 @@ namespace Security
 class PeerOptions
 {
 public:
-    PeerOptions() : sslVersion(0), encryptTransport(false) {}
+    PeerOptions() : parsedOptions(0), sslVersion(0), encryptTransport(false) {}
 
     /// parse a TLS squid.conf option
     void parse(const char *);
diff --git a/src/security/forward.h b/src/security/forward.h
new file mode 100644 (file)
index 0000000..c686bce
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SRC_SECURITY_FORWARD_H
+#define SQUID_SRC_SECURITY_FORWARD_H
+
+#include "security/Context.h"
+
+/// Network/connection security abstraction layer
+namespace Security
+{
+
+class EncryptorAnswer;
+class PeerOptions;
+
+} // namespace Security
+
+#endif /* SQUID_SRC_SECURITY_FORWARD_H */
+
index fb218be9ba1a766f72c890adf55c5937e0c42dc4..9ea15253560f09a85ce097d1145b1239aa7dfcc4 100644 (file)
@@ -45,7 +45,9 @@ Ssl::PeerConnector::PeerConnector(
     callback(aCallback),
     negotiationTimeout(timeout),
     startTime(squid_curtime),
-    splice(false)
+    splice(false),
+    resumingSession(false),
+    serverCertificateHandled(false)
 {
     // if this throws, the caller's cb dialer is not our CbDialer
     Must(dynamic_cast<CbDialer*>(callback->getDialer()));
@@ -134,8 +136,8 @@ Ssl::PeerConnector::initializeSsl()
         assert(!peer->secure.sslDomain.isEmpty());
 
         // const loss is okay here, ssl_ex_index_server is only read and not assigned a destructor
-        const char *host = const_cast<SBuf*>(&peer->secure.sslDomain)->c_str();
-        SSL_set_ex_data(ssl, ssl_ex_index_server, const_cast<char*>(host));
+        SBuf *host = new SBuf(peer->secure.sslDomain);
+        SSL_set_ex_data(ssl, ssl_ex_index_server, host);
 
         if (peer->sslSession)
             SSL_set_session(ssl, peer->sslSession);
@@ -143,16 +145,19 @@ Ssl::PeerConnector::initializeSsl()
         // client connection is required in the case we need to splice
         // or terminate client and server connections
         assert(clientConn != NULL);
-        const char *hostName = NULL;
+        SBuf *hostName = NULL;
         Ssl::ClientBio *cltBio = NULL;
 
+        //Enable Status_request tls extension, required to bump some clients
+        SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
+
         // In server-first bumping mode, clientSsl is NULL.
         if (SSL *clientSsl = fd_table[clientConn->fd].ssl) {
             BIO *b = SSL_get_rbio(clientSsl);
             cltBio = static_cast<Ssl::ClientBio *>(b->ptr);
             const Ssl::Bio::sslFeatures &features = cltBio->getFeatures();
             if (!features.serverName.isEmpty())
-                hostName = features.serverName.c_str();
+                hostName = new SBuf(features.serverName);
         }
 
         if (!hostName) {
@@ -161,7 +166,7 @@ Ssl::PeerConnector::initializeSsl()
             // unless it was the CONNECT request with a user-typed address.
             const bool isConnectRequest = !csd->port->flags.isIntercepted();
             if (!request->flags.sslPeek || isConnectRequest)
-                hostName = request->GetHost();
+                hostName = new SBuf(request->GetHost());
         }
 
         if (hostName)
@@ -172,7 +177,7 @@ Ssl::PeerConnector::initializeSsl()
             assert(cltBio);
             const Ssl::Bio::sslFeatures &features = cltBio->getFeatures();
             if (features.sslVersion != -1) {
-                features.applyToSSL(ssl);
+                features.applyToSSL(ssl, csd->sslBumpMode);
                 // Should we allow it for all protocols?
                 if (features.sslVersion >= 3) {
                     BIO *b = SSL_get_rbio(ssl);
@@ -189,7 +194,7 @@ Ssl::PeerConnector::initializeSsl()
 
             // Use SNI TLS extension only when we connect directly
             // to the origin server and we know the server host name.
-            const char *sniServer = hostName ? hostName :
+            const char *sniServer = hostName ? hostName->c_str() :
                                     (!request->GetHostIsNumeric() ? request->GetHost() : NULL);
             if (sniServer)
                 Ssl::setClientSNI(ssl, sniServer);
@@ -259,17 +264,47 @@ Ssl::PeerConnector::negotiateSsl()
     callBack();
 }
 
+void
+Ssl::PeerConnector::handleServerCertificate()
+{
+    if (serverCertificateHandled)
+        return;
+
+    if (ConnStateData *csd = request->clientConnectionManager.valid()) {
+        const int fd = serverConnection()->fd;
+        SSL *ssl = fd_table[fd].ssl;
+        Ssl::X509_Pointer serverCert(SSL_get_peer_certificate(ssl));
+        if (!serverCert.get())
+            return;
+
+        serverCertificateHandled = true;
+
+        csd->resetSslCommonName(Ssl::CommonHostName(serverCert.get()));
+        debugs(83, 5, "HTTPS server CN: " << csd->sslCommonName() <<
+               " bumped: " << *serverConnection());
+
+        // remember the server certificate for later use
+        if (Ssl::ServerBump *serverBump = csd->serverBump()) {
+            serverBump->serverCert.reset(serverCert.release());
+        }
+    }
+}
+
 bool
 Ssl::PeerConnector::sslFinalized()
 {
     const int fd = serverConnection()->fd;
     SSL *ssl = fd_table[fd].ssl;
 
-    if (request->clientConnectionManager.valid()) {
-        // remember the server certificate from the ErrorDetail object
-        if (Ssl::ServerBump *serverBump = request->clientConnectionManager->serverBump()) {
-            serverBump->serverCert.reset(SSL_get_peer_certificate(ssl));
+    // In the case the session is resuming, the certificates does not exist and
+    // we did not do any cert validation
+    if (resumingSession)
+        return true;
 
+    handleServerCertificate();
+
+    if (ConnStateData *csd = request->clientConnectionManager.valid()) {
+        if (Ssl::ServerBump *serverBump = csd->serverBump()) {
             // remember validation errors, if any
             if (Ssl::CertErrors *errs = static_cast<Ssl::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors)))
                 serverBump->sslErrors = cbdataReference(errs);
@@ -323,16 +358,15 @@ Ssl::PeerConnector::cbCheckForPeekAndSpliceDone(allow_t answer, void *data)
 void
 Ssl::PeerConnector::checkForPeekAndSplice()
 {
-    SSL *ssl = fd_table[serverConn->fd].ssl;
     // Mark Step3 of bumping
     if (request->clientConnectionManager.valid()) {
         if (Ssl::ServerBump *serverBump = request->clientConnectionManager->serverBump()) {
             serverBump->step = Ssl::bumpStep3;
-            if (!serverBump->serverCert.get())
-                serverBump->serverCert.reset(SSL_get_peer_certificate(ssl));
         }
     }
 
+    handleServerCertificate();
+
     ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(
         ::Config.accessList.ssl_bump,
         request.getRaw(), NULL);
@@ -532,7 +566,7 @@ Ssl::PeerConnector::handleNegotiateError(const int ret)
         return;
 
     case SSL_ERROR_WANT_WRITE:
-        if ((request->clientConnectionManager->sslBumpMode == Ssl::bumpPeek || request->clientConnectionManager->sslBumpMode == Ssl::bumpStare) && srvBio->holdWrite()) {
+        if ((srvBio->bumpMode() == Ssl::bumpPeek || srvBio->bumpMode() == Ssl::bumpStare) && srvBio->holdWrite()) {
             debugs(81, DBG_IMPORTANT, "hold write on SSL connection on FD " << fd);
             checkForPeekAndSplice();
             return;
@@ -544,6 +578,19 @@ Ssl::PeerConnector::handleNegotiateError(const int ret)
     case SSL_ERROR_SYSCALL:
         ssl_lib_error = ERR_get_error();
 
+        // In Peek mode, the ClientHello message sent to the server. If the
+        // server resuming a previous (spliced) SSL session with the client,
+        // then probably we are here because local SSL object does not know
+        // anything about the session being resumed.
+        //
+        if (srvBio->bumpMode() == Ssl::bumpPeek && (resumingSession = srvBio->resumingSession())) {
+            // we currently splice all resumed sessions unconditionally
+            if (const bool spliceResumed = true) {
+                checkForPeekAndSpliceDone(Ssl::bumpSplice);
+                return;
+            } // else fall through to find a matching ssl_bump action (with limited info)
+        }
+
         // If we are in peek-and-splice mode and still we did not write to
         // server yet, try to see if we should splice.
         // In this case the connection can be saved.
@@ -555,11 +602,13 @@ Ssl::PeerConnector::handleNegotiateError(const int ret)
         // unsupported server Hello message (TODO: make configurable).
 #if 1
         if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) &&
-                SSL_get_peer_certificate(ssl) &&
-                (request->clientConnectionManager->sslBumpMode == Ssl::bumpPeek  || request->clientConnectionManager->sslBumpMode == Ssl::bumpStare) && srvBio->holdWrite()) {
-            debugs(81, 3, "Error ("  << ERR_error_string(ssl_lib_error, NULL) <<  ") but, hold write on SSL connection on FD " << fd);
-            checkForPeekAndSplice();
-            return;
+                (srvBio->bumpMode() == Ssl::bumpPeek  || srvBio->bumpMode() == Ssl::bumpStare) && srvBio->holdWrite()) {
+            Ssl::X509_Pointer serverCert(SSL_get_peer_certificate(ssl));
+            if (serverCert.get()) {
+                debugs(81, 3, "Error ("  << ERR_error_string(ssl_lib_error, NULL) <<  ") but, hold write on SSL connection on FD " << fd);
+                checkForPeekAndSplice();
+                return;
+            }
         }
 #endif
 
@@ -696,16 +745,3 @@ Ssl::PeerConnector::status() const
     return buf.content();
 }
 
-/* PeerConnectorAnswer */
-
-Ssl::PeerConnectorAnswer::~PeerConnectorAnswer()
-{
-    delete error.get();
-}
-
-std::ostream &
-Ssl::operator <<(std::ostream &os, const Ssl::PeerConnectorAnswer &answer)
-{
-    return os << answer.conn << ", " << answer.error;
-}
-
index 005dde9ded9e39acf24f56481bdd14959c8dc910..75b76855ebd0e1a860191ff44fba1e6dbf851388 100644 (file)
@@ -12,6 +12,7 @@
 #include "acl/Acl.h"
 #include "base/AsyncCbdataCalls.h"
 #include "base/AsyncJob.h"
+#include "security/EncryptorAnswer.h"
 #include "ssl/support.h"
 #include <iosfwd>
 
@@ -24,19 +25,6 @@ namespace Ssl
 class ErrorDetail;
 class CertValidationResponse;
 
-/// PeerConnector results (supplied via a callback).
-/// The connection to peer was secured if and only if the error member is nil.
-class PeerConnectorAnswer
-{
-public:
-    ~PeerConnectorAnswer(); ///< deletes error if it is still set
-    Comm::ConnectionPointer conn; ///< peer connection (secured on success)
-
-    /// answer recepients must clear the error member in order to keep its info
-    /// XXX: We should refcount ErrorState instead of cbdata-protecting it.
-    CbcPointer<ErrorState> error; ///< problem details (nil on success)
-};
-
 /**
  \par
  * Connects Squid client-side to an SSL peer (cache_peer ... ssl).
@@ -44,7 +32,7 @@ public:
  * Used by TunnelStateData, FwdState, and PeerPoolMgr to start talking to an
  * SSL peer.
  \par
- * The caller receives a call back with PeerConnectorAnswer. If answer.error
+ * The caller receives a call back with Security::EncryptorAnswer. If answer.error
  * is not nil, then there was an error and the SSL connection to the SSL peer
  * was not fully established. The error object is suitable for error response
  * generation.
@@ -78,7 +66,7 @@ public:
     public:
         virtual ~CbDialer() {}
         /// gives PeerConnector access to the in-dialer answer
-        virtual PeerConnectorAnswer &answer() = 0;
+        virtual Security::EncryptorAnswer &answer() = 0;
     };
 
     typedef RefCount<HttpRequest> HttpRequestPointer;
@@ -156,6 +144,10 @@ private:
     /// Check SSL errors returned from cert validator against sslproxy_cert_error access list
     Ssl::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&);
 
+    /// Updates associated client connection manager members
+    /// if the server certificate was received from the server.
+    void handleServerCertificate();
+
     /// Callback function called when squid receive message from cert validator helper
     static void sslCrtvdHandleReplyWrapper(void *data, Ssl::CertValidationResponse const &);
 
@@ -173,10 +165,10 @@ private:
     time_t negotiationTimeout; ///< the ssl connection timeout to use
     time_t startTime; ///< when the peer connector negotiation started
     bool splice; ///< Whether we are going to splice or not
+    bool resumingSession; ///< whether it is an SSL resuming session connection
+    bool serverCertificateHandled; ///< whether handleServerCertificate() succeeded
 };
 
-std::ostream &operator <<(std::ostream &os, const Ssl::PeerConnectorAnswer &a);
-
 } // namespace Ssl
 
 #endif /* SQUID_PEER_CONNECTOR_H */
index a880278dce6f36cdf6dbc939a5fa91e9e2e7b1d2..788c5db18f44b227fd123776b08f3703481d9883 100644 (file)
@@ -150,12 +150,12 @@ Ssl::Bio::stateChanged(const SSL *ssl, int where, int ret)
 bool
 Ssl::ClientBio::isClientHello(int state)
 {
-    return (state == SSL2_ST_GET_CLIENT_HELLO_A ||
-            state == SSL3_ST_SR_CLNT_HELLO_A ||
-            state == SSL23_ST_SR_CLNT_HELLO_A ||
-            state == SSL23_ST_SR_CLNT_HELLO_B ||
-            state == SSL3_ST_SR_CLNT_HELLO_B ||
-            state == SSL3_ST_SR_CLNT_HELLO_C
+    return (
+               state == SSL3_ST_SR_CLNT_HELLO_A ||
+               state == SSL23_ST_SR_CLNT_HELLO_A ||
+               state == SSL23_ST_SR_CLNT_HELLO_B ||
+               state == SSL3_ST_SR_CLNT_HELLO_B ||
+               state == SSL3_ST_SR_CLNT_HELLO_C
            );
 }
 
@@ -209,28 +209,12 @@ Ssl::ClientBio::read(char *buf, int size, BIO *table)
     }
 
     if (helloState == atHelloNone) {
-
-        const unsigned char *head = (const unsigned char *)rbuf.content();
-        const char *s = objToString(head, rbuf.contentSize());
-        debugs(83, 7, "SSL Header: " << s);
-        if (rbuf.contentSize() < 5) {
+        helloSize = features.parseMsgHead(rbuf);
+        if (helloSize == 0) {
+            // Not enough bytes to get hello message size
             BIO_set_retry_read(table);
-            return 0;
-        }
-
-        if (head[0] == 0x16) {
-            debugs(83, 7, "SSL version 3 handshake message");
-            helloSize = (head[3] << 8) + head[4];
-            debugs(83, 7, "SSL Header Size: " << helloSize);
-            helloSize +=5;
-#if defined(DO_SSLV23)
-        } else if ((head[0] & 0x80) && head[2] == 0x01 && head[3] == 0x03) {
-            debugs(83, 7, "SSL version 2 handshake message with v3 support");
-            helloSize = head[1];
-            helloSize +=5;
-#endif
-        } else {
-            debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
+            return -1;
+        } else if (helloSize < 0) {
             wrongProtocol = true;
             return -1;
         }
@@ -247,7 +231,7 @@ Ssl::ClientBio::read(char *buf, int size, BIO *table)
             BIO_set_retry_read(table);
             return -1;
         }
-        features.get((const unsigned char *)rbuf.content());
+        features.get(rbuf);
         helloState = atHelloReceived;
     }
 
@@ -279,17 +263,7 @@ Ssl::ServerBio::stateChanged(const SSL *ssl, int where, int ret)
 void
 Ssl::ServerBio::setClientFeatures(const Ssl::Bio::sslFeatures &features)
 {
-    clientFeatures.sslVersion = features.sslVersion;
-    clientFeatures.compressMethod = features.compressMethod;
-    clientFeatures.serverName = features.serverName;
-    clientFeatures.clientRequestedCiphers = features.clientRequestedCiphers;
-    clientFeatures.unknownCiphers = features.unknownCiphers;
-    memcpy(clientFeatures.client_random, features.client_random, SSL3_RANDOM_SIZE);
-    clientFeatures.helloMessage.clear();
-    clientFeatures.helloMessage.append(features.helloMessage.rawContent(), features.helloMessage.length());
-    clientFeatures.doHeartBeats = features.doHeartBeats;
-    clientFeatures.extensions = features.extensions;
-    featuresSet = true;
+    clientFeatures = features;
 };
 
 int
@@ -325,7 +299,12 @@ adjustSSL(SSL *ssl, Ssl::Bio::sslFeatures &features)
 
     // If the client supports compression but our context does not support
     // we can not adjust.
-    if (features.compressMethod && ssl->ctx->comp_methods == NULL) {
+#if !defined(OPENSSL_NO_COMP)
+    const bool requireCompression = (features.compressMethod && ssl->ctx->comp_methods == NULL);
+#else
+    const bool requireCompression = features.compressMethod;
+#endif
+    if (requireCompression) {
         debugs(83, 5, "Client Hello Data supports compression, but we do not!");
         return false;
     }
@@ -454,7 +433,7 @@ Ssl::ServerBio::write(const char *buf, int size, BIO *table)
             assert(helloMsg.isEmpty());
 
             SSL *ssl = fd_table[fd_].ssl;
-            if (featuresSet && ssl) {
+            if (clientFeatures.initialized_ && ssl) {
                 if (bumpMode_ == Ssl::bumpPeek) {
                     if (adjustSSL(ssl, clientFeatures))
                         allowBump = true;
@@ -515,6 +494,24 @@ Ssl::ServerBio::flush(BIO *table)
     }
 }
 
+bool
+Ssl::ServerBio::resumingSession()
+{
+    if (!serverFeatures.initialized_)
+        serverFeatures.get(rbuf, false);
+
+    if (!clientFeatures.sessionId.isEmpty() && !serverFeatures.sessionId.isEmpty())
+        return clientFeatures.sessionId == serverFeatures.sessionId;
+
+    // is this a session resuming attempt using TLS tickets?
+    if (clientFeatures.hasTlsTicket &&
+            serverFeatures.tlsTicketsExtension &&
+            serverFeatures.hasCcsOrNst)
+        return true;
+
+    return false;
+}
+
 /// initializes BIO table after allocation
 static int
 squid_bio_create(BIO *bi)
@@ -634,7 +631,7 @@ squid_ssl_info(const SSL *ssl, int where, int ret)
     }
 }
 
-Ssl::Bio::sslFeatures::sslFeatures(): sslVersion(-1), compressMethod(-1), unknownCiphers(false), doHeartBeats(true)
+Ssl::Bio::sslFeatures::sslFeatures(): sslVersion(-1), compressMethod(-1), helloMsgSize(0), unknownCiphers(false), doHeartBeats(true), tlsTicketsExtension(false), hasTlsTicket(false), tlsStatusRequest(false), hasCcsOrNst(false), initialized_(false)
 {
     memset(client_random, 0, SSL3_RANDOM_SIZE);
 }
@@ -669,9 +666,11 @@ Ssl::Bio::sslFeatures::get(const SSL *ssl)
     debugs(83, 7, "SNI server name: " << serverName);
 #endif
 
+#if !defined(OPENSSL_NO_COMP)
     if (ssl->session->compress_meth)
         compressMethod = ssl->session->compress_meth;
     else if (sslVersion >= 3) //if it is 3 or newer version then compression is disabled
+#endif
         compressMethod = 0;
     debugs(83, 7, "SSL compression: " << compressMethod);
 
@@ -741,38 +740,225 @@ Ssl::Bio::sslFeatures::get(const SSL *ssl)
         opaquePrf = objToString(p, len);
     }
 #endif
+    initialized_ = true;
     return true;
 }
 
+int
+Ssl::Bio::sslFeatures::parseMsgHead(const MemBuf &buf)
+{
+    const unsigned char *head = (const unsigned char *)buf.content();
+    const char *s = objToString(head, buf.contentSize());
+    debugs(83, 7, "SSL Header: " << s);
+    if (buf.contentSize() < 5)
+        return 0;
+
+    if (helloMsgSize > 0)
+        return helloMsgSize;
+
+    // Check for SSLPlaintext/TLSPlaintext record
+    // RFC6101 section 5.2.1
+    // RFC5246 section 6.2.1
+    if (head[0] == 0x16) {
+        debugs(83, 7, "SSL version 3 handshake message");
+        // The SSL version exist in the 2nd and 3rd bytes
+        sslVersion = (head[1] << 8) | head[2];
+        debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
+        // The hello message size exist in 4th and 5th bytes
+        helloMsgSize = (head[3] << 8) + head[4];
+        debugs(83, 7, "SSL Header Size: " << helloMsgSize);
+        helloMsgSize +=5;
+#if defined(DO_SSLV23)
+    } else if ((head[0] & 0x80) && head[2] == 0x01 && head[3] == 0x03) {
+        debugs(83, 7, "SSL version 2 handshake message with v3 support");
+        sslVersion = (hello[3] << 8) | hello[4];
+        debugs(83, 7, "SSL Version :" << std::hex << std::setw(8) << std::setfill('0') << sslVersion);
+        // The hello message size exist in 2nd byte
+        helloMsgSize = head[1];
+        helloMsgSize +=2;
+#endif
+    } else {
+        debugs(83, 7, "Not an SSL acceptable handshake message (SSLv2 message?)");
+        return (helloMsgSize = -1);
+    }
+
+    // Set object as initialized. Even if we did not full parsing yet
+    // The basic features, like the SSL version is set
+    initialized_ = true;
+    return helloMsgSize;
+}
+
 bool
-Ssl::Bio::sslFeatures::get(const unsigned char *hello)
+Ssl::Bio::sslFeatures::checkForCcsOrNst(const unsigned char *msg, size_t size)
 {
-    // The SSL handshake message should starts with a 0x16 byte
-    if (hello[0] == 0x16) {
-        return parseV3Hello(hello);
+    while (size > 5) {
+        const int msgType = msg[0];
+        const int msgSslVersion = (msg[1] << 8) | msg[2];
+        debugs(83, 7, "SSL Message Version :" << std::hex << std::setw(8) << std::setfill('0') << msgSslVersion);
+        // Check for Change Cipher Spec message
+        // RFC5246 section 6.2.1
+        if (msgType == 0x14) {// Change Cipher Spec message found
+            debugs(83, 7, "SSL  Change Cipher Spec message found");
+            return true;
+        }
+        // Check for New Session Ticket message
+        // RFC5077 section 3.3
+        if (msgType == 0x04) {// New Session Ticket message found
+            debugs(83, 7, "TLS  New Session Ticket message found");
+            return true;
+        }
+        // The hello message size exist in 4th and 5th bytes
+        size_t msgLength = (msg[3] << 8) + msg[4];
+        debugs(83, 7, "SSL Message Size: " << msgLength);
+        msgLength += 5;
+
+        if (msgLength <= size) {
+            msg += msgLength;
+            size -= msgLength;
+        } else
+            size = 0;
+    }
+    return false;
+}
+
+bool
+Ssl::Bio::sslFeatures::get(const MemBuf &buf, bool record)
+{
+    int msgSize;
+    if ((msgSize = parseMsgHead(buf)) <= 0) {
+        debugs(83, 7, "Not a known SSL handshake message");
+        return false;
+    }
+
+    if (msgSize > buf.contentSize()) {
+        debugs(83, 2, "Partial SSL handshake message, can not parse!");
+        return false;
+    }
+
+    if (record) {
+        helloMessage.clear();
+        helloMessage.append(buf.content(), buf.contentSize());
+    }
+
+    const unsigned char *msg = (const unsigned char *)buf.content();
 #if defined(DO_SSLV23)
-    } else if ((hello[0] & 0x80) && hello[2] == 0x01 && hello[3] == 0x03) {
-        return parseV23Hello(hello);
+    if (msg[0] & 0x80)
+        return parseV23Hello(msg, (size_t)msgSize);
+    else
 #endif
+    {
+        // Hello messages require 5 bytes header + 1 byte Msg type + 3 bytes for Msg size
+        if (buf.contentSize() < 9)
+            return false;
+
+        // Check for the Handshake/Message type
+        // The type 2 is a ServerHello, the type 1 is a ClientHello
+        // RFC5246 section 7.4
+        if (msg[5] == 0x2) { // ServerHello message
+            if (parseV3ServerHello(msg, (size_t)msgSize)) {
+                hasCcsOrNst = checkForCcsOrNst(msg + msgSize,  buf.contentSize() - msgSize);
+                return true;
+            }
+        } else if (msg[5] == 0x1) // ClientHello message,
+            return parseV3Hello(msg, (size_t)msgSize);
     }
 
-    debugs(83, 7, "Not a known SSL handshake message");
     return false;
 }
 
 bool
-Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *hello)
+Ssl::Bio::sslFeatures::parseV3ServerHello(const unsigned char *hello, size_t size)
 {
-    debugs(83, 7, "Get fake features from v3 hello message.");
-    // The SSL version exist in the 2nd and 3rd bytes
-    sslVersion = (hello[1] << 8) | hello[2];
-    debugs(83, 7, "Get fake features. Version :" << std::hex << std::setw(8) << std::setfill('0')<< sslVersion);
+    // Parse a ServerHello Handshake message
+    // RFC5246 section 7.4, 7.4.1.3
+    // The ServerHello starts at hello+5
+    const size_t helloSize = (hello[6] << 16) | (hello[7] << 8) | hello[8];
+    debugs(83, 7, "ServerHello message size: " << helloSize);
+    // helloSize should be msgSize + hello Header (4 bytes)
+    if (helloSize + 4 > size) {
+        debugs(83, 2, "ServerHello parse error");
+        return false;
+    }
+
+    // helloSize should be at least 38 bytes long:
+    // (SSL Version + Random + SessionId Length + Cipher Suite + Compression Method)
+    if (helloSize < 38) {
+        debugs(83, 2, "Too short ServerHello message");
+        return false;
+    }
+
+    debugs(83, 7, "Get fake features from v3 ServerHello message.");
+    // Get the correct version of the sub-hello message
+    sslVersion = (hello[9] << 8) | hello[10];
+    // At the position 43 (MsgHeader(5 bytes) + HelloHeader (6bytes) + SSL3_RANDOM_SIZE (32bytes))
+    const size_t sessIdLen = (size_t)hello[43];
+    debugs(83, 7, "Session ID Length: " <<  sessIdLen);
+
+    // The size should be enough to hold at least the following
+    // 5 MsgHelloHeader + 4 (hello header)
+    // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
+    // + sessIdLength + 2 (cipher suite) + 1 (compression method)
+    // = 47 + sessIdLength
+    if (47 + sessIdLen > size) {
+        debugs(83, 2, "ciphers length parse error");
+        return false;
+    }
+
+    // The sessionID stored at 44 position, after sessionID length field
+    sessionId.assign((const char *)(hello + 44), sessIdLen);
+
+    // Check if there are extensions in hello message
+    // RFC5246 section 7.4.1.4
+    if (size > 47 + sessIdLen + 2) {
+        // 47 + sessIdLen
+        const unsigned char *pToExtensions = hello + 47 + sessIdLen;
+        const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
+        // Check if the hello size can hold extensions
+        if (47 + 2 + sessIdLen + extensionsLen > size ) {
+            debugs(83, 2, "Extensions length parse error");
+            return false;
+        }
+
+        pToExtensions += 2;
+        const unsigned char *ext = pToExtensions;
+        while (ext + 4 <= pToExtensions + extensionsLen) {
+            const short extType = (ext[0] << 8) | ext[1];
+            ext += 2;
+            const short extLen = (ext[0] << 8) | ext[1];
+            ext += 2;
+            debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
+            // SessionTicket TLS Extension, RFC5077 section 3.2
+            if (extType == 0x23) {
+                tlsTicketsExtension = true;
+            }
+            ext += extLen;
+        }
+    }
+    return true;
+}
+
+bool
+Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *hello, size_t size)
+{
+    // Parse a ClientHello Handshake message
+    // RFC5246 section 7.4, 7.4.1.2
+    // The ClientHello starts at hello+5
+
+    debugs(83, 7, "Get fake features from v3 ClientHello message.");
+    const size_t helloSize = (hello[6] << 16) | (hello[7] << 8) | hello[8];
+    debugs(83, 7, "ClientHello message size: " << helloSize);
+    // helloSize should be size + hello Header (4 bytes)
+    if (helloSize + 4 > size) {
+        debugs(83, 2, "ClientHello parse error");
+        return false;
+    }
 
-    // The following hello message size exist in 4th and 5th bytes
-    int helloSize = (hello[3] << 8) | hello[4];
-    helloSize += 5; //Include the 5 header bytes.
-    helloMessage.clear();
-    helloMessage.append((const char *)hello, helloSize);
+    // helloSize should be at least 38 bytes long:
+    // (SSL Version(2) + Random(32) + SessionId Length(1) + Cipher Suite Length(2) + Compression Method Length(1))
+    if (helloSize < 38) {
+        debugs(83, 2, "Too short ClientHello message");
+        return false;
+    }
 
     //For SSLv3 or TLSv1.* protocols we can get some more informations
     if (hello[1] == 0x3 && hello[5] == 0x1 /*HELLO A message*/) {
@@ -783,18 +969,35 @@ Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *hello)
         debugs(83, 7, "Client random: " <<  objToString(client_random, SSL3_RANDOM_SIZE));
 
         // At the position 43 (11+SSL3_RANDOM_SIZE)
-        int sessIDLen = (int)hello[43];
+        const size_t sessIDLen = (size_t)hello[43];
         debugs(83, 7, "Session ID Length: " <<  sessIDLen);
 
+        // The size should be enough to hold at least the following
+        // 5 MsgHelloHeader + 4 (hello header)
+        // + 2 (SSL Version) + 32 (random) + 1 (sessionId length)
+        // + sessIdLength + 2 (cipher suite length) + 1 (compression method length)
+        // = 47 + sessIdLength
+        if (47 + sessIDLen > size)
+            return false;
+
+        // The sessionID stored art 44 position, after sessionID length field
+        sessionId.assign((const char *)(hello + 44), sessIDLen);
+
         //Ciphers list. It is stored after the Session ID.
+        // It is a variable-length vector(RFC5246 section 4.3)
         const unsigned char *ciphers = hello + 44 + sessIDLen;
-        int ciphersLen = (ciphers[0] << 8) | ciphers[1];
+        const size_t ciphersLen = (ciphers[0] << 8) | ciphers[1];
+        if (47 + sessIDLen + ciphersLen > size) {
+            debugs(83, 2, "ciphers length parse error");
+            return false;
+        }
+
         ciphers += 2;
         if (ciphersLen) {
             const SSL_METHOD *method = SSLv3_method();
-            int cs = method->put_cipher_by_char(NULL, NULL);
+            const int cs = method->put_cipher_by_char(NULL, NULL);
             assert(cs > 0);
-            for (int i = 0; i < ciphersLen; i += cs) {
+            for (size_t i = 0; i < ciphersLen; i += cs) {
                 const SSL_CIPHER *c = method->get_cipher_by_char((ciphers + i));
                 if (c != NULL) {
                     if (!clientRequestedCiphers.empty())
@@ -815,27 +1018,56 @@ Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *hello)
             compressMethod = 0;
         debugs(83, 7, "SSL compression methods number: " << (int)compression[0]);
 
+        // Parse Extensions, RFC5246 section 7.4.1.4
         const unsigned char *pToExtensions = compression + 1 + (int)compression[0];
-        if (pToExtensions <  hello + helloSize) {
-            int extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
-            const unsigned char *ext = pToExtensions + 2;
-            while (ext < pToExtensions + extensionsLen) {
-                short extType = (ext[0] << 8) | ext[1];
+        if ((size_t)((pToExtensions - hello) + 2) < size) {
+            const size_t extensionsLen = (pToExtensions[0] << 8) | pToExtensions[1];
+            if ((pToExtensions - hello) + 2 + extensionsLen > size) {
+                debugs(83, 2, "Extensions length parse error");
+                return false;
+            }
+
+            pToExtensions += 2;
+            const unsigned char *ext = pToExtensions;
+            while (ext + 4 <= pToExtensions + extensionsLen) {
+                const short extType = (ext[0] << 8) | ext[1];
                 ext += 2;
-                short extLen = (ext[0] << 8) | ext[1];
+                const short extLen = (ext[0] << 8) | ext[1];
                 ext += 2;
-                debugs(83, 7, "SSL Exntension: " << std::hex << extType << " of size:" << extLen);
+                debugs(83, 7, "TLS Extension: " << std::hex << extType << " of size:" << extLen);
+
+                if (ext + extLen > pToExtensions + extensionsLen) {
+                    debugs(83, 2, "Extension " << std::hex << extType << " length parser error");
+                    return false;
+                }
+
                 //The SNI extension has the type 0 (extType == 0)
+                // RFC6066 sections 3, 10.2
                 // The two first bytes indicates the length of the SNI data (should be extLen-2)
                 // The next byte is the hostname type, it should be '0' for normal hostname (ext[2] == 0)
                 // The 3rd and 4th bytes are the length of the hostname
                 if (extType == 0 && ext[2] == 0) {
-                    int hostLen = (ext[3] << 8) | ext[4];
+                    const int hostLen = (ext[3] << 8) | ext[4];
                     serverName.assign((const char *)(ext+5), hostLen);
                     debugs(83, 7, "Found server name: " << serverName);
                 } else if (extType == 15 && ext[0] != 0) {
-                    // The heartBeats are the type 15
+                    // The heartBeats are the type 15, RFC6520
                     doHeartBeats = true;
+                } else if (extType == 0x23) {
+                    //SessionTicket TLS Extension RFC5077
+                    tlsTicketsExtension = true;
+                    if (extLen != 0)
+                        hasTlsTicket = true;
+                } else if (extType == 0x05) {
+                    // RFC6066 sections 8, 10.2
+                    tlsStatusRequest = true;
+                } else if (extType == 0x3374) {
+                    // detected TLS next protocol negotiate extension
+                } else if (extType == 0x10) {
+                    // Application-Layer Protocol Negotiation Extension, RFC7301
+                    const int listLen = (ext[0] << 8) | ext[1];
+                    if (listLen < extLen)
+                        tlsAppLayerProtoNeg.assign((const char *)(ext+5), listLen);
                 } else
                     extensions.push_back(extType);
 
@@ -847,23 +1079,19 @@ Ssl::Bio::sslFeatures::parseV3Hello(const unsigned char *hello)
 }
 
 bool
-Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello)
+Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello, size_t size)
 {
 #if defined(DO_SSLV23)
-    debugs(83, 7, "Get fake features from v23 hello message.");
-    sslVersion = (hello[3] << 8) | hello[4];
-    debugs(83, 7, "Get fake features. Version :" << std::hex << std::setw(8) << std::setfill('0')<< sslVersion);
-
-    // The following hello message size exist in 2nd byte
-    int helloSize = hello[1];
-    helloSize += 2; //Include the 2 header bytes.
-    helloMessage.clear();
-    helloMessage.append((char *)hello, helloSize);
-
+    debugs(83, 7, "Get fake features from v23 ClientHello message.");
+    if (size < 7)
+        return false;
     //Ciphers list. It is stored after the Session ID.
-
-    int ciphersLen = (hello[5] << 8) | hello[6];
+    const int ciphersLen = (hello[5] << 8) | hello[6];
     const unsigned char *ciphers = hello + 11;
+
+    if (size < ciphersLen + 11 + SSL3_RANDOM_SIZE)
+        return false;
+
     if (ciphersLen) {
         const SSL_METHOD *method = SSLv23_method();
         int cs = method->put_cipher_by_char(NULL, NULL);
@@ -897,7 +1125,7 @@ Ssl::Bio::sslFeatures::parseV23Hello(const unsigned char *hello)
 }
 
 void
-Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl) const
+Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl, Ssl::BumpMode bumpMode) const
 {
     // To increase the possibility for bumping after peek mode selection or
     // splicing after stare mode selection it is good to set the
@@ -919,12 +1147,28 @@ Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl) const
         SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
 #endif
 
+#if defined(TLSEXT_STATUSTYPE_ocsp)
+    if (tlsStatusRequest)
+        SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
+#endif
+
+#if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
+    if (!tlsAppLayerProtoNeg.isEmpty()) {
+        if (bumpMode == Ssl::bumpPeek)
+            SSL_set_alpn_protos(ssl, (const unsigned char*)tlsAppLayerProtoNeg.rawContent(), tlsAppLayerProtoNeg.length());
+        else {
+            static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
+            SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
+        }
+    }
+#endif
 }
 
 std::ostream &
 Ssl::Bio::sslFeatures::print(std::ostream &os) const
 {
     static std::string buf;
+    // TODO: Also print missing features like the HeartBeats and AppLayerProtoNeg
     return os << "v" << sslVersion <<
            " SNI:" << (serverName.isEmpty() ? SBuf("-") : serverName) <<
            " comp:" << compressMethod <<
index 0abbaa075b8d4cb2889da53f254d98ea5e0f0500..470896b9ecf132f64c64e97eed3b6fb81d3b9d9c 100644 (file)
@@ -37,18 +37,33 @@ public:
     public:
         sslFeatures();
         bool get(const SSL *ssl); ///< Retrieves the features from SSL object
-        bool get(const unsigned char *hello); ///< Retrieves the features from raw SSL hello message
-        bool parseV3Hello(const unsigned char *hello);
-        bool parseV23Hello(const unsigned char *hello);
+        /// Retrieves features from raw SSL Hello message.
+        /// \param record  whether to store Message to the helloMessage member
+        bool get(const MemBuf &, bool record = true);
+        /// Parses a v3 ClientHello message
+        bool parseV3Hello(const unsigned char *hello, size_t helloSize);
+        /// Parses a v23 ClientHello message
+        bool parseV23Hello(const unsigned char *hello, size_t helloSize);
+        /// Parses a v3 ServerHello message.
+        bool parseV3ServerHello(const unsigned char *hello, size_t helloSize);
         /// Prints to os stream a human readable form of sslFeatures object
         std::ostream & print(std::ostream &os) const;
         /// Converts to the internal squid SSL version form the sslVersion
         int toSquidSSLVersion() const;
         /// Configure the SSL object with the SSL features of the sslFeatures object
-        void applyToSSL(SSL *ssl) const;
+        void applyToSSL(SSL *ssl, Ssl::BumpMode bumpMode) const;
+        /// Parses an SSL Message header. It returns the ssl Message size.
+        /// \retval >0 if the hello size is retrieved
+        /// \retval 0 if the contents of the buffer are not enough
+        /// \retval <0 if the contents of buf are not SSLv3 or TLS hello message
+        int parseMsgHead(const MemBuf &);
+        /// Parses msg buffer and return true if one of the Change Cipher Spec
+        /// or New Session Ticket messages found
+        bool checkForCcsOrNst(const unsigned char *msg, size_t size);
     public:
         int sslVersion; ///< The requested/used SSL version
         int compressMethod; ///< The requested/used compressed  method
+        int helloMsgSize; ///< the hello message size
         mutable SBuf serverName; ///< The SNI hostname, if any
         std::string clientRequestedCiphers; ///< The client requested ciphers
         bool unknownCiphers; ///< True if one or more ciphers are unknown
@@ -56,10 +71,19 @@ public:
         std::string ellipticCurves; ///< tlsExtension ellipticCurveList
         std::string opaquePrf; ///< tlsExtension opaquePrf
         bool doHeartBeats;
+        bool tlsTicketsExtension; ///< whether TLS tickets extension is enabled
+        bool hasTlsTicket; ///< whether a TLS ticket is included
+        bool tlsStatusRequest; ///< whether the TLS status request extension is set
+        SBuf tlsAppLayerProtoNeg; ///< The value of the TLS application layer protocol extension if it is enabled
+        /// whether Change Cipher Spec message included in ServerHello
+        /// handshake message
+        bool hasCcsOrNst;
         /// The client random number
         unsigned char client_random[SSL3_RANDOM_SIZE];
+        SBuf sessionId;
         std::list<int> extensions;
         SBuf helloMessage;
+        bool initialized_;
     };
     explicit Bio(const int anFd);
     virtual ~Bio();
@@ -113,7 +137,7 @@ public:
     /// to socket and sets the "read retry" flag of the BIO to true
     virtual int read(char *buf, int size, BIO *table);
     /// Return true if the client hello message received and analized
-    bool gotHello() {return features.sslVersion != -1;}
+    bool gotHello() { return (helloState == atHelloReceived); }
     /// Return the SSL features requested by SSL client
     const Bio::sslFeatures &getFeatures() const {return features;}
     /// Prevents or allow writting on socket.
@@ -150,7 +174,7 @@ private:
 class ServerBio: public Bio
 {
 public:
-    explicit ServerBio(const int anFd): Bio(anFd), featuresSet(false), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), record_(false), bumpMode_(bumpNone) {}
+    explicit ServerBio(const int anFd): Bio(anFd), helloMsgSize(0), helloBuild(false), allowSplice(false), allowBump(false), holdWrite_(false), record_(false), bumpMode_(bumpNone) {}
     /// The ServerBio version of the Ssl::Bio::stateChanged method
     virtual void stateChanged(const SSL *ssl, int where, int ret);
     /// The ServerBio version of the Ssl::Bio::write method
@@ -167,6 +191,7 @@ public:
     /// Sets the random number to use in client SSL HELLO message
     void setClientFeatures(const sslFeatures &features);
 
+    bool resumingSession();
     /// The write hold state
     bool holdWrite() const {return holdWrite_;}
     /// Enables or disables the write hold state
@@ -179,10 +204,10 @@ public:
     bool canBump() {return allowBump;}
     /// The bumping mode
     void mode(Ssl::BumpMode m) {bumpMode_ = m;}
+    Ssl::BumpMode bumpMode() {return bumpMode_;} ///< return the bumping mode
 private:
-    /// A random number to use as "client random" in client hello message
-    sslFeatures clientFeatures;
-    bool featuresSet; ///< True if the clientFeatures member is set and can be used
+    sslFeatures clientFeatures; ///< SSL client features extracted from ClientHello message or SSL object
+    sslFeatures serverFeatures; ///< SSL server features extracted from ServerHello message
     SBuf helloMsg; ///< Used to buffer output data.
     mb_size_t  helloMsgSize;
     bool helloBuild; ///< True if the client hello message sent to the server
index 7be669f00687a320523c1989e6e180b454bd20ef..175243ce56d7d3bc8e7d59c59e0bdaec9bb2b7b6 100644 (file)
@@ -57,8 +57,10 @@ void Ssl::Lock::lock()
 
 #if _SQUID_WINDOWS_
     if (!LockFile(hFile, 0, 0, 1, 0))
-#else
+#elif _SQUID_SOLARIS_
     if (lockf(fd, F_LOCK, 0) != 0)
+#else
+    if (flock(fd, LOCK_EX) != 0)
 #endif
         throw std::runtime_error("Failed to get a lock of " + filename);
 }
@@ -73,7 +75,11 @@ void Ssl::Lock::unlock()
     }
 #else
     if (fd != -1) {
+#if _SQUID_SOLARIS_
         lockf(fd, F_ULOCK, 0);
+#else
+        flock(fd, LOCK_UN);
+#endif
         close(fd);
         fd = -1;
     }
index 41e5de6db6d51e877c3cbc578484eb63f4af5328..293e91d48f609f3e1739c659f1f6d45ce1539f43 100644 (file)
@@ -95,13 +95,14 @@ void Ssl::GlobalContextStorage::reconfigureFinish()
         reconfiguring = false;
 
         // remove or change old local storages.
-        for (std::map<Ip::Address, LocalContextStorage *>::iterator i = storage.begin(); i != storage.end(); ++i) {
+        for (std::map<Ip::Address, LocalContextStorage *>::iterator i = storage.begin(); i != storage.end();) {
             std::map<Ip::Address, size_t>::iterator conf_i = configureStorage.find(i->first);
             if (conf_i == configureStorage.end() || conf_i->second <= 0) {
                 delete i->second;
-                storage.erase(i);
+                storage.erase(i++);
             } else {
                 i->second->setMemLimit(conf_i->second);
+                ++i;
             }
         }
 
index f6c744f915bf1a77c6cadfc5d5ff59a395d1129a..f4f4a1b53505dda30e1e470829b25900cd9fa55f 100644 (file)
@@ -222,7 +222,7 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     char buffer[256] = "";
     SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
     SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
-    const char *server = (const char *)SSL_get_ex_data(ssl, ssl_ex_index_server);
+    SBuf *server = (SBuf *)SSL_get_ex_data(ssl, ssl_ex_index_server);
     void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
     ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
     X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
@@ -253,7 +253,7 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 
         // Check for domain mismatch only if the current certificate is the peer certificate.
         if (!dont_verify_domain && server && peer_cert == X509_STORE_CTX_get_current_cert(ctx)) {
-            if (!Ssl::checkX509ServerValidity(peer_cert, server)) {
+            if (!Ssl::checkX509ServerValidity(peer_cert, server->c_str())) {
                 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
                 ok = 0;
                 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
@@ -683,6 +683,15 @@ ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
     X509_free(cert);
 }
 
+// "free" function for SBuf
+static void
+ssl_free_SBuf(void *, void *ptr, CRYPTO_EX_DATA *,
+              int, long, void *)
+{
+    SBuf  *buf = static_cast <SBuf *>(ptr);
+    delete buf;
+}
+
 /// \ingroup ServerProtocolSSLInternal
 static void
 ssl_initialize(void)
@@ -716,7 +725,7 @@ ssl_initialize(void)
     if (!Ssl::DefaultSignHash)
         fatalf("Sign hash '%s' is not supported\n", defName);
 
-    ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
+    ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, ssl_free_SBuf);
     ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
     ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
     ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
@@ -1106,6 +1115,17 @@ Ssl::serverMethod(int version)
     return NULL;
 }
 
+#if defined(TLSEXT_TYPE_next_proto_neg)
+//Dummy next_proto_neg callback
+static int
+ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
+{
+    static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
+    (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
+    return SSL_TLSEXT_ERR_OK;
+}
+#endif
+
 SSL_CTX *
 sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
 {
@@ -1203,6 +1223,9 @@ sslCreateClientContext(const char *certfile, const char *keyfile, int version, c
         debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
     }
 
+#if defined(TLSEXT_TYPE_next_proto_neg)
+    SSL_CTX_set_next_proto_select_cb(sslContext, &ssl_next_proto_cb, NULL);
+#endif
     return sslContext;
 }
 
index a91e28027a19d46d6b7e87b2595d5313769cb34d..b8dabc9135ac1230f9a3e7334330516ec4787bba 100644 (file)
@@ -21,7 +21,7 @@ HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0),
     void HttpReply::packHeadersInto(Packable *) const STUB
     void HttpReply::reset() STUB
     void httpBodyPackInto(const HttpBody *, Packable *) STUB
-    bool HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
+    bool HttpReply::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
     int HttpReply::httpMsgParseError() STUB_RETVAL(0)
     bool HttpReply::expectingBody(const HttpRequestMethod&, int64_t&) const STUB_RETVAL(false)
     bool HttpReply::parseFirstLine(const char *start, const char *end) STUB_RETVAL(false)
index 9c45144062c3eaf6ce21e74995832f53787624aa..765769aaddb7e5625880940879c831c5cf4d0a22 100644 (file)
@@ -17,7 +17,7 @@ HttpRequest::HttpRequest() : HttpMsg(hoRequest) STUB
     HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aUrlpath) : HttpMsg(hoRequest) STUB
     HttpRequest::~HttpRequest() STUB
     void HttpRequest::packFirstLineInto(Packable *, bool) const STUB
-    bool HttpRequest::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
+    bool HttpRequest::sanityCheckStartLine(const char*buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
     void HttpRequest::hdrCacheInit() STUB
     void HttpRequest::reset() STUB
     bool HttpRequest::expectingBody(const HttpRequestMethod& unused, int64_t&) const STUB_RETVAL(false)
index 1e2fd20842760775f7f4492699a5c6a9783937fc..df3712c1994b80912929f08574ba20469246d743 100644 (file)
@@ -27,5 +27,5 @@ int cbdataInternalReferenceDoneValid(void **p, void **tp) STUB_RETVAL(0)
 #endif
 
 int cbdataReferenceValid(const void *p) STUB_RETVAL(0)
-cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func) STUB_RETVAL(CBDATA_UNKNOWN)
+cbdata_type cbdataInternalAddType(cbdata_type, const char *, int) STUB_RETVAL(CBDATA_UNKNOWN)
 
index 4f70cf8cf0218b0bf3181aedae69798cc5681cda..ec7903251ed75ddb3f6c91a2ab5091e3772ffb86 100644 (file)
@@ -7,10 +7,15 @@
  */
 
 #include "squid.h"
+#include "comm/Connection.h"
 
 #define STUB_API "security/libsecurity.la"
 #include "tests/STUB.h"
 
+#include "security/EncryptorAnswer.h"
+Security::EncryptorAnswer::~EncryptorAnswer() {}
+std::ostream &Security::operator <<(std::ostream &os, const Security::EncryptorAnswer &) STUB_RETVAL(os)
+
 #include "security/PeerOptions.h"
 Security::PeerOptions Security::ProxyOutgoingConfig;
 void Security::PeerOptions::parse(char const*) STUB
index a0259090369244bddac9152136d7bf334d679905..8fcd9d6d293781471affae78b693d800cabfc446 100644 (file)
@@ -50,14 +50,14 @@ testHttpReply::testSanityCheckFirstLine()
     // a valid status line
     input.append("HTTP/1.1 200 Okay\n\n", 19);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 1 && engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 1 && engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1    200  Okay     \n\n", 28);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 2 && engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 2 && engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -66,14 +66,14 @@ testHttpReply::testSanityCheckFirstLine()
     // invalid status line
     input.append("HTTP/1.1 999 Okay\n\n", 19);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 3 && !engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 3 && !engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1    2000  Okay     \n\n", 29);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 4 && engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 4 && engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -82,7 +82,7 @@ testHttpReply::testSanityCheckFirstLine()
     // valid ICY protocol status line
     input.append("ICY 200 Okay\n\n", 14);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -93,14 +93,14 @@ testHttpReply::testSanityCheckFirstLine()
     // empty status line
     input.append("\n\n", 2);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 5 && !engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 5 && !engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
 
     input.append("      \n\n", 8);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT( 6 && !engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT( 6 && !engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
@@ -108,14 +108,14 @@ testHttpReply::testSanityCheckFirstLine()
     // status line with no message
     input.append("HTTP/1.1 200\n\n", 14); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1 200 \n\n", 15); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -123,42 +123,42 @@ testHttpReply::testSanityCheckFirstLine()
     // incomplete (short) status lines... not sane (yet), but no error either.
     input.append("H", 1);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/", 5);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1", 6);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1", 8);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1 ", 9); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1    20", 14);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -166,21 +166,21 @@ testHttpReply::testSanityCheckFirstLine()
     // status line with no status
     input.append("HTTP/1.1 \n\n", 11);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1     \n\n", 15);
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
 
     input.append("HTTP/1.1  Okay\n\n", 16); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
@@ -188,7 +188,7 @@ testHttpReply::testSanityCheckFirstLine()
     // status line with nul-byte
     input.append("HTTP/1.1" "\0" "200 Okay\n\n", 19); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
@@ -196,7 +196,7 @@ testHttpReply::testSanityCheckFirstLine()
     // status line with negative status
     input.append("HTTP/1.1 -000\n\n", 15); /* real case seen */
     hdr_len = headersEnd(input.content(),input.contentSize());
-    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.sanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
index 336ae3265c9a307e27dfc942e97b1f1d2093ee0d..aacda2df555d19378e47ec490e05b59f2292ee9d 100644 (file)
@@ -22,7 +22,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest );
 class PrivateHttpRequest : public HttpRequest
 {
 public:
-    bool doSanityCheckStartLine(MemBuf *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); };
+    bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); };
 };
 
 /* init memory pools */
@@ -164,14 +164,14 @@ testHttpRequest::testSanityCheckStartLine()
     // a valid request line
     input.append("GET / HTTP/1.1\n\n", 16);
     hdr_len = headersEnd(input.content(), input.contentSize());
-    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("GET  /  HTTP/1.1\n\n", 18);
     hdr_len = headersEnd(input.content(), input.contentSize());
-    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -179,14 +179,14 @@ testHttpRequest::testSanityCheckStartLine()
     // strange but valid methods
     input.append(". / HTTP/1.1\n\n", 14);
     hdr_len = headersEnd(input.content(), input.contentSize());
-    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
 
     input.append("OPTIONS * HTTP/1.1\n\n", 20);
     hdr_len = headersEnd(input.content(), input.contentSize());
-    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scNone);
     input.reset();
     error = Http::scNone;
@@ -203,7 +203,7 @@ testHttpRequest::testSanityCheckStartLine()
 
     input.append("      \n\n", 8);
     hdr_len = headersEnd(input.content(), input.contentSize());
-    CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(&input, hdr_len, &error) );
+    CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(input.content(), hdr_len, &error) );
     CPPUNIT_ASSERT_EQUAL(error, Http::scInvalidHeader);
     input.reset();
     error = Http::scNone;
index 87f92381945a691069b723034062e32be0b64ae1..4fc715b95df1b50356c9ec35a0bcab4a3bf07da0 100644 (file)
@@ -39,6 +39,8 @@
 #include "ssl/bio.h"
 #include "ssl/PeerConnector.h"
 #include "ssl/ServerBump.h"
+#else
+#include "security/EncryptorAnswer.h"
 #endif
 #include "tools.h"
 #if USE_DELAY_POOLS
@@ -170,7 +172,7 @@ private:
     class MyAnswerDialer: public CallDialer, public Ssl::PeerConnector::CbDialer
     {
     public:
-        typedef void (TunnelStateData::*Method)(Ssl::PeerConnectorAnswer &);
+        typedef void (TunnelStateData::*Method)(Security::EncryptorAnswer &);
 
         MyAnswerDialer(Method method, TunnelStateData *tunnel):
             method_(method), tunnel_(tunnel), answer_() {}
@@ -183,17 +185,18 @@ private:
         }
 
         /* Ssl::PeerConnector::CbDialer API */
-        virtual Ssl::PeerConnectorAnswer &answer() { return answer_; }
+        virtual Security::EncryptorAnswer &answer() { return answer_; }
 
     private:
         Method method_;
         CbcPointer<TunnelStateData> tunnel_;
-        Ssl::PeerConnectorAnswer answer_;
+        Security::EncryptorAnswer answer_;
     };
-
-    void connectedToPeer(Ssl::PeerConnectorAnswer &answer);
 #endif
 
+    /// callback handler after connection setup (including any encryption)
+    void connectedToPeer(Security::EncryptorAnswer &answer);
+
 public:
     bool keepGoingAfterRead(size_t len, Comm::Flag errcode, int xerrno, Connection &from, Connection &to);
     void copy(size_t len, Connection &from, Connection &to, IOCB *);
@@ -413,7 +416,8 @@ TunnelStateData::handleConnectResponse(const size_t chunkSize)
     HttpReply rep;
     Http::StatusCode parseErr = Http::scNone;
     const bool eof = !chunkSize;
-    const bool parsed = rep.parse(connectRespBuf, eof, &parseErr);
+    connectRespBuf->terminate(); // HttpMsg::parse requires terminated string
+    const bool parsed = rep.parse(connectRespBuf->content(), connectRespBuf->contentSize(), eof, &parseErr);
     if (!parsed) {
         if (parseErr > 0) { // unrecoverable parsing error
             server.logicError("malformed CONNECT response from peer");
@@ -696,9 +700,8 @@ tunnelDelayedClientRead(void *data)
 {
     if (!data)
         return;
+
     TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
-    if (!tunnel)
-        return;
     tunnel->client.readPending = NULL;
     static uint64_t counter=0;
     debugs(26, 7, "Client read(2) delayed " << ++counter << " times");
@@ -710,9 +713,8 @@ tunnelDelayedServerRead(void *data)
 {
     if (!data)
         return;
+
     TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
-    if (!tunnel)
-        return;
     tunnel->server.readPending = NULL;
     static uint64_t counter=0;
     debugs(26, 7, "Server read(2) delayed " << ++counter << " times");
@@ -1014,29 +1016,26 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr, const
 void
 TunnelStateData::connectToPeer()
 {
-    const Comm::ConnectionPointer &srv = server.conn;
-
 #if USE_OPENSSL
-    if (CachePeer *p = srv->getPeer()) {
+    if (CachePeer *p = server.conn->getPeer()) {
         if (p->secure.encryptTransport) {
             AsyncCall::Pointer callback = asyncCall(5,4,
                                                     "TunnelStateData::ConnectedToPeer",
                                                     MyAnswerDialer(&TunnelStateData::connectedToPeer, this));
             Ssl::PeerConnector *connector =
-                new Ssl::PeerConnector(request, srv, client.conn, callback);
+                new Ssl::PeerConnector(request, server.conn, client.conn, callback);
             AsyncJob::Start(connector); // will call our callback
             return;
         }
     }
 #endif
 
-    tunnelRelayConnectRequest(srv, this);
+    Security::EncryptorAnswer nil;
+    connectedToPeer(nil);
 }
 
-#if USE_OPENSSL
-/// Ssl::PeerConnector callback
 void
-TunnelStateData::connectedToPeer(Ssl::PeerConnectorAnswer &answer)
+TunnelStateData::connectedToPeer(Security::EncryptorAnswer &answer)
 {
     if (ErrorState *error = answer.error.get()) {
         *status_ptr = error->httpStatus;
@@ -1049,7 +1048,6 @@ TunnelStateData::connectedToPeer(Ssl::PeerConnectorAnswer &answer)
 
     tunnelRelayConnectRequest(server.conn, this);
 }
-#endif
 
 static void
 tunnelRelayConnectRequest(const Comm::ConnectionPointer &srv, void *data)
index ef6c9f8994a0ee8afc6218b57995e240e0652ec8..a1efa650c1fdc26c34e3da7ab2755b4240725645 100644 (file)
@@ -683,30 +683,8 @@ urlMakeAbsolute(const HttpRequest * req, const char *relUrl)
     return (urlbuf);
 }
 
-/*
- * matchDomainName() compares a hostname with a domainname according
- * to the following rules:
- *
- *    HOST          DOMAIN        MATCH?
- * ------------- -------------    ------
- *    foo.com       foo.com         YES
- *   .foo.com       foo.com         YES
- *  x.foo.com       foo.com          NO
- *    foo.com      .foo.com         YES
- *   .foo.com      .foo.com         YES
- *  x.foo.com      .foo.com         YES
- *
- *  We strip leading dots on hosts (but not domains!) so that
- *  ".foo.com" is is always the same as "foo.com".
- *
- *  Return values:
- *     0 means the host matches the domain
- *     1 means the host is greater than the domain
- *    -1 means the host is less than the domain
- */
-
 int
-matchDomainName(const char *h, const char *d)
+matchDomainName(const char *h, const char *d, bool honorWildcards)
 {
     int dl;
     int hl;
@@ -763,6 +741,13 @@ matchDomainName(const char *h, const char *d)
     /*
      * We found different characters in the same position (from the end).
      */
+
+    // If the h has a form of "*.foo.com" and d has a form of "x.foo.com"
+    // then the h[hl] points to '*', h[hl+1] to '.' and d[dl] to 'x'
+    // The following checks are safe, the "h[hl + 1]" in the worst case is '\0'.
+    if (honorWildcards && h[hl] == '*' && h[hl + 1] == '.')
+        return 0;
+
     /*
      * If one of those character is '.' then its special.  In order
      * for splay tree sorting to work properly, "x-foo.com" must
index 7b1529c1c2b567c9a716617db29d6175b5252d7d..70fd121d2704e205a457e804b2bb9cf1ef70d347 100644 (file)
@@ -10,6 +10,9 @@
 #define _SQUID_TOOLS_SQUIDCLIENT_GSSAPI_H
 
 #if HAVE_GSSAPI
+#if USE_APPLE_KRB5
+#define GSSKRB_APPLE_DEPRECATED(x)
+#endif
 
 #if USE_HEIMDAL_KRB5
 #if HAVE_GSSAPI_GSSAPI_H