Commit Graph

3308 Commits

Author SHA1 Message Date
Willy Tarreau
1e5dfdad77 MINOR: session: only call http_send_name_header() when changing the server
Till now we used to call the function until the connection established, which
means that the header rewriting was performed for nothing upon each even (eg:
uploaded contents) until the server responded or timed out.

Now we only call the function when we assign the server.
2013-04-11 18:18:01 +02:00
Willy Tarreau
9d9179b581 BUG/MAJOR: peers: fix an overflow when syncing strings larger than 16 bytes
When syncing data between two haproxy instances, the received keys were
allocated in the stack but no room was planned for type string. So in
practice all strings of 16 or less bytes were properly handled (due to
the union with in6_addr which reserves some room), but above this some
local variables were overwritten. Up to 8 additional bytes could be
written without impact, but random behaviours are expected above, including
crashes and memory corruption.

If large enough strings are allowed in the configuration, it is possible that
code execution could be triggered when the function's return pointer is
overwritten.

A quick workaround consists in ensuring that no stick-table uses a string
larger than 16 bytes (default is 32). Another workaround is to disable peer
sync when strings are in use.

Thanks to Will Glass-Husain for bringing up this issue with a backtrace to
understand the issue.

The bug only affects 1.5-dev3 and above. No backport is needed.
2013-04-11 17:24:54 +02:00
Willy Tarreau
a7b46b50d9 MINOR: stick-table: allow to allocate an entry without filling it
By passing a NULL key to stksess_new(), we allocate it but do not yet
fill it. That way the caller can do that.
2013-04-11 17:24:53 +02:00
Willy Tarreau
72d6c16df4 CLEANUP: peers: remove a bit of spaghetti to prepare for the next bugfix
We'll need to centralize some pool_alloc()/pool_free() calls in the
upcoming fix so before that we need to reduce the number of points
by which we leave the critical code.
2013-04-11 17:24:53 +02:00
Willy Tarreau
deaec2fda3 BUG/MINOR: tcp: fix error reporting for TCP rules
tcp-request swapped two output words in the error message, making it meaningless.
2013-04-11 17:24:53 +02:00
Hiroaki Nakamura
e3cf2229ad BUG: regex: fix pcre compile error when using JIT
According to "man pcreapi", pcre_compile() does not accept being passed
a NULL pointer in errptr or erroffset. It immediately returns NULL, causing
any expression to fail. So let's pass real variables and make use of them
to improve error reporting.
2013-04-11 08:17:37 +02:00
Willy Tarreau
f75d008c45 BUG/MAJOR: acl: add implicit arguments to the resolve list
When an ACL keyword needs a mandatory argument and this argument is of
type proxy or table, it is allowed not to specify it so that current
proxy is used by default.

In order to achieve this, the ACL expression parser builds a dummy
argument from scratch and marks it unresolved.

However, since recent changes on the ACL and samples, an unresolved
argument needs to be added to the unresolved list. This specific code
did not do it, resulting in random data being used as a proxy pointer
if no argument was passed for a proxy name, possibly even causing a
crash.

A quick workaround consists explicitly naming proxies in ACLs.
2013-04-07 21:20:44 +02:00
Willy Tarreau
4fc90efed0 BUG/MEDIUM: splicing is broken since 1.5-dev12
Commit 96199b10 reintroduced the splice() mechanism in the new connection
system. However, it failed to account for the number of transferred bytes,
allowing more bytes than scheduled to be transferred to the client. This
can cause an issue with small-chunked responses, where each packet from
the server may contain several chunks, because a single splice() call may
succeed, then try to splice() a second time as the pipe is not full, thus
consuming the next chunk size.

This patch also reverts commit baf2a5 ("OPTIM: splice: detect shutdowns...")
because it introduced a related regression. The issue is that splice() may
return less data than available also if the pipe is full, so having EPOLLRDHUP
after splice() returns less than expected is not a sufficient indication that
the input is empty.

In both cases, the issue may be detected by the presence of "SD" termination
flags in the logs, and worked around by disabling splicing (using "-dS").

This problem was reported by Sander Klein, and no backport is needed.
2013-04-06 11:46:27 +02:00
Willy Tarreau
91418063c3 BUILD: mention in the Makefile that USE_PCRE_JIT is for libpcre >= 8.32
JIT was introduced in 8.20 but it's said everywhere that it was
significantly improved in 8.32. Let's not tempt users of older
versions then. BTW the patch was developped on 8.32.
2013-04-04 23:06:52 +02:00
Lukas Tribus
ea68d36e0b MINOR: show PCRE version and JIT status in -vv
haproxy -vv shows build informations about USE flags and lib versions.
This patch introduces informations about PCRE and the new JIT feature.
It also makes USE_PCRE_JIT=1 appear in the haproxy -vv "OPTIONS".

