Commit graph

37 commits

Author SHA1 Message Date
fanquake
ec5116ae14
Merge bitcoin/bitcoin#28695: net: Sanity check private keys received from SAM proxy
5cf4d266d9 [test] Test i2p private key constraints (Vasil Dimov)
cf70a8d565 [net] Check i2p private key constraints (dergoegge)

Pull request description:

  Not sanity checking can lead to crashes or worse:

  ```
  ==1715589==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000055c2 at pc 0x5622ed66e7ad bp 0x7ffee547a2c0 sp 0x7ffee547a2b8
  READ of size 2 at 0x6140000055c2 thread T0 (b-test)
      #0 0x5622ed66e7ac in memcpy include/bits/string_fortified.h:29:10
      #1 0x5622ed66e7ac in i2p::sam::Session::MyDestination() const src/i2p.cpp:362:5
      #2 0x5622ed662e46 in i2p::sam::Session::CreateIfNotCreatedAlready() src/i2p.cpp:414:40
      #3 0x5622ed6619f2 in i2p::sam::Session::Listen(i2p::Connection&) src/i2p.cpp:143:9
  ```

ACKs for top commit:
  maflcko:
    code lgtm ACK 5cf4d266d9
  stickies-v:
    re-ACK 5cf4d266d9
  vasild:
    ACK 5cf4d266d9

Tree-SHA512: 3de3bd396538fa619de67957b9c8a58011ab911f0f51097c387e730c13908278b7322aa3357051fb245a20b15bef34b0e9fadcb1eff8ad751139d2aa634c78ad
2023-10-30 14:44:40 +01:00
dergoegge
cf70a8d565 [net] Check i2p private key constraints
Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
2023-10-26 16:50:50 +01:00
Vasil Dimov
5c8e15c451
i2p: destroy the session if we get an unexpected error from the I2P router
From https://geti2p.net/en/docs/api/samv3:

  If SILENT=false was passed, which is the default value, the SAM bridge
  sends the client a ASCII line containing the base64 public destination
  key of the requesting peer

So, `Accept()` is supposed to receive a Base64 encoded destination of
the connecting peer, but if it receives something like this instead:

  STREAM STATUS RESULT=I2P_ERROR MESSAGE="Session was closed"

then destroy the session.
2023-10-05 14:11:13 +02:00
Vasil Dimov
5ac1a51ee5
i2p: avoid using Sock::Get() for checking for a valid socket
Peeking at the underlying socket file descriptor of `Sock` and checkig
if it is `INVALID_SOCKET` is bad encapsulation and stands in the way of
testing/mocking/fuzzing.

Instead use an empty unique_ptr to denote that there is no valid socket.
2023-08-24 14:39:58 +02:00
TheCharlatan
7d3b35004b
refactor: Move system from util to common library
Since the kernel library no longer depends on the system file, move it
to the common library instead in accordance to the diagram in
doc/design/libraries.md.
2023-05-20 12:08:13 +02:00
TheCharlatan
be55f545d5
move-only: Extract common/args and common/config.cpp from util/system
This is an extraction of ArgsManager related functions from util/system
into their own common file.

Config file related functions are moved to common/config.cpp.

The background of this commit is an ongoing effort to decouple the
libbitcoinkernel library from the ArgsManager. The ArgsManager belongs
into the common library, since the kernel library should not depend on
it. See doc/design/libraries.md for more information on this rationale.
2023-04-19 10:48:30 +02:00
TheCharlatan
00e9b97f37
refactor: Move fs.* to util/fs.*
The fs.* files are already part of the libbitcoin_util library. With the
introduction of the fs_helpers.* it makes sense to move fs.* into the
util/ directory as well.
2023-03-23 12:55:18 +01:00
fanquake
30874a7cc9
Merge bitcoin/bitcoin#26837: I2P network optimizations
3c1de032de i2p: use consistent number of tunnels with i2pd and Java I2P (Vasil Dimov)
801b405f85 i2p: lower the number of tunnels for transient sessions (Vasil Dimov)
b906b64eb7 i2p: reuse created I2P sessions if not used (Vasil Dimov)

