POSIX says that localtime should fail with EOVERFLOW if the result
cannot be represented, which is the case for most large (in absolute
value) time_t inputs, since they overflow (or underflow) tm_year, which
is an int. This patch introduces this functionality. Previously, tm_year
just overflowed (or underflowed) silently.
Incidentally, this partially fixes#12729 without solving the root
problem, which is that time_to_tm is linear in its input to determine
the number of years since epoch.
This means that the bash port mktime test no longer times-out in 60s,
but it still fails (faster) in some other place. Due to underlying issue
in the algorithm, the worst case inputs still take a couple of seconds
on my machine.
Every StyleValue type now has its own `equals()` method, rather than
relying on the default "compare the to_string() output" method, which
has now been removed. This logic is still used by UnresolvedSV and
CalculatedSV, because it's probably the best option for them unless
performance becomes a real issue.
Also took this opportunity to move all the `equals()` implementations
into the .cpp file, which may or may not actually help with compile
times but StyleValue.h is huge and included everywhere, so it can't
hurt.
31ca48e made this default to paths, but now that we have a few sensible
ways to complete things, let's make those work too.
For instance, prior to this `kill <tab>` would've suggested paths, but
now it will suggest processes.
Setting 'allow_commit_without_listing' to false will now make LibLine
show the suggestion before actually committing to it; this is useful for
completions that will replace all the user input, where mistakes can go
unnoticed without some visual cue.
Now that we can resolve these correctly and they're per-suggestion, we
can finally use them for their intended purpose of letting suggestions
overwrite stuff in the buffer.
The shell now expects a JSON object of the form {"kind":<kind>,...} per
line in the standard output of the completion process, where 'kind' is
one of:
- "plain": Just a plain suggestion.
- "program": Prompts the shell to complete a program name starting with
the given "name".
- "proxy": Prompts the shell to act as if a completion for "argv" was
requested.
- "path": Prompts the shell to complete a path given the "base" and
"part" (same as completing part in cwd=base).
We previously allowed globs as match pattern, but for more complex
matching needs, it's nice to have regular expressions.
And as the existing "name a part of the match" concept maps nicely to
named capture groups, we can simply reuse the same code and make groups
with names available in the match body.
We would have to fclose() it to be clean and nice, but that would close
the fd; instead just duplicate it and write through that, this makes it
actually write to the file.
This is to simplify the code, as Color, Alignment, Flag, Metric and Path
RoleModel classes looked exactly the same.
Additionally, I've added a try_create() function for error propagation.
:^)
For now, EventLoop and Application still have a make_inspectable
parameter, so that when working on an application you can temporarily
hard-code it to be inspectable rather than having to set the env var
each time.
Subject alternative name entries containing IP addresses will now be
parsed and added to the list of SANs. This should allow for certificate
verification when accessing IP addresses directly.
Root and intermediate CA certificates should have these extensions set
to indicate that they are allowed to sign other certificates. The values
reported in these extensions is now also checked by `verify_chain` to
make sure no non-CA certificates are used to sign another certificate.
The certificate parser now also aborts when a critical extension is
detected which is unsupported, as is required by the specification.
The ASN.1 decoder was originally using AK::BitmapView for decoded
BitStrings, however the specification requires that the bits are stored
in a byte from the most significant to the least significant.
Storing three bits '110' would result in a byte '1100 0000', i.e. 0xC0.
However, AK::BitmapView expects the bits to be stored at the bottom like
'0000 0110', i.e. 0x06. For the current uses the data was always a
multiple of eight bits, resulting in complete bytes, which could
directly be interpreted correctly.
For the implementation of the key usage extension of certificates the
correct implementation of the BitString is required.
ASN.1 encodes booleans as false is zero and true is non-zero. The
decoder currently returned true when the boolean was zero.
Since this decoder was barely used it did not cause any problems,
however for support of other certificate extensions the correct version
is required.
The wildcard specified in a certificates subject can only match a single
level of subdomains. Originally, this function could match multiple
levels of subdomains with a single "*.".
As an example, https://wrong.host.badssl.com/ should fail to load, as
the certificate provided by the server only specifies "*.badssl.com".
However this was correctly matching anyway. With this change this page
now correctly fails to load.
The `build_rsa_pre_master_secret` function originally called
`verify_chain_and_get_matching_certificate`, which verified the chain
and returned a certificate matching the specified hostname.
Since the first certificate in the chain should always be the one
matching with the hostname, we can simply use that one instead. This
means we can completely remove this method and just use `verify_chain`.
To make sure the hostname is still verified, `verify_chain` now also
checks that the first certificate in the chain matches the specified
hostname. If the hostname is empty, we currently fail the verification,
however this basically never happen, as the server name indication
extension is always used.
In this format the year is specified using two digits. In the case that
these digits are 50 or more, we should assume that the year is in
1950-1999. If it is 49 or less, the year is 2000-2049.
This is specified in RFC5280 section 4.1.2.5.1.
With this change the certificate chain sent by the server will actually
be verified, instead of just checking the names of the certificates.
To determine if a certificate is signed by a root certificate, the list
of root certificates is now a HashMap mapping from the unique identifier
string to the certificate. This allows us to take the issuer of a
certificate and easily check if it is a root certificate. If a
certificate is not signed by a root certificate, we will check that it
is signed by the next certificate in the chain.
This also removes the ad-hoc checking of certificate validity from
multiple places, and moves all checking to the verify_chain.
The CA certificates list now contains the actual certificate data for
approximatly a hundred certificate authorities. These certificates were
generated from https://mkcert.org, which uses the Mozilla CA certificate
list.
This also updates the code for reading the CA certificates.
The RSA key exchange was the only one actually verifying the validity of
the certificate chain supplied by the server. Now the DHE and ECDHE key
exchanges also check the certificate chain.