This is useful since with the introduction of JIT we will see libpcre
related issues.
2013-04-04 22:39:56 +02:00
Willy Tarreau
8d1c5164f3 BUG/MINOR: http: add-header/set-header did not accept the ACL condition
Sander Klein reported this bug. The test for the extra argument on these
rules prevent any condition from being added. The bug was introduced with
the feature itself in 1.5-dev16.
2013-04-03 14:13:58 +02:00
Willy Tarreau
289dd92a64 [RELEASE] Released version 1.5-dev18
Released version 1.5-dev18 with the following main changes :
    - DOCS: Add explanation of intermediate certs to crt paramater
    - DOC: typo and minor fixes in compression paragraph
    - MINOR: config: http-request configuration error message misses new keywords
    - DOC: minor typo fix in documentation
    - BUG/MEDIUM: ssl: ECDHE ciphers not usable without named curve configured.
    - MEDIUM: ssl: add bind-option "strict-sni"
    - MEDIUM: ssl: add mapping from SNI to cert file using "crt-list"
    - MEDIUM: regex: Use PCRE JIT in acl
    - DOC: simplify bind option "interface" explanation
    - DOC: tfo: bump required kernel to linux-3.7
    - BUILD: add explicit support for TFO with USE_TFO
    - MEDIUM: New cli option -Ds for systemd compatibility
    - MEDIUM: add haproxy-systemd-wrapper
    - MEDIUM: add systemd service
    - BUG/MEDIUM: systemd-wrapper: don't leak zombie processes
    - BUG/MEDIUM: remove supplementary groups when changing gid
    - BUG/MEDIUM: config: fix parser crash with bad bind or server address
    - BUG/MINOR: Correct logic in cut_crlf()
    - CLEANUP: checks: Make desc argument to set_server_check_status const
    - CLEANUP: dumpstats: Make cli_release_handler() static
    - MEDIUM: server: Break out set weight processing code
    - MEDIUM: server: Allow relative weights greater than 100%
    - MEDIUM: server: Tighten up parsing of weight string
    - MEDIUM: checks: Add agent health check
    - BUG/MEDIUM: ssl: openssl 0.9.8 doesn't open /dev/random before chroot
    - BUG/MINOR: time: frequency counters are not totally accurate
    - BUG/MINOR: http: don't process abortonclose when request was sent
    - BUG/MEDIUM: stream_interface: don't close outgoing connections on shutw()
    - BUG/MEDIUM: checks: ignore late resets after valid responses
    - DOC: fix bogus recommendation on usage of gpc0 counter
    - BUG/MINOR: http-compression: lookup Cache-Control in the response, not the request
    - MINOR: signal: don't block SIGPROF by default
    - OPTIM: epoll: make use of EPOLLRDHUP
    - OPTIM: splice: detect shutdowns and avoid splice() == 0
    - OPTIM: splice: assume by default that splice is working correctly
    - BUG/MINOR: log: temporary fix for lost SSL info in some situations
    - BUG/MEDIUM: peers: only the last peers section was used by tables
    - BUG/MEDIUM: config: verbosely reject peers sections with multiple local peers
    - BUG/MINOR: epoll: use a fix maxevents argument in epoll_wait()
    - BUG/MINOR: config: fix improper check for failed memory alloc in ACL parser
    - BUG/MINOR: config: free peer's address when exiting upon parsing error
    - BUG/MINOR: config: check the proper variable when parsing log minlvl
    - BUG/MEDIUM: checks: ensure the health_status is always within bounds
    - BUG/MINOR: cli: show sess should always validate s->listener
    - BUG/MINOR: log: improper NULL return check on utoa_pad()
    - CLEANUP: http: remove a useless null check
    - CLEANUP: tcp/unix: remove useless NULL check in {tcp,unix}_bind_listener()
    - BUG/MEDIUM: signal: signal handler does not properly check for signal bounds
    - BUG/MEDIUM: tools: off-by-one in quote_arg()
    - BUG/MEDIUM: uri_auth: missing NULL check and memory leak on memory shortage
    - BUG/MINOR: unix: remove the 'level' field from the ux struct
    - CLEANUP: http: don't try to deinitialize http compression if it fails before init
    - CLEANUP: config: slowstart is never negative
    - CLEANUP: config: maxcompcpuusage is never negative
    - BUG/MEDIUM: log: emit '-' for empty fields again
    - BUG/MEDIUM: checks: fix a race condition between checks and observe layer7
    - BUILD: fix a warning emitted by isblank() on non-c99 compilers
    - BUILD: improve the makefile's support for libpcre
    - MEDIUM: halog: add support for counting per source address (-ic)
    - MEDIUM: tools: make str2sa_range support all address syntaxes
    - MEDIUM: config: make use of str2sa_range() instead of str2sa()
    - MEDIUM: config: use str2sa_range() to parse server addresses
    - MEDIUM: config: use str2sa_range() to parse peers addresses
    - MINOR: tests: add a config file to ease address parsing tests.
    - MINOR: ssl: add a global tunable for the max SSL/TLS record size
    - BUG/MINOR: syscall: fix NR_accept4 system call on sparc/linux
    - BUILD/MINOR: syscall: add definition of NR_accept4 for ARM
    - MINOR: config: report missing peers section name
    - BUG/MEDIUM: tools: fix bad character handling in str2sa_range()
    - BUG/MEDIUM: stats: never apply "unix-bind prefix" to the global stats socket
    - MINOR: tools: prepare str2sa_range() to return an error message
    - BUG/MEDIUM: checks: don't call connect() on unsupported address families
    - MINOR: tools: prepare str2sa_range() to accept a prefix
    - MEDIUM: tools: make str2sa_range() parse unix addresses too
    - MEDIUM: config: make str2listener() use str2sa_range() to parse unix addresses
    - MEDIUM: config: use a single str2sa_range() call to parse bind addresses
    - MEDIUM: config: use str2sa_range() to parse log addresses
    - CLEANUP: tools: remove str2sun() which is not used anymore.
    - MEDIUM: config: add complete support for str2sa_range() in dispatch
    - MEDIUM: config: add complete support for str2sa_range() in server addr
    - MEDIUM: config: add complete support for str2sa_range() in 'server'
    - MEDIUM: config: add complete support for str2sa_range() in 'peer'
    - MEDIUM: config: add complete support for str2sa_range() in 'source' and 'usesrc'
    - CLEANUP: minor cleanup in str2sa_range() and str2ip()
    - CLEANUP: config: do not use multiple errmsg at once
    - MEDIUM: tools: support specifying explicit address families in str2sa_range()
    - MAJOR: listener: support inheriting a listening fd from the parent
    - MAJOR: tools: support environment variables in addresses
    - BUG/MEDIUM: http: add-header should not emit "-" for empty fields
    - BUG/MEDIUM: config: ACL compatibility check on "redirect" was wrong
    - BUG/MEDIUM: http: fix another issue caused by http-send-name-header
    - DOC: mention the new HTTP 307 and 308 redirect statues
    - MEDIUM: poll: do not use FD_* macros anymore
    - BUG/MAJOR: ev_select: disable the select() poller if maxsock > FD_SETSIZE
    - BUG/MINOR: acl: ssl_fc_{alg,use}_keysize must parse integers, not strings
    - BUG/MINOR: acl: ssl_c_used, ssl_fc{,_has_crt,_has_sni} take no pattern
    - BUILD: fix usual isdigit() warning on solaris
    - BUG/MEDIUM: tools: vsnprintf() is not always reliable on Solaris
    - OPTIM: buffer: remove one jump in buffer_count()
    - OPTIM: http: improve branching in chunk size parser
    - OPTIM: http: optimize the response forward state machine
    - BUILD: enable poll() by default in the makefile
    - BUILD: add explicit support for Mac OS/X
    - BUG/MAJOR: http: use a static storage for sample fetch context
    - BUG/MEDIUM: ssl: improve error processing and reporting in ssl_sock_load_cert_list_file()
    - BUG/MAJOR: http: fix regression introduced by commit a890d072
    - BUG/MAJOR: http: fix regression introduced by commit d655ffe
    - BUG/CRITICAL: using HTTP information in tcp-request content may crash the process
    - MEDIUM: acl: remove flag ACL_MAY_LOOKUP which is improperly used
    - MEDIUM: samples: use new flags to describe compatibility between fetches and their usages
    - MINOR: log: indicate it when some unreliable sample fetches are logged
    - MEDIUM: samples: move payload-based fetches and ACLs to their own file
    - MINOR: backend: rename sample fetch functions and declare the sample keywords
    - MINOR: frontend: rename sample fetch functions and declare the sample keywords
    - MINOR: listener: rename sample fetch functions and declare the sample keywords
    - MEDIUM: http: unify acl and sample fetch functions
    - MINOR: session: rename sample fetch functions and declare the sample keywords
    - MAJOR: acl: make all ACLs reference the fetch function via a sample.
    - MAJOR: acl: remove the arg_mask from the ACL definition and use the sample fetch's
    - MAJOR: acl: remove fetch argument validation from the ACL struct
    - MINOR: http: add new direction-explicit sample fetches for headers and cookies
    - MINOR: payload: add new direction-explicit sample fetches
    - CLEANUP: acl: remove ACL hooks which were never used
    - MEDIUM: proxy: remove acl_requires and just keep a flag "http_needed"
    - MINOR: sample: provide a function to report the name of a sample check point
    - MAJOR: acl: convert all ACL requires to SMP use+val instead of ->requires
    - CLEANUP: acl: remove unused references to ACL_USE_*
    - MINOR: http: replace acl_parse_ver with acl_parse_str
    - MEDIUM: acl: move the ->parse, ->match and ->smp fields to acl_expr
    - MAJOR: acl: add option -m to change the pattern matching method
    - MINOR: acl: remove the use_count in acl keywords
    - MEDIUM: acl: have a pointer to the keyword name in acl_expr
    - MEDIUM: acl: support using sample fetches directly in ACLs
    - MEDIUM: http: remove val_usr() to validate user_lists
    - MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
    - MINOR: ssl: add support for the "alpn" bind keyword
    - MINOR: http: status code 303 is HTTP/1.1 only
    - MEDIUM: http: implement redirect 307 and 308
    - MINOR: http: status 301 should not be marked non-cacheable