Pull request description:

  * Reuse an I2P transient session instead of discarding it if we failed to connect to the desired peer. This means we never used the generated address (destination), whose creation is not cheap. This does not mean that we will use the same address for more than one peer.
  * Lower the number of tunnels for transient sessions.
  * Explicitly specify the number of tunnels for persistent sessions instead of relying on the defaults which differ between I2P routers. This way we get consistent behavior with all routers.

  Alleviates: https://github.com/bitcoin/bitcoin/issues/26754

  (I have not tested this with i2pd, yet)

ACKs for top commit:
  jonatack:
    ACK 3c1de032de
  mzumsande:
    Light ACK 3c1de032de

Tree-SHA512: 477b4b9a5755e6a9a46bc0f7b268fa419dff4414e25445c750ae913f7552d9e2313f2aca4e3b70067b8390c2d0c2d68ec459f331765e939fc84139e454031cd4
2023-02-22 17:58:41 +00:00
Andrew Chow
35fbc97208
Merge bitcoin/bitcoin#25619: net: avoid overriding non-virtual ToString() in CService and use better naming
c9d548c91f net: remove CService::ToStringPort() (Vasil Dimov)
fd4f0f41e9 gui: simplify OptionsDialog::updateDefaultProxyNets() (Vasil Dimov)
96c791dd20 net: remove CService::ToString() use ToStringAddrPort() instead (Vasil Dimov)
944a9de08a net: remove CNetAddr::ToString() and use ToStringAddr() instead (Vasil Dimov)
043b9de59a scripted-diff: rename ToStringIP[Port]() to ToStringAddr[Port]() (Vasil Dimov)