2013-04-03 02:26:31 +02:00
Willy Tarreau
ab861d3856 MINOR: ssl: add support for the "alpn" bind keyword
The ALPN extension is meant to replace the now deprecated NPN extension.
This patch implements support for it. It requires a version of openssl
with support for this extension. Patches are available here right now :

   http://html5labs.interopbridges.com/media/167447/alpn_patches.zip
2013-04-03 02:13:02 +02:00
Willy Tarreau
a4312fa28e MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
While ACL args were resolved after all the config was parsed, it was not the
case with sample fetch args because they're almost everywhere now.

The issue is that ACLs now solely rely on sample fetches, so their args
resolving doesn't work anymore. And many fetches involving a server, a
proxy or a userlist don't work at all.

The real issue is that at the bottom layers we have no information about
proxies, line numbers, even ACLs in order to report understandable errors,
and that at the top layers we have no visibility over the locations where
fetches are referenced (think log node).

After failing multiple unsatisfying solutions attempts, we now have a new
concept of args list. The principle is that every proxy has a list head
which contains a number of indications such as the config keyword, the
context where it's used, the file and line number, etc... and a list of
arguments. This list head is of the same type as the elements, so it
serves as a template for adding new elements. This way, it is filled from
top to bottom by the callers with the information they have (eg: line
numbers, ACL name, ...) and the lower layers just have to duplicate it and
add an element when they face an argument they cannot resolve yet.