Pull request description:

  Before this PR we had the somewhat confusing combination of methods:

  `CNetAddr::ToStringIP()`
  `CNetAddr::ToString()` (duplicate of the above)
  `CService::ToStringIPPort()`
  `CService::ToString()` (duplicate of the above, overrides a non-virtual method from `CNetAddr`)
  `CService::ToStringPort()`

  Avoid [overriding non-virtual methods](https://github.com/bitcoin/bitcoin/pull/25349/#issuecomment-1185226396).

  "IP" stands for "Internet Protocol" and while sometimes "IP addresses" are called just "IPs", it is incorrect to call Tor or I2P addresses "IPs". Thus use "Addr" instead of "IP".

  Change the above to:

  `CNetAddr::ToStringAddr()`
  `CService::ToStringAddrPort()`

  The changes touch a lot of files, but are mostly mechanical.

ACKs for top commit:
  sipa:
    utACK c9d548c91f
  achow101:
    ACK c9d548c91f
  jonatack:
    re-ACK c9d548c91f only change since my previous reviews is rebase, but as a sanity check rebased to current master and at each commit quickly re-reviewed and re-verified clean build and green unit tests
  LarryRuane:
    ACK c9d548c91f

Tree-SHA512: 633fb044bdecf9f551b5e3314c385bf10e2b78e8027dc51ec324b66b018da35e5b01f3fbe6295bbc455ea1bcd1a3629de1918d28de510693afaf6a52693f2157
2023-02-17 13:34:40 -05:00
Hennadii Stepanov
581f16ef34
Apply default umask in SetupEnvironment()
This change makes all filesystem artifacts--files and directories--being
created with the default umask.
2023-02-06 11:08:03 +00:00
Hennadii Stepanov
8a6219e543
Remove -sysperms option
This change effectively reverts commits from
https://github.com/bitcoin/bitcoin/pull/4286.

Users, who rely on non-default access permissions, should use `chmod`
command.
2023-02-05 08:09:16 +00:00
Vasil Dimov
3c1de032de
i2p: use consistent number of tunnels with i2pd and Java I2P
The default number of tunnels in the Java implementation is 2 and in the
C++ i2pd it is 5. Pick a mid-number (3) and explicitly set it in order
to get a consistent behavior with both routers. Do this for persistent
sessions which are created once at startup and can be used to open up
to ~10 outbound connections and can accept up to ~125 incoming
connections. Transient sessions already set number of tunnels to 1.

Suggested in:
https://github.com/bitcoin/bitcoin/issues/26754#issuecomment-1367356129
https://geti2p.net/en/docs/api/samv3

Alleviates: https://github.com/bitcoin/bitcoin/issues/26754
2023-01-11 13:56:14 +01:00
Vasil Dimov
801b405f85
i2p: lower the number of tunnels for transient sessions
This will lower the load on the I2P network. Since we use one transient
session for connecting to just one peer, a higher number of tunnels is
unnecessary.

This was suggested in:
https://github.com/bitcoin/bitcoin/issues/26754#issuecomment-1365449401
https://github.com/bitcoin/bitcoin/issues/26754#issuecomment-1367356129

The options are documented in:
https://geti2p.net/en/docs/protocol/i2cp#options

A tunnel is unidirectional, so even if we make a single outbound
connection we still need an inbound tunnel to receive the messages sent
to us over that connection.

Alleviates: https://github.com/bitcoin/bitcoin/issues/26754
2023-01-11 13:56:13 +01:00
Hennadii Stepanov
306ccd4927
scripted-diff: Bump copyright headers
-BEGIN VERIFY SCRIPT-
./contrib/devtools/copyright_header.py update ./
-END VERIFY SCRIPT-

Commits of previous years:
- 2021: f47dda2c58
- 2020: fa0074e2d8
- 2019: aaaaad6ac9
2022-12-24 23:49:50 +00:00
Vasil Dimov
96c791dd20
net: remove CService::ToString() use ToStringAddrPort() instead
Both methods do the same thing, so simplify to having just one.

`ToString()` is too generic in this case and it is unclear what it does,
given that there are similar methods:
`ToStringAddr()` (inherited from `CNetAddr`),
`ToStringPort()` and
`ToStringAddrPort()`.
2022-12-12 11:54:20 +01:00
Vasil Dimov
043b9de59a
scripted-diff: rename ToStringIP[Port]() to ToStringAddr[Port]()
"IP" stands for "Internet Protocol".

"IP address" is sometimes shortened to just "IP" or "address".

However, Tor or I2P addresses are not "IP addresses", nor "IPs".

Thus, use "Addr" instead of "IP" for addresses that could be IP, Tor or
I2P addresses:

`CService::ToStringIPPort()` -> `CService::ToStringAddrPort()`
`CNetAddr::ToStringIP()` -> `CNetAddr::ToStringAddr()`

-BEGIN VERIFY SCRIPT-
sed -i 's/ToStringIPPort/ToStringAddrPort/g' -- $(git grep -l ToStringIPPort src)
sed -i 's/ToStringIP/ToStringAddr/g' -- $(git grep -l ToStringIP src)
-END VERIFY SCRIPT-
2022-12-12 11:48:30 +01:00
fanquake
b89530483d
util: move threadinterrupt into util 2022-11-01 10:14:49 +00:00
Vasil Dimov
8b2891a6d1
i2p: use the same destination type for transient and persistent addresses
We generate our persistent I2P address with type `EdDSA_SHA512_Ed25519`
(`DEST GENERATE SIGNATURE_TYPE=7`).

Use the same type for our transient addresses which are created by the
`SESSION CREATE ...` command. If not specified, then the default one is
`DSA_SHA1` according to https://geti2p.net/en/docs/api/samv3.
2022-09-12 12:55:36 +02:00
Vasil Dimov
59aa54f731
i2p: log "SAM session" instead of "session"
This way the log messages are consistent with "Creating SAM session..."
2022-08-16 13:02:21 +02:00
Vasil Dimov
2b781ad66e
i2p: add support for creating transient sessions
Instead of providing our destination (private key) to the I2P proxy when
creating the session, ask it to generate one for us and do not save it
on disk.
2022-08-11 17:51:18 +02:00
fanquake
cc7b2fdd70
refactor: move compat.h into compat/ 2022-07-20 10:34:46 +01:00
Vasil Dimov
a724c39606
net: rename Sock::Reset() to Sock::Close() and make it private
Outside of `Sock`, `Sock::Reset()` was used in just one place (in
`i2p.cpp`) which can use the assignment operator instead.

This simplifies the public `Sock` API by having one method less.
2022-06-22 09:19:43 +02:00
laanwj
0ea92cad52
Merge bitcoin/bitcoin#24356: refactor: replace CConnman::SocketEvents() with mockable Sock::WaitMany()
6e68ccbefe net: use Sock::WaitMany() instead of CConnman::SocketEvents() (Vasil Dimov)
ae263460ba net: introduce Sock::WaitMany() (Vasil Dimov)
cc74459768 net: also wait for exceptional events in Sock::Wait() (Vasil Dimov)

Pull request description:

  _This is a piece of #21878, chopped off to ease review._

  `Sock::Wait()` waits for IO events on one socket. Introduce a similar `virtual` method `WaitMany()` that waits simultaneously for IO events on more than one socket.

  Use `WaitMany()` instead of `CConnman::SocketEvents()` (and ditch the latter). Given that the former is a `virtual` method, it can be mocked by unit and fuzz tests. This will help to make bigger parts of `CConnman` testable (unit and fuzz).

ACKs for top commit:
  laanwj:
    Code review ACK 6e68ccbefe
  jonatack:
    re-ACK 6e68ccbefe per `git range-diff e18fd47 6747729 6e68ccb`, and verified rebase to master and debug build

Tree-SHA512: 917fb6ad880d64d3af1ebb301c06fbd01afd8ff043f49e4055a088ebed6affb7ffe1dcf59292d822f10de5f323b6d52d557cb081dd7434634995f9148efcf08f
2022-06-16 20:05:03 +02:00
Vasil Dimov
cc74459768
net: also wait for exceptional events in Sock::Wait()
This mimics closely `CConnman::SocketEvents()` and the underlying
`poll(2)`.
2022-06-09 13:34:27 +02:00
Jon Atack
ecff20db28 logging: use LogPrintfCategory rather than a manual category
Here we update only the log messages that manually print a category.

In upcoming commits, LogPrintCategory will likely be used in many
other cases, such as to replace `LogPrintf` where it makes sense.
2022-06-08 14:02:54 +02:00
Jon Atack
d40550d725 scripted-diff: remove duplicate categories from LogPrint output
-BEGIN VERIFY SCRIPT-
s() { git grep -l "$1" src | xargs sed -i "s/$1/$2/g"; }
s 'BCLog::TOR, "tor: '       'BCLog::TOR, "'
s 'BCLog::I2P, "I2P: '       'BCLog::I2P, "'
s 'BCLog::NET, "net: '       'BCLog::NET, "'
s 'BCLog::ZMQ, "zmq: '       'BCLog::ZMQ, "'
s 'BCLog::PRUNE, "Prune: '   'BCLog::PRUNE, "'
-END VERIFY SCRIPT-
2022-06-06 12:12:03 +02:00
Pieter Wuille
78f3ac51b7 Make DecodeBase{32,64} return optional instead of taking bool* 2022-04-27 14:12:55 +02:00
Pieter Wuille
a65931e3ce Make DecodeBase{32,64} always return vector, not string
Base32/base64 are mechanisms for encoding binary data. That they'd
decode to a string is just bizarre. The fact that they'd do that
based on the type of input arguments even more so.
2022-04-27 14:12:55 +02:00
Hennadii Stepanov
f47dda2c58
scripted-diff: Bump copyright headers
-BEGIN VERIFY SCRIPT-
./contrib/devtools/copyright_header.py update ./
-END VERIFY SCRIPT-

Commits of previous years:
* 2020: fa0074e2d8
* 2019: aaaaad6ac9
2021-12-30 19:36:57 +02:00
Russell Yanofsky
6544ea5035 refactor: Block unsafe fs::path std::string conversion calls
There is no change in behavior. This just helps prepare for the
transition from boost::filesystem to std::filesystem by avoiding calls
to methods which will be unsafe after the transaction to std::filesystem
to due lack of a boost::filesystem::path::imbue equivalent and inability
to set a predictable locale.

Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Co-authored-by: Kiminuo <kiminuo@protonmail.com>
Co-authored-by: MarcoFalke <falke.marco@gmail.com>
2021-10-05 11:10:47 -04:00
Vasil Dimov
4f432bd738
net: do not connect to I2P hosts on port!=0
When connecting to an I2P host we don't specify destination port and it
is being forced to 0 by the SAM 3.1 proxy, so if we connect to the same
host on two different ports, that would be actually two connections to
the same service (listening on port 0).

Fixes https://github.com/bitcoin/bitcoin/issues/21389
2021-07-09 11:19:37 +02:00
Vasil Dimov
38f900290c
net: change assumed I2P port to 0
* When accepting an I2P connection, assume the peer has port 0 instead
  of the default 8333 (for mainnet). It is not being sent to us, so we
  must assume something.
* When deriving our own I2P listen CService use port 0 instead of the
  default 8333 (for mainnet). So that we later advertise it to peers
  with port 0.

In the I2P protocol SAM 3.1 and older (we use 3.1) ports are not used,
so they are irrelevant. However in SAM 3.2 and newer ports are used and
from the point of view of SAM 3.2, a peer using SAM 3.1 seems to have
specified port=0.
2021-07-09 11:19:35 +02:00
Vasil Dimov
1c1467f51b
i2p: cancel the Accept() method if waiting on the socket errors 2021-04-08 16:31:55 +02:00
Vasil Dimov
9947e44de0
i2p: use pointers to Sock to accommodate mocking
Change the types of `i2p::Connection::sock` and
`i2p::sam::Session::m_control_sock` from `Sock` to
`std::unique_ptr<Sock>`.

Using pointers would allow us to sneak `FuzzedSock` instead of `Sock`
and have the methods of the former called.

After this change a test only needs to replace `CreateSock()` with
a function that returns `FuzzedSock`.
2021-03-16 13:59:18 +01:00
Vasil Dimov
82d360b5a8
net: change ConnectSocketDirectly() to take a Sock argument
Change `ConnectSocketDirectly()` to take a `Sock` argument instead of a
bare `SOCKET`. With this, use the `Sock`'s (possibly mocked) methods
`Connect()`, `Wait()` and `GetSockOpt()` instead of calling the OS
functions directly.
2021-03-16 13:58:23 +01:00
Vasil Dimov
80a5a8ea2b
i2p: limit the size of incoming messages
Put a limit on the amount of data `Sock::RecvUntilTerminator()` can read
if no terminator is received.

In the case of I2P this avoids a runaway (or malicious) I2P proxy
sending us tons of data without a terminator before a timeout is
triggered.
2021-03-16 11:00:57 +01:00
Vasil Dimov
c22daa2ecf
net: implement the necessary parts of the I2P SAM protocol
Implement the following commands from the I2P SAM protocol:

* HELLO: needed for all of the remaining ones
* DEST GENERATE: to generate our private key and destination
* NAMING LOOKUP: to convert .i2p addresses to destinations
* SESSION CREATE: needed for STREAM CONNECT and STREAM ACCEPT
* STREAM CONNECT: to make outgoing connections
* STREAM ACCEPT: to accept incoming connections
2021-03-01 18:19:37 +01:00