Then at the end of the configuration parsing, a loop passes over each
proxy's list and resolves all the args in sequence. And this way there is
all necessary information to report verbose errors.

The first immediate benefit is that for the first time we got very precise
location of issues (arg number in a keyword in its context, ...). Second,
in order to do this we had to parse log-format and unique-id-format a bit
earlier, so that was a great opportunity for doing so when the directives
are encountered (unless it's a default section). This way, the recorded
line numbers for these args are the ones of the place where the log format
is declared, not the end of the file.

Userlists report slightly more information now. They're the only remaining
ones in the ACL resolving function.
2013-04-03 02:13:02 +02:00
Willy Tarreau
0a0daecbb2 MEDIUM: http: remove val_usr() to validate user_lists
This one was incorrect since it tried to validate the user-lists
before end of parsing.
2013-04-03 02:13:02 +02:00
Willy Tarreau
bef91e7144 MEDIUM: acl: support using sample fetches directly in ACLs
Now it becomes possible to directly use sample fetches as the ACL fetch
methods. In this case, the matching method is mandatory. This allows to
form more ACL combinations from existing fetches and will limit the need
for new ACLs when everything is available to form them from sample fetches
and matches.
2013-04-03 02:13:02 +02:00
Willy Tarreau
93fddf1dbc MEDIUM: acl: have a pointer to the keyword name in acl_expr
The acl_expr struct used to hold a pointer to the ACL keyword. But since
we now have all the relevant pointers, we don't need that anymore, we just
need the pointer to the keyword as a string in order to return warnings
and error messages.

So let's change this in order to remove the dependency on the acl_keyword
struct from acl_expr.

During this change, acl_cond_kw_conflicts() used to return a pointer to an
ACL keyword but had to be changed to return a const char* for the same reason.
2013-04-03 02:13:01 +02:00
Willy Tarreau
acca90d8e5 MINOR: acl: remove the use_count in acl keywords
use_cnt is not used at all anymore, let's get rid of it.
2013-04-03 02:13:01 +02:00
Willy Tarreau
5adeda1f63 MAJOR: acl: add option -m to change the pattern matching method
ACL expressions now support "-m" in addition to "-i" and "-f". This new
option is followed by the name of the pattern matching method to be used
on the extracted pattern. This makes it possible to reuse existing sample
fetch methods with other matching methods (eg: regex). A "found" matching
method ignores any pattern and only verifies that the required sample was
found (useful for cookies).
2013-04-03 02:13:01 +02:00
Willy Tarreau
d76a98a5fc MEDIUM: acl: move the ->parse, ->match and ->smp fields to acl_expr
We'll need each ACL expression to be able to support its own parse and
match methods, so we're moving these fields to the ACL expression.
2013-04-03 02:13:01 +02:00
Willy Tarreau
ff5afcc32b MINOR: http: replace acl_parse_ver with acl_parse_str
The HTTP version parser used in ACLs has long been a string and
still had its own parser. This makes no sense, switch it to use
the standard string parser.
2013-04-03 02:13:01 +02:00
Willy Tarreau
d86e29d2a1 CLEANUP: acl: remove unused references to ACL_USE_*
Now that acl->requires is not used anymore, we can remove all references
to it as well as all ACL_USE_* flags.
2013-04-03 02:13:00 +02:00
Willy Tarreau
a91d0a583c MAJOR: acl: convert all ACL requires to SMP use+val instead of ->requires
The ACLs now use the fetch's ->use and ->val to decide upon compatibility
between the place where they are used and where the information are fetched.
The code is capable of reporting warnings about very fine incompatibilities
between certain fetches and an exact usage location, so it is expected that
some new warnings will be emitted on some existing configurations.

Two degrees of detection are provided :
  - detecting ACLs that never match
  - detecting keywords that are ignored

All tests show that this seems to work well, though bugs are still possible.
2013-04-03 02:13:00 +02:00
Willy Tarreau
bf8e251077 MINOR: sample: provide a function to report the name of a sample check point
We need to put names on places where samples are used in order to emit warnings
and errors. Let's do that now.
2013-04-03 02:13:00 +02:00
Willy Tarreau
25320b2906 MEDIUM: proxy: remove acl_requires and just keep a flag "http_needed"
Proxy's acl_requires was a copy of all bits taken from ACLs, but we'll
get rid of ACL flags and only rely on sample fetches soon. The proxy's
acl_requires was only used to allocate an HTTP context when needed, and
was even forced in HTTP mode. So better have a flag which exactly says
what it's supposed to be used for.
2013-04-03 02:13:00 +02:00
Willy Tarreau
4a96bf5a5d CLEANUP: acl: remove ACL hooks which were never used
These hooks, which established the relation between ACL_USE_* and the location
where the ACL were used, were never used because they were superseded with the
sample capabilities. Remove them now.
2013-04-03 02:12:59 +02:00
Willy Tarreau
fa95734840 MINOR: payload: add new direction-explicit sample fetches
Similarly to previous commit fixing "hdr" and "cookie" in HTTP, we have to deal
with "payload" and "payload_lv" which are request-only for ACLs and req/resp for
sample fetches depending on the context, and to a less extent with other req_*
and rep_*/rep_* fetches. So let's add explicit "req." and "res." variants and
make the ACLs rely on that instead.
2013-04-03 02:12:59 +02:00
Willy Tarreau
18ed2569f5 MINOR: http: add new direction-explicit sample fetches for headers and cookies
Since "hdr" and "cookie" were ambiguously referring to the request or response
depending on the context, we need a way to explicitly specify the direction.
By prefixing the fetches names with "req." and "res.", we can now restrict such
fetches to the appropriate direction. At the moment the fetches are explicitly
declared by later we might think about having an automatic match when "req." or
"res." appears. These explicit fetches are now used by the relevant ACLs.
2013-04-03 02:12:59 +02:00
Willy Tarreau
9baae63d8d MAJOR: acl: remove fetch argument validation from the ACL struct
ACL fetch being inherited from the sample fetch keyword, we don't need
anymore to specify what function to use to validate the fetch arguments.

Note that the job is still done in the ACL parsing code based on elements
from the sample fetch structs.
2013-04-03 02:12:59 +02:00
Willy Tarreau
c48c90dfa5 MAJOR: acl: remove the arg_mask from the ACL definition and use the sample fetch's
Now that ACLs solely rely on sample fetch functions, make them use the
same arg mask. All inconsistencies have been fixed separately prior to
this patch, so this patch almost only adds a new pointer indirection
and removes all references to ARG*() in the definitions.

The parsing is still performed by the ACL code though.
2013-04-03 02:12:58 +02:00
Willy Tarreau
8ed669b12a MAJOR: acl: make all ACLs reference the fetch function via a sample.
ACL fetch functions used to directly reference a fetch function. Now
that all ACL fetches have their sample fetches equivalent, we can make
ACLs reference a sample fetch keyword instead.

In order to simplify the code, a sample keyword name may be NULL if it
is the same as the ACL's, which is the most common case.

A minor change appeared, http_auth always expects one argument though
the ACL allowed it to be missing and reported as such afterwards, so
fix the ACL to match this. This is not really a bug.
2013-04-03 02:12:58 +02:00
Willy Tarreau
281c799e25 MINOR: session: rename sample fetch functions and declare the sample keywords
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

  sc1_bytes_in_rate, sc1_bytes_out_rate, sc1_clr_gpc0, sc1_conn_cnt,
  sc1_conn_cur, sc1_conn_rate, sc1_get_gpc0, sc1_http_err_cnt,
  sc1_http_err_rate, sc1_http_req_cnt, sc1_http_req_rate, sc1_inc_gpc0,
  sc1_kbytes_in, sc1_kbytes_out, sc1_sess_cnt, sc1_sess_rate, sc1_trackers,
  sc2_bytes_in_rate, sc2_bytes_out_rate, sc2_clr_gpc0, sc2_conn_cnt,
  sc2_conn_cur, sc2_conn_rate, sc2_get_gpc0, sc2_http_err_cnt,
  sc2_http_err_rate, sc2_http_req_cnt, sc2_http_req_rate, sc2_inc_gpc0,
  sc2_kbytes_in, sc2_kbytes_out, sc2_sess_cnt, sc2_sess_rate, sc2_trackers,
  src_bytes_in_rate, src_bytes_out_rate, src_clr_gpc0, src_conn_cnt,
  src_conn_cur, src_conn_rate, src_get_gpc0, src_http_err_cnt,
  src_http_err_rate, src_http_req_cnt, src_http_req_rate, src_inc_gpc0,
  src_kbytes_in, src_kbytes_out, src_sess_cnt, src_sess_rate,
  src_updt_conn_cnt, table_avl, table_cnt,

The fetch functions have been renamed "smp_fetch_*".
2013-04-03 02:12:58 +02:00
Willy Tarreau
409bcde176 MEDIUM: http: unify acl and sample fetch functions
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

    cook, cook_cnt, cook_val, hdr_cnt, hdr_ip, hdr_val, http_auth,
    http_auth_group, http_first_req, method, req_proto_http, req_ver,
    resp_ver, scook, scook_cnt, scook_val, shdr, shdr_cnt, shdr_ip,
    shdr_val, status, urlp, urlp_val,

Most of them won't bring much benefit at the moment, or are even aliases of
existing ones, however they'll be needed for ACL->SMP convergence.

A new val_usr() function was added to resolve userlist names into pointers.

The http_auth_group ACL forgot to make its first argument mandatory, so
there was a check in cfgparse to report a vague error. Now that args are
correctly parsed, let's report something more precise.

All urlp* ACLs now support an optional 3rd argument like their sample
counter-part which is the optional delimiter.

The fetch functions have been renamed "smp_fetch_*".

Some args controls on the sample keywords have been relaxed so that we
can soon use them for ACLs :

  - cookie now accepts to have an optional name ; it will return the
    first matching cookie if the name is not set ;
  - same for set-cookie and hdr
2013-04-03 02:12:57 +02:00
Willy Tarreau
0ccb744ffb MINOR: listener: rename sample fetch functions and declare the sample keywords
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

          dst_conn, so_id,

The fetch functions have been renamed "smp_fetch_*".
2013-04-03 02:12:57 +02:00
Willy Tarreau
d6896bc72a MINOR: frontend: rename sample fetch functions and declare the sample keywords
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

      fe_conn, fe_id, fe_sess_rate

The fetch functions have been renamed "smp_fetch_*".
2013-04-03 02:12:57 +02:00
Willy Tarreau
1a7eca19b8 MINOR: backend: rename sample fetch functions and declare the sample keywords
The following sample fetch functions were only usable by ACLs but are now
usable by sample fetches too :

  avg_queue, be_conn, be_id, be_sess_rate, connslots, nbsrv,
  queue, srv_conn, srv_id, srv_is_up, srv_sess_rate

The fetch functions have been renamed "smp_fetch_*".
2013-04-03 02:12:57 +02:00
Willy Tarreau
d4c33c8889 MEDIUM: samples: move payload-based fetches and ACLs to their own file
The file acl.c is a real mess, it both contains functions to parse and
process ACLs, and some sample extraction functions which act on buffers.
Some other payload analysers were arbitrarily dispatched to proto_tcp.c.

So now we're moving all payload-based fetches and ACLs to payload.c
which is capable of extracting data from buffers and rely on everything
that is protocol-independant. That way we can safely inflate this file
and only use the other ones when some fetches are really specific (eg:
HTTP, SSL, ...).

As a result of this cleanup, the following new sample fetches became
available even if they're not really useful :

  always_false, always_true, rep_ssl_hello_type, rdp_cookie_cnt,
  req_len, req_ssl_hello_type, req_ssl_sni, req_ssl_ver, wait_end

The function 'acl_fetch_nothing' was wrong and never used anywhere so it
was removed.

The "rdp_cookie" sample fetch used to have a mandatory argument while it
was optional in ACLs, which are supposed to iterate over RDP cookies. So
we're making it optional as a fetch too, and it will return the first one.
2013-04-03 02:12:57 +02:00
Willy Tarreau
434c57c95c MINOR: log: indicate it when some unreliable sample fetches are logged
If a log-format involves some sample fetches that may not be present at
the logging instant, we can now report a warning.

Note that this is done both for log-format and for add-header and carefully
respects the original fetch keyword's capabilities.
2013-04-03 02:12:56 +02:00
Willy Tarreau
80aca90ad2 MEDIUM: samples: use new flags to describe compatibility between fetches and their usages
Samples fetches were relying on two flags SMP_CAP_REQ/SMP_CAP_RES to describe
whether they were compatible with requests rules or with response rules. This
was never reliable because we need a finer granularity (eg: an HTTP request
method needs to parse an HTTP request, and is available past this point).

Some fetches are also dependant on the context (eg: "hdr" uses request or
response depending where it's involved, causing some abiguity).

In order to solve this, we need to precisely indicate in fetches what they
use, and their users will have to compare with what they have.

So now we have a bunch of bits indicating where the sample is fetched in the
processing chain, with a few variants indicating for some of them if it is
permanent or volatile (eg: an HTTP status is stored into the transaction so
it is permanent, despite being caught in the response contents).

The fetches also have a second mask indicating their validity domain. This one
is computed from a conversion table at registration time, so there is no need
for doing it by hand. This validity domain consists in a bitmask with one bit
set for each usage point in the processing chain. Some provisions were made
for upcoming controls such as connection-based TCP rules which apply on top of
the connection layer but before instantiating the session.

Then everywhere a fetch is used, the bit for the control point is checked in
the fetch's validity domain, and it becomes possible to finely ensure that a
fetch will work or not.

Note that we need these two separate bitfields because some fetches are usable
both in request and response (eg: "hdr", "payload"). So the keyword will have
a "use" field made of a combination of several SMP_USE_* values, which will be
converted into a wider list of SMP_VAL_* flags.

The knowledge of permanent vs dynamic information has disappeared for now, as
it was never used. Later we'll probably reintroduce it differently when
dealing with variables. Its only use at the moment could have been to avoid
caching a dynamic rate measurement, but nothing is cached as of now.
2013-04-03 02:12:56 +02:00
Willy Tarreau
e0db1e8946 MEDIUM: acl: remove flag ACL_MAY_LOOKUP which is improperly used
This flag is used on ACL matches that support being looking up patterns
in trees. At the moment, only strings and IPs support tree-based lookups,
but the flag is randomly set also on integers and binary data, and is not
even always set on strings nor IPs.

Better get rid of this mess by only relying on the matching function to
decide whether or not it supports tree-based lookups, this is safer and
easier to maintain.
2013-04-03 02:12:56 +02:00
Willy Tarreau
aae75e3279 BUG/CRITICAL: using HTTP information in tcp-request content may crash the process
During normal HTTP request processing, request buffers are realigned if
there are less than global.maxrewrite bytes available after them, in
order to leave enough room for rewriting headers after the request. This
is done in http_wait_for_request().

However, if some HTTP inspection happens during a "tcp-request content"
rule, this realignment is not performed. In theory this is not a problem
because empty buffers are always aligned and TCP inspection happens at
the beginning of a connection. But with HTTP keep-alive, it also happens
at the beginning of each subsequent request. So if a second request was
pipelined by the client before the first one had a chance to be forwarded,
the second request will not be realigned. Then, http_wait_for_request()
will not perform such a realignment either because the request was
already parsed and marked as such. The consequence of this, is that the
rewrite of a sufficient number of such pipelined, unaligned requests may
leave less room past the request been processed than the configured
reserve, which can lead to a buffer overflow if request processing appends
some data past the end of the buffer.

A number of conditions are required for the bug to be triggered :
  - HTTP keep-alive must be enabled ;
  - HTTP inspection in TCP rules must be used ;
  - some request appending rules are needed (reqadd, x-forwarded-for)
  - since empty buffers are always realigned, the client must pipeline
    enough requests so that the buffer always contains something till
    the point where there is no more room for rewriting.

While such a configuration is quite unlikely to be met (which is
confirmed by the bug's lifetime), a few people do use these features
together for very specific usages. And more importantly, writing such
a configuration and the request to attack it is trivial.

A quick workaround consists in forcing keep-alive off by adding
"option httpclose" or "option forceclose" in the frontend. Alternatively,
disabling HTTP-based TCP inspection rules enough if the application
supports it.

At first glance, this bug does not look like it could lead to remote code
execution, as the overflowing part is controlled by the configuration and
not by the user. But some deeper analysis should be performed to confirm
this. And anyway, corrupting the process' memory and crashing it is quite
trivial.

Special thanks go to Yves Lafon from the W3C who reported this bug and
deployed significant efforts to collect the relevant data needed to
understand it in less than one week.

CVE-2013-1912 was assigned to this issue.

Note that 1.4 is also affected so the fix must be backported.
2013-04-03 02:12:55 +02:00
Willy Tarreau
2d43e18b69 BUG/MAJOR: http: fix regression introduced by commit d655ffe
Sander Klein reported that since last snapshot, some downloads would
hang from nginx but succeed from apache. The culprit was not too hard
to find given the low number of recent changes affecting the data path.

Commit d655ffe slightly reorganized the HTTP state machine and
introduced this regression. The reason is that we must never jump
into the MSG_DONE case without first flushing remaining data because
this is not done anymore afterwards. This part is scheduled for
being reorganized since it's totally ugly especially since we added
compression, and this regression is an illustration of its readability.

The issue is entirely dependant on the server close sequence, which
explains why it was reproducible only with nginx here.
2013-04-03 00:22:25 +02:00
Willy Tarreau
ffb6f08bab BUG/MAJOR: http: fix regression introduced by commit a890d072
This commit fixed a bug and introduced a new one at the same time.
It's a stupid typo, the index to store the context is [0], not [2].

The effect is that parsing the header can loop forever if multiple
headers are found. This issue was reported by Lukas Tribus.
2013-04-02 23:19:30 +02:00
Lukas Tribus
0999f7662c BUILD: add explicit support for TFO with USE_TFO
TCP Fast Open is supported in server mode since Linux 3.7, but current
libc's don't define TCP_FASTOPEN=23. Introduce the new USE flag USE_TFO
to define it manually in compat.h. Also note this in the TFO related
documentation.
2013-04-02 17:40:43 +02:00
Willy Tarreau
ad1731d553 BUG/MEDIUM: ssl: improve error processing and reporting in ssl_sock_load_cert_list_file()
fe61656b added the ability to load a list of certificates from a file,
but error control was incomplete and misleading, as some errors such
as missing files were not reported, and errors reported with Alert()
instead of memprintf() were inappropriate and mixed with upper errors.
Also, the code really supports a single SNI filter right now, so let's
correct it and the doc for that, leaving room for later change if needed.
2013-04-02 17:39:04 +02:00
Emmanuel Hocdet
fe61656bb2 MEDIUM: ssl: add mapping from SNI to cert file using "crt-list"
It designates a list of PEM file with an optional list of SNI filter
per certificate, with the following format for each line :

    <crtfile>[ <snifilter>]*

Wildcards are supported in the SNI filter. The certificates will be
presented to clients who provide a valid TLS Server Name Indication
field matching one of SNI filter. If no SNI filter is specified the
CN and alt subjects are used.
2013-04-02 16:59:19 +02:00
Marc-Antoine Perennou
47f922dd24 BUG/MEDIUM: systemd-wrapper: don't leak zombie processes
Formerly, if A was replaced by B, and then B by C before
A finished exiting, we didn't wait for B to finish so it
ended up as a zombie process.
Fix this by waiting randomly every child we spawn.

Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
2013-04-02 14:34:51 +02:00
Willy Tarreau
a890d072fc BUG/MAJOR: http: use a static storage for sample fetch context
Baptiste Assmann reported that the cook*() ACLs do not work anymore.

The reason is the way we store the hdr_ctx between subsequent calls
to smp_fetch_cookie() since commit 3740635b (1.5-dev10).

The smp->ctx.a[] storage holds up to 8 pointers. It is not meant for
generic storage. We used to store hdr_ctx in the ctx, but while it used
to just fit for smp_fetch_hdr(), it does not for smp_fetch_cookie()
since we stored it at offset 2.

The correct solution is to use this storage to store a pointer to the
current hdr_ctx struct which is statically allocated.
2013-04-02 12:01:06 +02:00
Willy Tarreau
8624cab29c BUILD: add explicit support for Mac OS/X
The "osx" target may now be passed in the TARGET variable. It supports
the same features as FreeBSD and allows its users to use the GNU makefile
instead of the platform-specific makefile which lacks some features.
2013-04-02 08:20:01 +02:00
Willy Tarreau
32e65ef625 BUILD: enable poll() by default in the makefile
This allows to build haproxy for unknown targets and still have poll().
If for any reason a target does not support it, just passing USE_POLL=""
disables it.
2013-04-02 08:20:00 +02:00