relay: add command "handshake" in weechat relay protocol and nonce to prevent replay attacks (closes #1474)

This introduces a new command called "handshake" in the weechat relay protocol.
It should be sent by the client before the "init" command, to negotiate the way
to authenticate with a password.

3 new options are added:

* relay.network.auth_password
* relay.network.hash_iterations
* relay.network.nonce_size
master
Sébastien Helleu 2020-04-14 21:34:46 +02:00
parent ccd45e4921
commit 9fa3609c85
43 changed files with 2390 additions and 471 deletions

View File

@ -21,6 +21,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
New features::
* buflist: evaluate option buflist.look.sort so that sort can be customized for each of the three buflist bar items (issue #1465)
* relay: add command "handshake" in weechat relay protocol and nonce to prevent replay attacks, add options relay.network.auth_password, relay.network.hash_iterations, relay.network.nonce_size (issue #1474)
* relay: add option relay.network.auth_timeout
* relay: update default colors for client status
* relay: add status "waiting_auth" in irc and weechat protocols (issue #1358)

View File

@ -20,6 +20,36 @@ https://weechat.org/files/changelog/ChangeLog-devel.html[ChangeLog]
[[v2.9]]
== Version 2.9 (under dev)
[[v2.9_relay_weechat_protocol_handshake_nonce]]
=== Add of handshake and nonce in weechat relay protocol
==== Handshake
A _handshake_ command has been added in weechat relay protocol. +
The client should send this command before the _init_ to negotiate the way to
authenticate with the relay server.
See the link:weechat_relay_protocol.en.html#command_handshake[handshake command]
in Relay protocol doc for more information.
==== Server "nonce"
Furthermore, a "nonce" is now generated for each client connecting and must be
used by the client in case of hashed password in the _init_ command. +
The goal is to prevent replay attacks in case someone manages to read exchanges
between the client and relay.
When hashing the password, the client must use salt composed by this nonce
as binary (it is hexadecimal and must be base16-decoded), concatenated with
a client nonce after this one. +
So the hash is computed on: (`server nonce` + `client nonce` + `password`).
This salt is now mandatory even for algorithms `SHA256` and `SHA512`; this is
a breaking change in protocol, needed for security reasons.
See the link:weechat_relay_protocol.en.html#command_init[init command]
in Relay protocol doc for more information.
[[v2.9_trigger_command_eval]]
=== Evaluation of trigger command arguments

View File

@ -116,6 +116,12 @@
** Werte: beliebige Zeichenkette
** Standardwert: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** Beschreibung: pass:none[comma separated list of hash algorithms used for password authentication in weechat protocol, among these values: "plain" (password in plain text, not hashed), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512"), "*" means all algorithms, a name beginning with "!" is a negative value to prevent an algorithm from being used, wildcard "*" is allowed in names (examples: "*", "pbkdf2*", "*,!plain")]
** Typ: Zeichenkette
** Werte: beliebige Zeichenkette
** Standardwert: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** Beschreibung: pass:none[timeout (in seconds) for client authentication: connection is closed if the client is still not authenticated after this delay and the client status is set to "authentication failed" (0 = wait forever)]
** Typ: integer
@ -140,6 +146,12 @@
** Werte: 0 .. 9
** Standardwert: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** Beschreibung: pass:none[number of iterations asked to the client in weechat protocol when a hashed password with algorithm PBKDF2 is used for authentication; more iterations is better in term of security but is slower to compute; this number should not be too high if your CPU is slow]
** Typ: integer
** Werte: 1 .. 1000000
** Standardwert: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** Beschreibung: pass:none[lauscht standardmäßig am IPv6 Socket (zusätzlich zu IPv4, welches als Standardprotokoll genutzt wird); mittels des Protokollnamens kann das IPv4 und IPv6 Protokoll, einzeln oder gemeinsam, erzwungen werden (siehe /help relay)]
** Typ: boolesch
@ -152,6 +164,12 @@
** Werte: 0 .. 2147483647
** Standardwert: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** Beschreibung: pass:none[size of nonce (in bytes), generated when a client connects; the client must use this nonce, concatenated to the client nonce and the password when hashing the password in the "init" command of the weechat protocol]
** Typ: integer
** Werte: 8 .. 128
** Standardwert: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** Beschreibung: pass:none[Passwort wird von Clients benötigt um Zugriff auf dieses Relay zu erhalten (kein Eintrag bedeutet, dass kein Passwort benötigt wird, siehe Option relay.network.allow_empty_password) (Hinweis: Inhalt wird evaluiert, siehe /help eval)]
** Typ: Zeichenkette

View File

@ -116,6 +116,12 @@
** values: any string
** default value: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** description: pass:none[comma separated list of hash algorithms used for password authentication in weechat protocol, among these values: "plain" (password in plain text, not hashed), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512"), "*" means all algorithms, a name beginning with "!" is a negative value to prevent an algorithm from being used, wildcard "*" is allowed in names (examples: "*", "pbkdf2*", "*,!plain")]
** type: string
** values: any string
** default value: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** description: pass:none[timeout (in seconds) for client authentication: connection is closed if the client is still not authenticated after this delay and the client status is set to "authentication failed" (0 = wait forever)]
** type: integer
@ -140,6 +146,12 @@
** values: 0 .. 9
** default value: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** description: pass:none[number of iterations asked to the client in weechat protocol when a hashed password with algorithm PBKDF2 is used for authentication; more iterations is better in term of security but is slower to compute; this number should not be too high if your CPU is slow]
** type: integer
** values: 1 .. 1000000
** default value: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** description: pass:none[listen on IPv6 socket by default (in addition to IPv4 which is default); protocols IPv4 and IPv6 can be forced (individually or together) in the protocol name (see /help relay)]
** type: boolean
@ -152,6 +164,12 @@
** values: 0 .. 2147483647
** default value: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** description: pass:none[size of nonce (in bytes), generated when a client connects; the client must use this nonce, concatenated to the client nonce and the password when hashing the password in the "init" command of the weechat protocol]
** type: integer
** values: 8 .. 128
** default value: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** description: pass:none[password required by clients to access this relay (empty value means no password required, see option relay.network.allow_empty_password) (note: content is evaluated, see /help eval)]
** type: string

View File

@ -318,6 +318,7 @@ WeeChat "core" is located in following directories:
|       weechat-python-api.c | Python scripting API functions.
|    relay/ | Relay plugin (IRC proxy and relay for remote interfaces).
|       relay.c | Main relay functions.
|       relay-auth.c | Clients authentication.
|       relay-buffer.c | Relay buffer.
|       relay-client.c | Clients of relay.
|       relay-command.c | Relay commands.
@ -378,48 +379,47 @@ WeeChat "core" is located in following directories:
[width="100%",cols="1m,2",options="header"]
|===
| Path/file | Description
| tests/ | Root of tests.
|    tests.cpp | Program used to run all tests.
|    scripts/ | Root of scripting API tests.
|       test-scripts.cpp | Program used to run the scripting API tests.
|       python/ | Python scripts to generate and run the scripting API tests.
|          testapigen.py | Python script generating scripts in all languages to test the scripting API.
|          testapi.py | Python script with scripting API tests, used by script testapigen.py.
|          unparse.py | Convert Python code to other languages, used by script testapigen.py.
|    unit/ | Root of unit tests.
|       test-plugins.cpp | Tests: plugins.
|       core/ | Root of unit tests for core.
|          test-core-arraylist.cpp | Tests: arraylists.
|          test-core-calc.cpp | Tests: calculation of expressions.
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | Tests: evaluation of expressions.
|          test-core-hashtble.cpp | Tests: hashtables.
|          test-core-hdata.cpp | Tests: hdata.
|          test-core-hook.cpp | Tests: hooks.
|          test-core-infolist.cpp | Tests: infolists.
|          test-core-list.cpp | Tests: lists.
|          test-core-secure.cpp | Tests: secured data.
|          test-core-string.cpp | Tests: strings.
|          test-core-url.cpp | Tests: URLs.
|          test-core-utf8.cpp | Tests: UTF-8.
|          test-core-util.cpp | Tests: utility functions.
|       gui/ | Root of unit tests for interfaces.
|          test-gui-color.cpp | Tests: colors.
|          test-gui-line.cpp | Tests: lines.
|          test-gui-nick.cpp | Tests: nicks.
|       plugins/ | Root of unit tests for plugins.
|          irc/ | Root of unit tests for IRC plugin.
|             test-irc-color.cpp | Tests: IRC colors.
|             test-irc-config.cpp | Tests: IRC configuration.
|             test-irc-ignore.cpp | Tests: IRC ignores.
|             test-irc-message.cpp | Tests: IRC messages.
|             test-irc-mode.cpp | Tests: IRC modes.
|             test-irc-nick.cpp | Tests: IRC nicks.
|             test-irc-protocol.cpp | Tests: IRC protocol.
|          relay/ | Root of unit tests for Relay plugin.
|             weechat/ | Root of unit tests for weechat protocol.
|                test-relay-weechat-protocol.cpp | Tests: weechat protocol.
| Path/file | Description
| tests/ | Root of tests.
|    tests.cpp | Program used to run all tests.
|    scripts/ | Root of scripting API tests.
|       test-scripts.cpp | Program used to run the scripting API tests.
|       python/ | Python scripts to generate and run the scripting API tests.
|          testapigen.py | Python script generating scripts in all languages to test the scripting API.
|          testapi.py | Python script with scripting API tests, used by script testapigen.py.
|          unparse.py | Convert Python code to other languages, used by script testapigen.py.
|    unit/ | Root of unit tests.
|       test-plugins.cpp | Tests: plugins.
|       core/ | Root of unit tests for core.
|          test-core-arraylist.cpp | Tests: arraylists.
|          test-core-calc.cpp | Tests: calculation of expressions.
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | Tests: evaluation of expressions.
|          test-core-hashtble.cpp | Tests: hashtables.
|          test-core-hdata.cpp | Tests: hdata.
|          test-core-hook.cpp | Tests: hooks.
|          test-core-infolist.cpp | Tests: infolists.
|          test-core-list.cpp | Tests: lists.
|          test-core-secure.cpp | Tests: secured data.
|          test-core-string.cpp | Tests: strings.
|          test-core-url.cpp | Tests: URLs.
|          test-core-utf8.cpp | Tests: UTF-8.
|          test-core-util.cpp | Tests: utility functions.
|       gui/ | Root of unit tests for interfaces.
|          test-gui-color.cpp | Tests: colors.
|          test-gui-line.cpp | Tests: lines.
|          test-gui-nick.cpp | Tests: nicks.
|       plugins/ | Root of unit tests for plugins.
|          irc/ | Root of unit tests for IRC plugin.
|             test-irc-color.cpp | Tests: IRC colors.
|             test-irc-config.cpp | Tests: IRC configuration.
|             test-irc-ignore.cpp | Tests: IRC ignores.
|             test-irc-message.cpp | Tests: IRC messages.
|             test-irc-mode.cpp | Tests: IRC modes.
|             test-irc-nick.cpp | Tests: IRC nicks.
|             test-irc-protocol.cpp | Tests: IRC protocol.
|          relay/ | Root of unit tests for Relay plugin.
|             test-relay-auth.cpp | Tests: clients authentication.
|===

View File

@ -32,11 +32,11 @@ The _clients_ are connected to _relay_ like shown in this diagram:
....
┌──────────┐ Workstation
┌────────┐ ┌───┤ client 1 │ (Linux, Windows,
│ irc │──┐ ╔═══════════╤═══════╗ │ └──────────┘ BSD, macOS ...)
└────────┘ └──╢ │ ║───┘ ┌──────────┐
...... ║ WeeChat │ Relay ║───────┤ client 2 │ Mobile device
┌────────┐ ┌──╢ │ ║───┐ └──────────┘ (Android, iPhone ...)
│ jabber │──┘ ╚═══════════╧═══════╝ │ ......
│ irc │──┐ ╔═══════════╤═══════╗ │ └──────────┘ BSD, macOS ...)
└────────┘ └──╢ │ ║───┘ ┌──────────┐
...... ║ WeeChat │ Relay ║───────┤ client 2 │ Mobile device
┌────────┐ ┌──╢ │ ║───┐ └──────────┘ (Android, iPhone ...)
│ jabber │──┘ ╚═══════════╧═══════╝ │ ......
└────────┘ │ ┌──────────┐
...... └───┤ client N │ Other devices
└──────────┘
@ -86,24 +86,129 @@ List of available commands (detail in next chapters):
[width="80%",cols="^3m,14",options="header"]
|===
| Command | Description
| init | Initialize connection with _relay_.
| hdata | Request a _hdata_.
| info | Request an _info_.
| infolist | Request an _infolist_.
| nicklist | Request a _nicklist_.
| input | Send data to a buffer (text or command).
| sync | Synchronize buffer(s): get updates for buffer(s).
| desync | Desynchronize buffer(s): stop updates for buffer(s).
| quit | Disconnect from _relay_.
| Command | Description
| handshake | Handshake: prepare client authentication and set options, before _init_ command.
| init | Authenticate with _relay_.
| hdata | Request a _hdata_.
| info | Request an _info_.
| infolist | Request an _infolist_.
| nicklist | Request a _nicklist_.
| input | Send data to a buffer (text or command).
| sync | Synchronize buffer(s): get updates for buffer(s).
| desync | Desynchronize buffer(s): stop updates for buffer(s).
| quit | Disconnect from _relay_.
|===
[[command_handshake]]
=== handshake
_WeeChat ≥ 2.9._
Perform an handshake between the client and WeeChat: this is required in most
cases to know the session settings and prepare the authentication with the
_init_ command.
The handshake can be performed multiple times before the _init_ command,
although it is rarely needed.
Syntax:
----
handshake [<option>=<value>,[<option>=<value>,...]]
----
Arguments:
* _option_: one of following options:
** _password_: list of hash algorithms supported by the client (separated by colons),
allowed values are:
*** _plain_: plain text password (no hash)
*** _sha256_: password salted and hashed with SHA256 algorithm
*** _sha512_: password salted and hashed with SHA512 algorithm
*** _pbkdf2+sha256_: password salted and hashed with PBKDF2 algorithm (using SHA256 hash)
*** _pbkdf2+sha512_: password salted and hashed with PBKDF2 algorithm (using SHA512 hash)
** _compression_: compression type:
*** _zlib_: enable _zlib_ compression for messages sent by _relay_
(enabled by default if _relay_ supports _zlib_ compression)
*** _off_: disable compression
Notes about option _password_:
* If the option is not given (of if the _handshake_ command is not sent by the
client), _relay_ uses automatically _plain_ authentication (if allowed on
_relay_ side).
* _Relay_ chooses the safest algorithm available on both client and _relay_,
by order of priority from first (safest) to last used:
. _pbkdf2+sha512_
. _pbkdf2+sha256_
. _sha512_
. _sha256_
. _plain_
WeeChat replies with a hashtable containing the following keys and values:
* _auth_password_: the password authentication negotiated: supported by both
the client and _relay_:
** (empty value): negotiation failed, password authentication is *NOT* possible
** _plain_
** _sha256_
** _sha512_
** _pbkdf2+sha256_
** _pbkdf2+sha512_
* _hash_iterations_: number of iterations for hash (for the PBKDF2 algorithm only)
* _totp_:
** _on_: Time-based One-Time Password (TOTP) is configured and expected
in the _init_ command
** _off_: Time-based One-Time Password (TOTP) is not enabled and not needed
in the _init_ command
* _nonce_: a buffer of unpredictable bytes, sent as hexadecimal, to prevent
replay attacks; if _auth_password_ is a hash algorithm, the client must compute
the hash of password on this nonce, concatenated with a client nonce and the
user password (the _relay_ nonce + the client nonce is the salt used in the
password hash algorithm)
Examples:
----
# nothing offered by the client (or only "plain"), authentication password "plain" will be used if allowed on relay side
handshake
handshake password=plain
# only plain, sha256 and pbkdf2+sha256 are supported by the client
handshake password=plain:sha256:pbkdf2+sha256
----
Example of response:
[source,python]
----
id: 'handshake'
htb: {'auth_password': 'pbkdf2+sha256', 'hash_iterations': '100000', 'totp': 'on', 'nonce': '85B1EE00695A5B254E14F4885538DF0D'}
----
The client can authenticate with this command (see <<command_init,init command>>),
the salt is the _relay_ nonce + "ABCD" ("41424344" in hexadecimal):
----
init password_hash=pbkdf2+sha256:85b1ee00695a5b254e14f4885538df0d41424344:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[TIP]
With WeeChat ≤ 2.8, the command _handshake_ is not implemented, WeeChat silently
ignores this command, even if it is sent before the _init_ command. +
So it is safe to send this command to any WeeChat version.
[[command_init]]
=== init
Initialize connection with _relay_. This must be first command sent to _relay_.
If not sent, _relay_ will close connection on first command received, without
warning.
_Updated in versions 2.4, 2.8, 2.9._
Authenticate with _relay_.
This must be first command sent to _relay_ (only _handshake_ command can be sent
before _init_). +
If not sent, _relay_ will close connection on first command received (except
_handshake_), without warning.
Syntax:
@ -123,7 +228,9 @@ Arguments:
factor, in addition to the password
(option _relay.network.totp_secret_ in WeeChat)
_(WeeChat ≥ 2.4)_
** _compression_: compression type:
** _compression_: compression type (*deprecated* since version 2.9, it is kept
for compatibility reasons but should be sent in the
<<command_handshake,handshake command>>):
*** _zlib_: enable _zlib_ compression for messages sent by _relay_
(enabled by default if _relay_ supports _zlib_ compression)
*** _off_: disable compression
@ -135,13 +242,27 @@ With WeeChat ≥ 1.6, commas can be escaped in the value, for example
Format of hashed password is one of the following, where _hash_ is the hashed
password as hexadecimal:
* `+sha256:hash+`
* `+sha512:hash+`
* `+pbkdf2:algorithm:salt:iterations:hash+` with:
** _algorithm_: _sha256_ or _sha512_
** _salt_: salt (hexadecimal)
* `+sha256:salt:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _hash_: the hashed salt + password (hexadecimal)
* `+sha512:salt:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _hash_: the hashed salt + password (hexadecimal)
* `+pbkdf2+sha256:salt:iterations:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _iterations_: number of iterations
** _hash_: the hashed password (hexadecimal)
** _hash_: the hashed salt + password with SHA256 algorithm (hexadecimal)
* `+pbkdf2+sha512:salt:iterations:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _iterations_: number of iterations
** _hash_: the hashed salt + password with SHA512 algorithm (hexadecimal)
[NOTE]
Hexadecimal strings can be lower or upper case, _relay_ can decode both.
Examples:
@ -158,14 +279,14 @@ init password=mypass,totp=123456
# initialize and disable compression
init password=mypass,compression=off
# initialize with hashed password (SHA256) (WeeChat ≥ 2.8)
init password_hash=sha256:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialize with hashed password (SHA256: salt="nonce:cnonce") (WeeChat ≥ 2.9)
init password_hash=sha256:6e6f6e63653a636e6f6e6365:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialize with hashed password (SHA512) (WeeChat ≥ 2.8)
init password_hash=sha512:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialize with hashed password (SHA512: salt="nonce:cnonce") (WeeChat ≥ 2.9)
init password_hash=sha512:6e6f6e63653a636e6f6e6365:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialize with hashed password (PBKDF2: SHA256, salt="ABCDEFGHIJKLMNOP", 100000 iterations) (WeeChat ≥ 2.8)
init password_hash=pbkdf2:sha256:4142434445464748494a4b4c4d4e4f50:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
# initialize with hashed password (PBKDF2: SHA256, salt="nonce:cnonce", 100000 iterations) (WeeChat ≥ 2.9)
init password_hash=pbkdf2+sha256:6e6f6e63653a636e6f6e6365:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[[command_hdata]]
@ -1389,7 +1510,7 @@ Example:
....
┌────┐
│ 41 │ ──── 65 (0x41: "A")
│ 41 │ ──── 65 (0x41: "A")
└────┘
....
@ -1405,11 +1526,11 @@ Examples:
....
┌────┬────┬────┬────┐
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
└────┴────┴────┴────┘
┌────┬────┬────┬────┐
│ FF │ FE │ 1D │ C0 │ ──── -123456
│ FF │ FE │ 1D │ C0 │ ──── -123456
└────┴────┴────┴────┘
....
@ -1424,13 +1545,13 @@ Examples:
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
length '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └────────────────────────────────────────────────────┘
length '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
@ -1445,7 +1566,7 @@ Example:
....
┌────┬────┬────┬────╥────┬────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
└────┴────┴────┴────╨────┴────┴────┴────┴────┘
└─────────────────┘ └──────────────────────┘
length 'h' 'e' 'l' 'l' 'o'
@ -1455,7 +1576,7 @@ An empty string has a length of zero:
....
┌────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 00 │ ──── ""
│ 00 │ 00 │ 00 │ 00 │ ──── ""
└────┴────┴────┴────┘
└─────────────────┘
length
@ -1465,7 +1586,7 @@ A _NULL_ string (NULL pointer in C) has a length of -1:
....
┌────┬────┬────┬────┐
│ FF │ FF │ FF │ FF │ ──── NULL
│ FF │ FF │ FF │ FF │ ──── NULL
└────┴────┴────┴────┘
└─────────────────┘
length
@ -1485,7 +1606,7 @@ Example:
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └──────────────────────────────────────────┘
length '1' 'a' '2' 'b' '3' 'c' '4' 'd' '5'
@ -1495,7 +1616,7 @@ A _NULL_ pointer has a length of 1 with value 0:
....
┌────╥────┐
│ 01 ║ 00 │ ──── NULL (0x0)
│ 01 ║ 00 │ ──── NULL (0x0)
└────╨────┘
└──┘ └──┘
length 0
@ -1510,7 +1631,7 @@ Example:
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
length '1' '3' '2' '1' '9' '9' '3' '4' '5' '6'
@ -1532,7 +1653,7 @@ Example:
....
┌─────┬─────┬───╥──────┬─────╥──────┬─────┐
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
└─────┴─────┴───╨──────┴─────╨──────┴─────┘ 'key2' => 'def' }
└───┘ └───┘ └─┘ └──────────┘ └──────────┘
type type count item 1 item 2
@ -1759,7 +1880,7 @@ Example of array with two strings:
type number of strings length
──╥────┬────┬────╥────┬────┬────┬────╥────┬────┐
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
──╨────┴────┴────╨────┴────┴────┴────╨────┴────┘
└────────────┘ └─────────────────┘ └───────┘
'a' 'b' 'c' length 'd' 'e'
@ -1775,7 +1896,7 @@ Example of array with three integers:
type number of integers 123 (0x7B)
──╥────┬────┬────┬────╥────┬────┬────┬────┐
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
──╨────┴────┴────┴────╨────┴────┴────┴────┘
└─────────────────┘ └─────────────────┘
456 (0x1C8) 789 (0x315)
@ -1785,7 +1906,7 @@ A _NULL_ array:
....
┌─────╥────┬────┬────┬────┐
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
└─────╨────┴────┴────┴────┘
└───┘ └─────────────────┘
type number of strings
@ -1799,43 +1920,49 @@ A _NULL_ array:
│ Client ├ ─ ─ ─ ─(network)─ ─ ─ ─ ┤ Relay ├────────────────┤ WeeChat │
└────────┘ └───────┘ └─────────┘
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ open socket ║ add client ║
║ ║ ║
╟───────────────────────────────► ║ ║
║ cmd: init password=xxx,... ║ init/allow client ║
╟───────────────────────────────▶ ║ ║
║ cmd: handshake password=xxx,... ║ negotiate algos ║
║ ║ and options ║
║ ◀───────────────────────────────╢ ║
║ msg: id: "handshake" ... ║ ║
║ ║ ║
╟───────────────────────────────► ║ ║
║ cmd: hdata buffer ... ╟───────────────────────► ║
╟───────────────────────────────▶ ║ ║
║ cmd: init password=xxx,... ║ authenticate client ║
║ ║ ║
╟───────────────────────────────▶ ║ ║
║ cmd: hdata buffer ... ╟───────────────────────▶ ║
║ sync ... ║ request hdata ║ read hdata
║ ║ ║ values
║ ║ ◄───────────────────────╢
───────────────────────────────╢ hdata ║
║ ║ ───────────────────────╢
───────────────────────────────╢ hdata ║
create ║ msg: hda buffer ║ ║
buffers ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟───────────────────────
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟───────────────────────
║ ║ send data to buffer ║ send data
║ ║ ║ to buffer
║ ........ ║ ........ ║
║ ║ ║ signal
║ ║ ───────────────────────╢ received
───────────────────────────────╢ signal XXX ║ (hooked by
║ ║ ───────────────────────╢ received
───────────────────────────────╢ signal XXX ║ (hooked by
update ║ msg: id: "_buffer_..." ║ ║ relay)
buffers ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: ping ... ║ ║
║ ║ ║
───────────────────────────────╢ ║
───────────────────────────────╢ ║
measure ║ msg: id: "_pong" ... ║ ║
response ║ ║ ║
time ║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: quit ║ disconnect client ║
║ ║ ║
....

View File

@ -116,6 +116,12 @@
** valeurs: toute chaîne
** valeur par défaut: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** description: pass:none[liste des algorithmes de hachage pour l'authentification par mot de passe dans le protocole relay, parmi ces valeurs : "plain" (mot de passe en clair, non haché), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512" ; "*" signifie tous les algorithmes, un nom commençant par "!" est une valeur négative pour empêcher un algorithme d'être utilisé, le caractère joker "*" est autorisé dans les noms (exemples : "*", "pbkdf2*", "*,!plain")]
** type: chaîne
** valeurs: toute chaîne
** valeur par défaut: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** description: pass:none[temps maximum (en secondes) pour l'authentification du client ; la connexion est fermée si le client n'est toujours pas authentifié après ce délai et le statut est positionné à "échec d'authentification" (0 = attendre sans fin)]
** type: entier
@ -140,6 +146,12 @@
** valeurs: 0 .. 9
** valeur par défaut: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** description: pass:none[nombre d'itérations demandées au client dans le protocole weechat lorsqu'un mot de passe haché avec l'algorithme PBKDF2 est utilisé pour l'authentification ; plus d'itérations est mieux en terme de sécurité mais est plus lent à calculer ; ce nombre ne doit pas être trop élevé si votre micro-processeur est lent]
** type: entier
** valeurs: 1 .. 1000000
** valeur par défaut: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** description: pass:none[écouter en IPv6 sur le socket par défaut (en plus de l'IPv4 qui est par défaut) ; les protocoles IPv4 et IPv6 peuvent être forcés (individuellement ou ensemble) dans le nom du protocole (voir /help relay)]
** type: booléen
@ -152,6 +164,12 @@
** valeurs: 0 .. 2147483647
** valeur par défaut: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** description: pass:none[taille du nonce (en octets), généré lorsqu'un client se connecte ; le client doit utiliser ce nonce, concaténé au nonce client et au mot de passe pour hacher le mot de passe dans la commande "init" du protocole weechat]
** type: entier
** valeurs: 8 .. 128
** valeur par défaut: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** description: pass:none[mot de passe requis par les clients pour accéder à ce relai (une valeur vide indique que le mot de passe n'est pas nécessaire, voir l'option relay.network.allow_empty_password) (note : le contenu est évalué, voir /help eval)]
** type: chaîne

View File

@ -320,6 +320,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|       weechat-python-api.c | Fonctions de l'API script Python.
|    relay/ | Extension Relay (proxy IRC et relai pour des interfaces distantes).
|       relay.c | Fonctions principales de Relay.
|       relay-auth.c | Authentification des clients.
|       relay-buffer.c | Tampon Relay.
|       relay-client.c | Clients du relai.
|       relay-command.c | Commandes de Relay.
@ -380,48 +381,47 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
[width="100%",cols="1m,2",options="header"]
|===
| Chemin/fichier | Description
| tests/ | Racine des tests.
|    tests.cpp | Programme utilisé pour lancer tous les tests.
|    scripts/ | Racine des tests de l'API script.
|       test-scripts.cpp | Programme utilisé pour lancer les tests de l'API script.
|       python/ | Scripts Python pour générer et lancer les tests de l'API script.
|          testapigen.py | Script Python générant des scripts dans tous les languages pour tester l'API script.
|          testapi.py | Script Python avec les tests API, utilisé par le script testapigen.py.
|          unparse.py | Conversion de code Python vers d'autres langages, utilisé par le script testapigen.py.
|    unit/ | Racine des tests unitaires.
|       test-plugins.cpp | Tests : extensions.
|       core/ | Racine des tests unitaires pour le cœur.
|          test-core-arraylist.cpp | Tests : listes avec tableau (« arraylists »).
|          test-core-calc.cpp | Tests : calcul d'expressions.
|          test-core-crypto.cpp | Tests : fonctions cryptographiques.
|          test-core-eval.cpp | Tests : évaluation d'expressions.
|          test-core-hashtble.cpp | Tests : tables de hachage.
|          test-core-hdata.cpp | Tests : hdata.
|          test-core-hook.cpp | Tests : hooks.
|          test-core-infolist.cpp | Tests : infolists.
|          test-core-list.cpp | Tests : listes.
|          test-core-secure.cpp | Tests : données sécurisées.
|          test-core-string.cpp | Tests : chaînes.
|          test-core-url.cpp | Tests : URLs.
|          test-core-utf8.cpp | Tests : UTF-8.
|          test-core-util.cpp | Tests : fonctions utiles.
|       gui/ | Racine des tests unitaires pour les interfaces.
|          test-gui-color.cpp | Tests : couleurs.
|          test-gui-line.cpp | Tests : lignes.
|          test-gui-nick.cpp | Tests : pseudos.
|       plugins/ | Racine des tests unitaires pour les extensions.
|          irc/ | Racine des tests unitaires pour l'extension IRC.
|             test-irc-color.cpp | Tests : couleurs IRC.
|             test-irc-config.cpp | Tests : configuration IRC.
|             test-irc-ignore.cpp | Tests : ignores IRC.
|             test-irc-message.cpp | Tests : messages IRC.
|             test-irc-mode.cpp | Tests : modes IRC.
|             test-irc-nick.cpp | Tests : pseudos IRC.
|             test-irc-protocol.cpp | Tests : protocole IRC.
|          relay/ | Racine des tests unitaires pour l'extension Relay.
|             weechat/ | Racine des tests unitaires pour le protocole weechat.
|                test-relay-weechat-protocol.cpp | Tests : protocole weechat.
| Chemin/fichier | Description
| tests/ | Racine des tests.
|    tests.cpp | Programme utilisé pour lancer tous les tests.
|    scripts/ | Racine des tests de l'API script.
|       test-scripts.cpp | Programme utilisé pour lancer les tests de l'API script.
|       python/ | Scripts Python pour générer et lancer les tests de l'API script.
|          testapigen.py | Script Python générant des scripts dans tous les languages pour tester l'API script.
|          testapi.py | Script Python avec les tests API, utilisé par le script testapigen.py.
|          unparse.py | Conversion de code Python vers d'autres langages, utilisé par le script testapigen.py.
|    unit/ | Racine des tests unitaires.
|       test-plugins.cpp | Tests : extensions.
|       core/ | Racine des tests unitaires pour le cœur.
|          test-core-arraylist.cpp | Tests : listes avec tableau (« arraylists »).
|          test-core-calc.cpp | Tests : calcul d'expressions.
|          test-core-crypto.cpp | Tests : fonctions cryptographiques.
|          test-core-eval.cpp | Tests : évaluation d'expressions.
|          test-core-hashtble.cpp | Tests : tables de hachage.
|          test-core-hdata.cpp | Tests : hdata.
|          test-core-hook.cpp | Tests : hooks.
|          test-core-infolist.cpp | Tests : infolists.
|          test-core-list.cpp | Tests : listes.
|          test-core-secure.cpp | Tests : données sécurisées.
|          test-core-string.cpp | Tests : chaînes.
|          test-core-url.cpp | Tests : URLs.
|          test-core-utf8.cpp | Tests : UTF-8.
|          test-core-util.cpp | Tests : fonctions utiles.
|       gui/ | Racine des tests unitaires pour les interfaces.
|          test-gui-color.cpp | Tests : couleurs.
|          test-gui-line.cpp | Tests : lignes.
|          test-gui-nick.cpp | Tests : pseudos.
|       plugins/ | Racine des tests unitaires pour les extensions.
|          irc/ | Racine des tests unitaires pour l'extension IRC.
|             test-irc-color.cpp | Tests : couleurs IRC.
|             test-irc-config.cpp | Tests : configuration IRC.
|             test-irc-ignore.cpp | Tests : ignores IRC.
|             test-irc-message.cpp | Tests : messages IRC.
|             test-irc-mode.cpp | Tests : modes IRC.
|             test-irc-nick.cpp | Tests : pseudos IRC.
|             test-irc-protocol.cpp | Tests : protocole IRC.
|          relay/ | Racine des tests unitaires pour l'extension Relay.
|             test-relay-auth.cpp | Tests : authentification des clients.
|===
[[documentation_translations]]

View File

@ -36,11 +36,11 @@ Les _clients_ sont connectés au _relay_ comme dans le diagramme ci-dessous :
....
┌──────────┐ Station de travail
┌────────┐ ┌───┤ client 1 │ (Linux, Windows,
│ irc │──┐ ╔═══════════╤═══════╗ │ └──────────┘ BSD, macOS ...)
└────────┘ └──╢ │ ║───┘ ┌──────────┐
...... ║ WeeChat │ Relay ║───────┤ client 2 │ Appareil mobile
┌────────┐ ┌──╢ │ ║───┐ └──────────┘ (Android, iPhone ...)
│ jabber │──┘ ╚═══════════╧═══════╝ │ ......
│ irc │──┐ ╔═══════════╤═══════╗ │ └──────────┘ BSD, macOS ...)
└────────┘ └──╢ │ ║───┘ ┌──────────┐
...... ║ WeeChat │ Relay ║───────┤ client 2 │ Appareil mobile
┌────────┐ ┌──╢ │ ║───┐ └──────────┘ (Android, iPhone ...)
│ jabber │──┘ ╚═══════════╧═══════╝ │ ......
└────────┘ │ ┌──────────┐
...... └───┤ client N │ Autres appareils
└──────────┘
@ -91,24 +91,139 @@ Liste des commandes disponibles (détail dans les chapitres suivants) :
[width="80%",cols="^3m,14",options="header"]
|===
| Commande | Description
| init | Initialiser la connexion avec _relay_.
| hdata | Demander un _hdata_.
| info | Demander une _info_.
| infolist | Demander une _infolist_.
| nicklist | Demander une _nicklist_ (liste de pseudos).
| input | Envoyer des données à un tampon (texte ou commande).
| sync | Synchroniser un/des tampon(s) : recevoir les mises à jour pour le(s) tampon(s).
| desync | Désynchroniser un/des tampon(s) : stopper les mises à jour pour le(s) tampon(s).
| quit | Se déconnecter de _relay_.
| Commande | Description
| handshake | Poignée de main : préparer l'authentification du client et définir des options, avant la commande _init_.
| init | S'authentifier avec _relay_.
| hdata | Demander un _hdata_.
| info | Demander une _info_.
| infolist | Demander une _infolist_.
| nicklist | Demander une _nicklist_ (liste de pseudos).
| input | Envoyer des données à un tampon (texte ou commande).
| sync | Synchroniser un/des tampon(s) : recevoir les mises à jour pour le(s) tampon(s).
| desync | Désynchroniser un/des tampon(s) : stopper les mises à jour pour le(s) tampon(s).
| quit | Se déconnecter de _relay_.
|===
[[command_handshake]]
=== handshake
_WeeChat ≥ 2.9._
Effectuer une poignée de main entre le client et WeeChat : cela est obligatoire
dans la plupart des cas pour connaître les paramètres de la session et préparer
l'authentification avec la commande _init_.
La poignée de main peut être effectuée plusieurs fois avant la commande _init_,
même si cela est rarement nécessaire.
Syntaxe :
----
handshake [<option>=<valeur>,[<option>=<valeur>,...]]
----
Paramètres :
* _option_ : une des options suivantes :
** _password_ : liste d'algorithmes de hachage supportés par le client (séparés par
des deux-points), les valeurs autorisées sont :
*** _plain_ : mot de passe en clair (pas de hachage)
*** _sha256_ : mot de passe salé et haché avec l'algorithme SHA256
*** _sha512_ : mot de passe salé et haché avec l'algorithme SHA512
*** _pbkdf2+sha256_ : mot de passe salé et haché avec l'algorithme PBKDF2
(avec un hachage SHA256)
*** _pbkdf2+sha512_ : mot de passe salé et haché avec l'algorithme PBKDF2
(avec un hachage SHA512)
** _compression_ : type de compression :
*** _zlib_ : activer la compression _zlib_ pour les messages envoyés par _relay_
(activée par défaut si _relay_ supporte la compression _zlib_)
*** _off_ : désactiver la compression
Notes à propos de l'option _password_ :
* Si l'option _password_ n'est pas donnée (ou si la commande _handshake_ n'est
pas envoyée par le client), _relay_ utilise automatiquement l'authentification
_plain_ (si elle est autorisée côté _relay_).
* _Relay_ choisit l'algorithme le plus sûr disponible à la fois côté client et
_relay_, par ordre de priorité du premier (plus sûr) au dernier utilisé :
. _pbkdf2+sha512_
. _pbkdf2+sha256_
. _sha512_
. _sha256_
. _plain_
[NOTE]
Si l'option _password_ n'est pas donnée, WeeChat utilise automatiquement
l'authentification _plain_ (si autorisée par _relay_).
WeeChat répond avec une table de hachage qui contient les clés et valeurs
suivantes :
* _auth_password_ : l'authentification mot de passe négociée : supportée par le
client et _relay_ :
** (valeur vide) : la négociation a échoué, l'authentification par mot de passe
n'est *PAS* possible
** _plain_
** _sha256_
** _sha512_
** _pbkdf2+sha256_
** _pbkdf2+sha512_
* _hash_iterations_ : nombre d'itérations pour le hachage (pour l'algorithme
PBKDF2 seulement)
* _totp_:
** _on_ : le mot de passe à usage unique basé sur le temps (TOTP : Time-based
One-Time Password) est configuré et est attendu dans la commande _init_
** _off_ : le mot de passe à usage unique basé sur le temps (TOTP : Time-based
One-Time Password) n'est pas activé et pas nécessaire dans la commande _init_
* _nonce_ : un tampon d'octets non prédictibles, envoyé en hexadécimal, pour
empêcher les attaques par rejeu ; si _auth_password_ est un algorithme de
hachage, le client doit calculer le mot de passe haché avec ce nonce,
concaténé avec un nonce client et le mot de passe utilisateur (le nonce
_relay_ + le nonce client constituent le sel utilisé dans l'algorithme de
hachage du mot de passe)
Exemples :
----
# rien d'offert par le client (ou seulement "plain"), l'authentification par mot de passe "plain" sera utilisée si autorisée côté relay
handshake
handshake password=plain
# seulement plain, sha256 et pbkdf2+sha256 sont supportés par le client
handshake password=plain:sha256:pbkdf2+sha256
----
Exemple de réponse :
[source,python]
----
id: 'handshake'
htb: {'auth_password': 'pbkdf2+sha256', 'hash_iterations': '100000', 'totp': 'on', 'nonce': '85B1EE00695A5B254E14F4885538DF0D'}
----
Le client peut s'authentifier avec cette commande (voir la <<command_init,commande init>>),
le sel est le nonce _relay_ + "ABCD" ("41424344" en hexadécimal) :
----
init password_hash=pbkdf2+sha256:85b1ee00695a5b254e14f4885538df0d41424344:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[TIP]
Avec WeeChat ≤ 2.8, la commande _handshake_ n'est pas implémentée, WeeChat ignore
silencieusement cette commande, même si elle est envoyée avant la commande _init_. +
Il est donc sûr d'envoyer cette commande à n'importe quelle version de WeeChat.
[[command_init]]
=== init
Initialiser la connexion avec _relay_. Il doit s'agir de la première commande
envoyée à _relay_. Si elle n'est pas envoyée, _relay_ coupera la connexion à la
première commande reçue, sans avertissement.
_Mis à jour dans les versions 2.4, 2.8, 2.9._
S'authentifier avec _relay_.
Il doit s'agir de la première commande envoyée à _relay_ (seule la commande
_handshake_ peut être envoyée avant _init_). +
Si elle n'est pas envoyée, _relay_ coupera la connexion à la première commande
reçue, sans avertissement.
Syntaxe :
@ -128,7 +243,9 @@ Paramètres :
One-Time Password) utilisé comme second facteur d'authentification, en plus
du mot de passe (option _relay.network.totp_secret_ dans WeeChat)
_(WeeChat ≥ 2.4)_
** _compression_ : type de compression :
** _compression_ : type de compression (*obsolète* depuis la version 2.9, gardé
pour des raisons de compatibilité mais devrait être envoyé dans la
<<command_handshake,commande handshake>>) :
*** _zlib_ : activer la compression _zlib_ pour les messages envoyés par _relay_
(activée par défaut si _relay_ supporte la compression _zlib_)
*** _off_ : désactiver la compression
@ -140,13 +257,28 @@ par exemple `init password=foo\,bar` pour envoyer le mot de passe "foo,bar".
Le format du mot de passe haché est l'un des suivants, où _hash_ est le mot
de passe haché en hexadécimal :
* `+sha256:hash+`
* `+sha512:hash+`
* `+pbkdf2:algorithme:sel:itérations:hash+` avec :
** _algorithme_ : _sha256_ ou _sha512_
** _sel_ : sel (hexadécimal)
* `+sha256:sel:hash+` avec :
** _sel_ : sel (hexadécimal), qui doit démarrer avec le nonce de _relay_,
concaténé au nonce client
** _hash_ : le sel et mot de passe haché (hexadécimal)
* `+sha512:sel:hash+` avec :
** _sel_ : sel (hexadécimal), qui doit démarrer avec le nonce de _relay_,
concaténé au nonce client
** _hash_ : le set et mot de passe haché (hexadécimal)
* `+pbkdf2+sha256:sel:itérations:hash+` avec :
** _sel_ : sel (hexadécimal), qui doit démarrer avec le nonce de _relay_,
concaténé au nonce client
** _iterations_ : nombre d'itérations
** _hash_ : le mot de passe haché (hexadécimal)
** _hash_ : le sel et mot de passe haché avec l'algorithme SHA256 (hexadécimal)
* `+pbkdf2+sha256:sel:itérations:hash+` avec :
** _sel_ : sel (hexadécimal), qui doit démarrer avec le nonce de _relay_,
concaténé au nonce client
** _iterations_ : nombre d'itérations
** _hash_ : le sel et mot de passe haché avec l'algorithme SHA512 (hexadécimal)
[NOTE]
Les chaînes en hexadécimal peuvent être en minuscules ou majuscules, _relay_
peut décoder les deux.
Exemples :
@ -163,14 +295,14 @@ init password=mypass,totp=123456
# initialiser et désactiver la compression
init password=mypass,compression=off
# initialiser avec un mot de passe haché (SHA256) (WeeChat ≥ 2.8)
init password_hash=sha256:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialiser avec un mot de passe haché (SHA256 : sel="nonce:cnonce") (WeeChat ≥ 2.9)
init password_hash=sha256:6e6f6e63653a636e6f6e6365:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialiser avec un mot de passe haché (SHA512) (WeeChat ≥ 2.8)
init password_hash=sha512:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialiser avec un mot de passe haché (SHA512 : sel="nonce:cnonce") (WeeChat ≥ 2.9)
init password_hash=sha512:6e6f6e63653a636e6f6e6365:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialiser avec un mot de passe haché (PBKDF2: SHA256, sel="ABCDEFGHIJKLMNOP", 100000 itérations) (WeeChat ≥ 2.8)
init password_hash=pbkdf2:sha256:4142434445464748494a4b4c4d4e4f50:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
# initialiser avec un mot de passe haché (PBKDF2 : SHA256, sel="nonce:cnonce", 100000 itérations) (WeeChat ≥ 2.9)
init password_hash=pbkdf2:sha256:6e6f6e63653a636e6f6e6365:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[[command_hdata]]
@ -1415,7 +1547,7 @@ Exemple :
....
┌────┐
│ 41 │ ──── 65 (0x41: "A")
│ 41 │ ──── 65 (0x41: "A")
└────┘
....
@ -1431,11 +1563,11 @@ Exemples :
....
┌────┬────┬────┬────┐
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
└────┴────┴────┴────┘
┌────┬────┬────┬────┐
│ FF │ FE │ 1D │ C0 │ ──── -123456
│ FF │ FE │ 1D │ C0 │ ──── -123456
└────┴────┴────┴────┘
....
@ -1451,13 +1583,13 @@ Exemples :
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
long. '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └────────────────────────────────────────────────────┘
long. '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
@ -1473,7 +1605,7 @@ Exemple :
....
┌────┬────┬────┬────╥────┬────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
└────┴────┴────┴────╨────┴────┴────┴────┴────┘
└─────────────────┘ └──────────────────────┘
longueur 'h' 'e' 'l' 'l' 'o'
@ -1483,7 +1615,7 @@ Une chaîne vide a une longueur de zéro :
....
┌────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 00 │ ──── ""
│ 00 │ 00 │ 00 │ 00 │ ──── ""
└────┴────┴────┴────┘
└─────────────────┘
longueur
@ -1493,7 +1625,7 @@ Une chaîne _NULL_ (pointeur NULL en C) a une longueur de -1 :
....
┌────┬────┬────┬────┐
│ FF │ FF │ FF │ FF │ ──── NULL
│ FF │ FF │ FF │ FF │ ──── NULL
└────┴────┴────┴────┘
└─────────────────┘
longueur
@ -1515,7 +1647,7 @@ Exemple :
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └──────────────────────────────────────────┘
long. '1' 'a' '2' 'b' '3' 'c' '4' 'd' '5'
@ -1525,7 +1657,7 @@ Un pointeur _NULL_ a une longueur de 1 avec la valeur 0 :
....
┌────╥────┐
│ 01 ║ 00 │ ──── NULL (0x0)
│ 01 ║ 00 │ ──── NULL (0x0)
└────╨────┘
└──┘ └──┘
long. 0
@ -1541,7 +1673,7 @@ Exemple :
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
long. '1' '3' '2' '1' '9' '9' '3' '4' '5' '6'
@ -1564,7 +1696,7 @@ Exemple :
....
┌─────┬─────┬───╥──────┬─────╥──────┬─────┐
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
└─────┴─────┴───╨──────┴─────╨──────┴─────┘ 'key2' => 'def' }
└───┘ └───┘ └─┘ └──────────┘ └──────────┘
type type nombre élément 1 élément 2
@ -1796,7 +1928,7 @@ Exemple de tableau avec deux chaînes de caractères :
type nombre de chaînes longueur
──╥────┬────┬────╥────┬────┬────┬────╥────┬────┐
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
──╨────┴────┴────╨────┴────┴────┴────╨────┴────┘
└────────────┘ └─────────────────┘ └───────┘
'a' 'b' 'c' longueur 'd' 'e'
@ -1812,7 +1944,7 @@ Exemple de tableau avec trois entiers :
type nombre d'entiers 123 (0x7B)
──╥────┬────┬────┬────╥────┬────┬────┬────┐
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
──╨────┴────┴────┴────╨────┴────┴────┴────┘
└─────────────────┘ └─────────────────┘
456 (0x1C8) 789 (0x315)
@ -1822,7 +1954,7 @@ Un tableau _NULL_ :
....
┌─────╥────┬────┬────┬────┐
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
└─────╨────┴────┴────┴────┘
└───┘ └─────────────────┘
type nombre de chaînes
@ -1836,43 +1968,49 @@ Un tableau _NULL_ :
│ Client ├ ─ ─ ─ ─ (réseau)─ ─ ─ ─ ┤ Relay ├────────────────┤ WeeChat │
└────────┘ └───────┘ └─────────┘
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ ouverture socket ║ ajout du client ║
║ ║ ║
╟───────────────────────────────► ║ ║
║ cmd: init password=xxx,... ║ init/autoriser client ║
╟───────────────────────────────▶ ║ ║
║ cmd: handshake password=xxx,... ║ négociation algos ║
║ ║ et options ║
║ ◀───────────────────────────────╢ ║
║ msg: id: "handshake" ... ║ ║
║ ║ ║
╟───────────────────────────────► ║ ║
║ cmd: hdata buffer ... ╟───────────────────────► ║
╟───────────────────────────────▶ ║ ║
║ cmd: init password=xxx,... ║ authentification ║
║ ║ client ║
╟───────────────────────────────▶ ║ ║
║ cmd: hdata buffer ... ╟───────────────────────▶ ║
║ sync ... ║ demande de hdata ║ lecture
║ ║ ║ valeurs
║ ║ ◄───────────────────────╢ hdata
───────────────────────────────╢ hdata ║
║ ║ ───────────────────────╢ hdata
───────────────────────────────╢ hdata ║
créat° ║ msg: hda buffer ║ ║
tampons ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟───────────────────────
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟───────────────────────
║ ║ envoi données au tampon ║ envoi données
║ ║ ║ au tampon
║ ........ ║ ........ ║
║ ║ ║ signal
║ ║ ───────────────────────╢ reçu
───────────────────────────────╢ signal XXX ║ (accroché
║ ║ ───────────────────────╢ reçu
───────────────────────────────╢ signal XXX ║ (accroché
MAJ ║ msg: id: "_buffer_..." ║ ║ par relay)
tampons ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: ping ... ║ ║
║ ║ ║
───────────────────────────────╢ ║
───────────────────────────────╢ ║
mesure ║ msg: id: "_pong" ... ║ ║
temps ║ ║ ║
réponse ║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: quit ║ déconnexion du client ║
║ ║ ║
....

View File

@ -116,6 +116,12 @@
** valori: qualsiasi stringa
** valore predefinito: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** descrizione: pass:none[comma separated list of hash algorithms used for password authentication in weechat protocol, among these values: "plain" (password in plain text, not hashed), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512"), "*" means all algorithms, a name beginning with "!" is a negative value to prevent an algorithm from being used, wildcard "*" is allowed in names (examples: "*", "pbkdf2*", "*,!plain")]
** tipo: stringa
** valori: qualsiasi stringa
** valore predefinito: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** descrizione: pass:none[timeout (in seconds) for client authentication: connection is closed if the client is still not authenticated after this delay and the client status is set to "authentication failed" (0 = wait forever)]
** tipo: intero
@ -140,6 +146,12 @@
** valori: 0 .. 9
** valore predefinito: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** descrizione: pass:none[number of iterations asked to the client in weechat protocol when a hashed password with algorithm PBKDF2 is used for authentication; more iterations is better in term of security but is slower to compute; this number should not be too high if your CPU is slow]
** tipo: intero
** valori: 1 .. 1000000
** valore predefinito: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** descrizione: pass:none[listen on IPv6 socket by default (in addition to IPv4 which is default); protocols IPv4 and IPv6 can be forced (individually or together) in the protocol name (see /help relay)]
** tipo: bool
@ -152,6 +164,12 @@
** valori: 0 .. 2147483647
** valore predefinito: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** descrizione: pass:none[size of nonce (in bytes), generated when a client connects; the client must use this nonce, concatenated to the client nonce and the password when hashing the password in the "init" command of the weechat protocol]
** tipo: intero
** valori: 8 .. 128
** valore predefinito: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** descrizione: pass:none[password required by clients to access this relay (empty value means no password required, see option relay.network.allow_empty_password) (note: content is evaluated, see /help eval)]
** tipo: stringa

View File

@ -116,6 +116,12 @@
** 値: 未制約文字列
** デフォルト値: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** 説明: pass:none[comma separated list of hash algorithms used for password authentication in weechat protocol, among these values: "plain" (password in plain text, not hashed), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512"), "*" means all algorithms, a name beginning with "!" is a negative value to prevent an algorithm from being used, wildcard "*" is allowed in names (examples: "*", "pbkdf2*", "*,!plain")]
** タイプ: 文字列
** 値: 未制約文字列
** デフォルト値: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** 説明: pass:none[timeout (in seconds) for client authentication: connection is closed if the client is still not authenticated after this delay and the client status is set to "authentication failed" (0 = wait forever)]
** タイプ: 整数
@ -140,6 +146,12 @@
** 値: 0 .. 9
** デフォルト値: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** 説明: pass:none[number of iterations asked to the client in weechat protocol when a hashed password with algorithm PBKDF2 is used for authentication; more iterations is better in term of security but is slower to compute; this number should not be too high if your CPU is slow]
** タイプ: 整数
** 値: 1 .. 1000000
** デフォルト値: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** 説明: pass:none[デフォルトで IPv6 ソケットをリッスン (デフォルトの IPv4 に加えて); 特定のプロトコルでプロトコルに IPv4 と IPv6 (個別または両方) を強制 (/help relay を参照してください)]
** タイプ: ブール
@ -152,6 +164,12 @@
** 値: 0 .. 2147483647
** デフォルト値: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** 説明: pass:none[size of nonce (in bytes), generated when a client connects; the client must use this nonce, concatenated to the client nonce and the password when hashing the password in the "init" command of the weechat protocol]
** タイプ: 整数
** 値: 8 .. 128
** デフォルト値: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** 説明: pass:none[このリレーを利用するためにクライアントが必要なパスワード (空の場合パスワードなし、オプション relay.network.allow_empty_password を参照してください) (注意: 値は評価されます、/help eval を参照してください)]
** タイプ: 文字列

View File

@ -327,6 +327,8 @@ WeeChat "core" は以下のディレクトリに配置されています:
|       weechat-python-api.c | python スクリプト作成 API 関数
|    relay/ | relay プラグイン (IRC プロキシとリモートインターフェースへの中継)
|       relay.c | relay の主要関数
// TRANSLATION MISSING
|       relay-auth.c | Clients authentification.
|       relay-buffer.c | relay バッファ
|       relay-client.c | relay クライアント
|       relay-command.c | relay コマンド
@ -387,60 +389,58 @@ WeeChat "core" は以下のディレクトリに配置されています:
[width="100%",cols="1m,2",options="header"]
|===
| パス/ファイル名 | 説明
| tests/ | テスト用のルートディレクトリ
|    tests.cpp | 全テストの実行時に使われるプログラム
|    scripts/ | スクリプト API テスト用のルートディレクトリ
|       test-scripts.cpp | スクリプト API テストの実行時に使われるプログラム
|       python/ | スクリプト API テストを生成、実行する Python スクリプト
|          testapigen.py | スクリプト API のテスト時にすべての言語に関するスクリプトを生成する Python スクリプト
|          testapi.py | スクリプト API テスト時に使われる Python スクリプト (スクリプト testapigen.py から使われます)
|          unparse.py | Python コードを別の言語に変換 (スクリプト testapigen.py から使われます)
|    unit/ | 単体テスト用のルートディレクトリ
|       test-plugins.cpp | テスト: プラグイン
|       core/ | core 向け単体テスト用のルートディレクトリ
|          test-core-arraylist.cpp | テスト: 配列リスト
| パス/ファイル名 | 説明
| tests/ | テスト用のルートディレクトリ
|    tests.cpp | 全テストの実行時に使われるプログラム
|    scripts/ | スクリプト API テスト用のルートディレクトリ
|       test-scripts.cpp | スクリプト API テストの実行時に使われるプログラム
|       python/ | スクリプト API テストを生成、実行する Python スクリプト
|          testapigen.py | スクリプト API のテスト時にすべての言語に関するスクリプトを生成する Python スクリプト
|          testapi.py | スクリプト API テスト時に使われる Python スクリプト (スクリプト testapigen.py から使われます)
|          unparse.py | Python コードを別の言語に変換 (スクリプト testapigen.py から使われます)
|    unit/ | 単体テスト用のルートディレクトリ
|       test-plugins.cpp | テスト: プラグイン
|       core/ | core 向け単体テスト用のルートディレクトリ
|          test-core-arraylist.cpp | テスト: 配列リスト
// TRANSLATION MISSING
|          test-core-calc.cpp | Tests: calculation of expressions.
|          test-core-calc.cpp | Tests: calculation of expressions.
// TRANSLATION MISSING
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | テスト: 式の評価
|          test-core-hashtble.cpp | テスト: ハッシュテーブル
|          test-core-hdata.cpp | テスト: hdata
|          test-core-hook.cpp | テスト: フック
|          test-core-infolist.cpp | テスト: インフォリスト
|          test-core-list.cpp | テスト: リスト
|          test-core-secure.cpp | テスト: データ保護
|          test-core-string.cpp | テスト: 文字列
|          test-core-url.cpp | テスト: URL
|          test-core-utf8.cpp | テスト: UTF-8
|          test-core-util.cpp | テスト: ユーティリティ関数
|       gui/ | インターフェースの単体テストを収める最上位ディレクトリ
|          test-core-crypto.cpp | Tests: cryptographic functions.
|          test-core-eval.cpp | テスト: 式の評価
|          test-core-hashtble.cpp | テスト: ハッシュテーブル
|          test-core-hdata.cpp | テスト: hdata
|          test-core-hook.cpp | テスト: フック
|          test-core-infolist.cpp | テスト: インフォリスト
|          test-core-list.cpp | テスト: リスト
|          test-core-secure.cpp | テスト: データ保護
|          test-core-string.cpp | テスト: 文字列
|          test-core-url.cpp | テスト: URL
|          test-core-utf8.cpp | テスト: UTF-8
|          test-core-util.cpp | テスト: ユーティリティ関数
|       gui/ | インターフェースの単体テストを収める最上位ディレクトリ
// TRANSLATION MISSING
|          test-gui-color.cpp | Tests: colors.
|          test-gui-line.cpp | テスト: 行
|          test-gui-color.cpp | Tests: colors.
|          test-gui-line.cpp | テスト: 行
// TRANSLATION MISSING
|          test-gui-nick.cpp | テスト: nicks
|       plugins/ | プラグインの単体テストを収める最上位ディレクトリ
|          irc/ | IRC プラグインの単体テストを収める最上位ディレクトリ
|          test-gui-nick.cpp | テスト: nicks
|       plugins/ | プラグインの単体テストを収める最上位ディレクトリ
|          irc/ | IRC プラグインの単体テストを収める最上位ディレクトリ
// TRANSLATION MISSING
|             test-irc-color.cpp | Tests: IRC colors.
|             test-irc-config.cpp | テスト: IRC 設定
|             test-irc-color.cpp | Tests: IRC colors.
|             test-irc-config.cpp | テスト: IRC 設定
// TRANSLATION MISSING
|             test-irc-ignore.cpp | Tests: IRC ignores.
|             test-irc-ignore.cpp | Tests: IRC ignores.
// TRANSLATION MISSING
|             test-irc-message.cpp | Tests: IRC messages.
|             test-irc-message.cpp | Tests: IRC messages.
// TRANSLATION MISSING
|             test-irc-mode.cpp | Tests: IRC modes.
|             test-irc-mode.cpp | Tests: IRC modes.
// TRANSLATION MISSING
|             test-irc-nick.cpp | Tests: IRC nicks.
|             test-irc-protocol.cpp | テスト: IRC プロトコル
|             test-irc-nick.cpp | Tests: IRC nicks.
|             test-irc-protocol.cpp | テスト: IRC プロトコル
// TRANSLATION MISSING
|          relay/ | Root of unit tests for Relay plugin.
|          relay/ | Root of unit tests for Relay plugin.
// TRANSLATION MISSING
|             weechat/ | Root of unit tests for weechat protocol.
// TRANSLATION MISSING
|                test-relay-weechat-protocol.cpp | Tests: weechat protocol.
|             test-relay-auth.cpp | Tests: clients authentication.
|===
[[documentation_translations]]

View File

@ -39,11 +39,11 @@
....
┌────────────────┐ ワークステーション
┌────────┐ ┌───┤ クライアント 1 │ (Linux、Windows、
│ irc │──┐ ╔═══════════╤════════╗ │ └────────────────┘ BSD、macOS ...)
└────────┘ └──╢ │ ║───┘ ┌────────────────┐
...... ║ WeeChat │ リレー ║───────┤ クライアント 2 │ 携帯デバイス
┌────────┐ ┌──╢ │ ║───┐ └────────────────┘ (Android、iPhone ...)
│ jabber │──┘ ╚═══════════╧════════╝ │ ......
│ irc │──┐ ╔═══════════╤════════╗ │ └────────────────┘ BSD、macOS ...)
└────────┘ └──╢ │ ║───┘ ┌────────────────┐
...... ║ WeeChat │ リレー ║───────┤ クライアント 2 │ 携帯デバイス
┌────────┐ ┌──╢ │ ║───┐ └────────────────┘ (Android、iPhone ...)
│ jabber │──┘ ╚═══════════╧════════╝ │ ......
└────────┘ │ ┌────────────────┐
...... └───┤ クライアント N │ その他のデバイス
└────────────────┘
@ -93,24 +93,134 @@ _リレー_ プラグインは _IRC プロキシ_ のように振舞います (
[width="80%",cols="^3m,14",options="header"]
|===
| コマンド | 説明
| init | _リレー_ 接続を初期化
| hdata | _hdata_ を要求
| info | _インフォ_ を要求
| infolist | _インフォリスト_ を要求
| nicklist | _ニックネームリスト_ を要求
| input | バッファにデータを送信 (テキストまたはコマンド)
| sync | バッファを同期: バッファの最新情報を取得
| desync | バッファを非同期: バッファの更新を止める
| quit | _リレー_ から切断
| コマンド | 説明
// TRANSLATION MISSING
| handshake | Handshake: prepare client authentication and set options, before _init_ command.
| init | _リレー_ 接続を初期化
| hdata | _hdata_ を要求
| info | _インフォ_ を要求
| infolist | _インフォリスト_ を要求
| nicklist | _ニックネームリスト_ を要求
| input | バッファにデータを送信 (テキストまたはコマンド)
| sync | バッファを同期: バッファの最新情報を取得
| desync | バッファを非同期: バッファの更新を止める
| quit | _リレー_ から切断
|===
// TRANSLATION MISSING
[[command_handshake]]
=== handshake
_WeeChat ≥ 2.9._
Perform an handshake between the client and WeeChat: this is required in most
cases to know the session settings and prepare the authentication with the
_init_ command.
The handshake can be performed multiple times before the _init_ command,
although it is rarely needed.
Syntax:
----
handshake [<option>=<value>,[<option>=<value>,...]]
----
Arguments:
* _option_: one of following options:
** _password_: list of hash algorithms supported by the client (separated by colons),
allowed values are:
*** _plain_: plain text password (no hash)
*** _sha256_: password salted and hashed with SHA256 algorithm
*** _sha512_: password salted and hashed with SHA512 algorithm
*** _pbkdf2+sha256_: password salted and hashed with PBKDF2 algorithm (using SHA256 hash)
*** _pbkdf2+sha512_: password salted and hashed with PBKDF2 algorithm (using SHA512 hash)
** _compression_: compression type:
*** _zlib_: enable _zlib_ compression for messages sent by _relay_
(enabled by default if _relay_ supports _zlib_ compression)
*** _off_: disable compression
Notes about option _password_:
* If the option is not given (of if the _handshake_ command is not sent by the
client), _relay_ uses automatically _plain_ authentication (if allowed on
_relay_ side).
* _Relay_ chooses the safest algorithm available on both client and _relay_,
by order of priority from first (safest) to last used:
. _pbkdf2+sha512_
. _pbkdf2+sha256_
. _sha512_
. _sha256_
. _plain_
WeeChat replies with a hashtable containing the following keys and values:
* _auth_password_: the password authentication negotiated: supported by both
the client and _relay_:
** (empty value): negotiation failed, password authentication is *NOT* possible
** _plain_
** _sha256_
** _sha512_
** _pbkdf2+sha256_
** _pbkdf2+sha512_
* _hash_iterations_: number of iterations for hash (for the PBKDF2 algorithm only)
* _totp_:
** _on_: Time-based One-Time Password (TOTP) is configured and expected
in the _init_ command
** _off_: Time-based One-Time Password (TOTP) is not enabled and not needed
in the _init_ command
* _nonce_: a buffer of unpredictable bytes, sent as hexadecimal, to prevent
replay attacks; if _auth_password_ is a hash algorithm, the client must compute
the hash of password on this nonce, concatenated with a client nonce and the
user password (the _relay_ nonce + the client nonce is the salt used in the
password hash algorithm)
Examples:
----
# nothing offered by the client (or only "plain"), authentication password "plain" will be used if allowed on relay side
handshake
handshake password=plain
# only plain, sha256 and pbkdf2+sha256 are supported by the client
handshake password=plain:sha256:pbkdf2+sha256
----
Example of response:
[source,python]
----
id: 'handshake'
htb: {'auth_password': 'pbkdf2+sha256', 'hash_iterations': '100000', 'totp': 'on', 'nonce': '85B1EE00695A5B254E14F4885538DF0D'}
----
The client can authenticate with this command (see <<command_init,init command>>),
the salt is the _relay_ nonce + "ABCD" ("41424344" in hexadecimal):
----
init password_hash=pbkdf2+sha256:85b1ee00695a5b254e14f4885538df0d41424344:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[TIP]
With WeeChat ≤ 2.8, the command _handshake_ is not implemented, WeeChat silently
ignores this command, even if it is sent before the _init_ command. +
So it is safe to send this command to any WeeChat version.
[[command_init]]
=== init
_リレー_ 接続を初期化。_リレー_ に送るコマンドは必ずこのコマンドから始めてください。_リレー_
がこのコマンドを受信していない場合、_リレー_
は最初のコマンドを受け取った時点で警告無しに接続を閉じます。
// TRANSLATION MISSING
_Updated in versions 2.4, 2.8, 2.9._
// TRANSLATION MISSING
Authenticate with _relay_.
// TRANSLATION MISSING
This must be first command sent to _relay_ (only _handshake_ command can be sent
before _init_). +
If not sent, _relay_ will close connection on first command received (except
_handshake_), without warning.
構文:
@ -130,7 +240,10 @@ init [<option>=<value>,[<option>=<value>,...]]
** _totp_: パスワードに加えた二要素認証で利用する時間ベースのワンタイムパスワード (TOTP)
(WeeChat の _relay.network.totp_secret_ オプション)
_(WeeChat バージョン 2.4 で利用可能)_
** _compression_: 圧縮タイプ:
// TRANSLATION MISSING
** _compression_: 圧縮タイプ (*deprecated* since version 2.9, it is kept
for compatibility reasons but should be sent in the
<<command_handshake,handshake command>>):
*** _zlib_: _リレー_ から受信するメッセージに対して _zlib_ 圧縮を使う
(_リレー_ が _zlib_ 圧縮をサポートしている場合、デフォルトで有効化されます)
*** _off_: 圧縮を使わない
@ -143,13 +256,27 @@ WeeChat バージョン 1.6 以上の場合、コンマをエスケープする
Format of hashed password is one of the following, where _hash_ is the hashed
password as hexadecimal:
* `+sha256:hash+`
* `+sha512:hash+`
* `+pbkdf2:algorithm:salt:iterations:hash+` with:
** _algorithm_: _sha256_ or _sha512_
** _salt_: salt (hexadecimal)
* `+sha256:salt:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _hash_: the hashed salt + password (hexadecimal)
* `+sha512:salt:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _hash_: the hashed salt + password (hexadecimal)
* `+pbkdf2+sha256:salt:iterations:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _iterations_: number of iterations
** _hash_: the hashed password (hexadecimal)
** _hash_: the hashed salt + password with SHA256 algorithm (hexadecimal)
* `+pbkdf2+sha512:salt:iterations:hash+` with:
** _salt_: salt (hexadecimal), which must start with the server nonce,
concatenated to the client nonce
** _iterations_: number of iterations
** _hash_: the hashed salt + password with SHA512 algorithm (hexadecimal)
[NOTE]
Hexadecimal strings can be lower or upper case, _relay_ can decode both.
// TRANSLATION MISSING
例:
@ -167,14 +294,14 @@ init password=mypass,totp=123456
# 圧縮を使わない例
init password=mypass,compression=off
# initialize with hashed password (SHA256) (WeeChat バージョン 2.8 以上の場合)
init password_hash=sha256:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialize with hashed password (SHA256: salt="nonce:cnonce") (WeeChat バージョン 2.9 以上の場合)
init password_hash=sha256:6e6f6e63653a636e6f6e6365:b9a4c3393dfac4330736684510378851e581c68add8eca84110c31a33e694676
# initialize with hashed password (SHA512) (WeeChat バージョン 2.8 以上の場合)
init password_hash=sha512:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialize with hashed password (SHA512: salt="nonce:cnonce") (WeeChat バージョン 2.9 以上の場合)
init password_hash=sha512:6e6f6e63653a636e6f6e6365:4469190d4e0d1fdc0afb6f408d9873c89b8ce89cc4db79fe058255c55ad6821fa5e9bb068f9e578c8ae7cc825d85ff99c439d59e439bc589d95620a1e6b8ae6e
# initialize with hashed password (PBKDF2: SHA256, salt="ABCDEFGHIJKLMNOP", 100000 iterations) (WeeChat バージョン 2.8 以上の場合)
init password_hash=pbkdf2:sha256:4142434445464748494a4b4c4d4e4f50:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
# initialize with hashed password (PBKDF2: SHA256, salt="nonce:cnonce", 100000 iterations) (WeeChat バージョン 2.9 以上の場合)
init password_hash=pbkdf2+sha256:6e6f6e63653a636e6f6e6365:100000:01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc945a1c
----
[[command_hdata]]
@ -1397,7 +1524,7 @@ _WeeChat バージョン 0.3.8 以上で利用可。_
....
┌────┐
│ 41 │ ──── 65 (0x41: "A")
│ 41 │ ──── 65 (0x41: "A")
└────┘
....
@ -1413,11 +1540,11 @@ _WeeChat バージョン 0.3.8 以上で利用可。_
....
┌────┬────┬────┬────┐
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
│ 00 │ 01 │ E2 │ 40 │ ──── 123456
└────┴────┴────┴────┘
┌────┬────┬────┬────┐
│ FF │ FE │ 1D │ C0 │ ──── -123456
│ FF │ FE │ 1D │ C0 │ ──── -123456
└────┴────┴────┴────┘
....
@ -1432,13 +1559,13 @@ _WeeChat バージョン 0.3.8 以上で利用可。_
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── 1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
length '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ──── -1234567890
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └────────────────────────────────────────────────────┘
length '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
@ -1453,7 +1580,7 @@ length '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
....
┌────┬────┬────┬────╥────┬────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ──── "hello"
└────┴────┴────┴────╨────┴────┴────┴────┴────┘
└─────────────────┘ └──────────────────────┘
length 'h' 'e' 'l' 'l' 'o'
@ -1463,7 +1590,7 @@ length '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
....
┌────┬────┬────┬────┐
│ 00 │ 00 │ 00 │ 00 │ ──── ""
│ 00 │ 00 │ 00 │ 00 │ ──── ""
└────┴────┴────┴────┘
└─────────────────┘
length
@ -1473,7 +1600,7 @@ _NULL_ 文字列 (C 言語の NULL ポインタ) を表現するにはの長さ
....
┌────┬────┬────┬────┐
│ FF │ FF │ FF │ FF │ ──── NULL
│ FF │ FF │ FF │ FF │ ──── NULL
└────┴────┴────┴────┘
└─────────────────┘
length
@ -1493,7 +1620,7 @@ _NULL_ 文字列 (C 言語の NULL ポインタ) を表現するにはの長さ
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ──── 0x1a2b3c4d5
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └──────────────────────────────────────────┘
length '1' 'a' '2' 'b' '3' 'c' '4' 'd' '5'
@ -1503,7 +1630,7 @@ _NULL_ ポインタを表現するには長さを 1 で値を 0 にしてくだ
....
┌────╥────┐
│ 01 ║ 00 │ ──── NULL (0x0)
│ 01 ║ 00 │ ──── NULL (0x0)
└────╨────┘
└──┘ └──┘
length 0
@ -1518,7 +1645,7 @@ length 0
....
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ──── 1321993456
└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
└──┘ └───────────────────────────────────────────────┘
length '1' '3' '2' '1' '9' '9' '3' '4' '5' '6'
@ -1540,7 +1667,7 @@ length '1' '3' '2' '1' '9' '9' '3' '4' '5' '6'
....
┌─────┬─────┬───╥──────┬─────╥──────┬─────┐
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ──── { 'key1' => 'abc',
└─────┴─────┴───╨──────┴─────╨──────┴─────┘ 'key2' => 'def' }
└───┘ └───┘ └─┘ └──────────┘ └──────────┘
type type count item 1 item 2
@ -1767,7 +1894,7 @@ infolist buffer
type number of strings length
──╥────┬────┬────╥────┬────┬────┬────╥────┬────┐
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ──── [ "abc", "de" ]
──╨────┴────┴────╨────┴────┴────┴────╨────┴────┘
└────────────┘ └─────────────────┘ └───────┘
'a' 'b' 'c' length 'd' 'e'
@ -1783,7 +1910,7 @@ infolist buffer
type number of integers 123 (0x7B)
──╥────┬────┬────┬────╥────┬────┬────┬────┐
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ──── [ 123, 456, 789 ]
──╨────┴────┴────┴────╨────┴────┴────┴────┘
└─────────────────┘ └─────────────────┘
456 (0x1C8) 789 (0x315)
@ -1793,7 +1920,7 @@ _NULL_ 配列:
....
┌─────╥────┬────┬────┬────┐
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
│ str ║ 00 │ 00 │ 00 │ 00 │ ──── NULL
└─────╨────┴────┴────┴────┘
└───┘ └─────────────────┘
type number of strings
@ -1802,48 +1929,55 @@ _NULL_ 配列:
[[typical_session]]
== 典型的なセッション
// TRANSLATION MISSING
....
┌──────────────┐ ┌────────┐ ┌─────────┐
│ クライアント ├ ─(ネットワーク)─ ┤ リレー ├──────────────────┤ WeeChat │
└──────────────┘ └────────┘ └─────────┘
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ ソケットをオープン ║ クライアントを追加 ║
║ ║ ║
╟───────────────────────────────► ║ ║
╟───────────────────────────────▶ ║ ║
║ cmd: handshake password=xxx,... ║ negotiate algos ║
║ ║ and options ║
║ ◀───────────────────────────────╢ ║
║ msg: id: "handshake" ... ║ ║
║ ║ ║
╟───────────────────────────────▶ ║ ║
║ cmd: init password=xxx,... ║ クライアントを初期化/許可 ║
║ ║ ║
╟───────────────────────────────► ║ ║
║ cmd: hdata buffer ... ╟─────────────────────────► ║
╟─────────────────────────────── ║ ║
║ cmd: hdata buffer ... ╟─────────────────────────
║ sync ... ║ hdata の要求 ║ hdata
║ ║ ║ の値を読み出し
║ ║ ─────────────────────────╢
───────────────────────────────╢ hdata ║
║ ║ ─────────────────────────╢
───────────────────────────────╢ hdata ║
バッファ ║ msg: hda buffer ║ ║
を作成 ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟─────────────────────────
╟─────────────────────────────── ║ ║
║ cmd: input ... ╟─────────────────────────
║ ║ バッファにデータを送信 ║ バッファに
║ ║ ║ データを送信
║ ........ ║ ........ ║
║ ║ ║ シグナル
║ ║ ─────────────────────────╢ の受信
───────────────────────────────╢ シグナル XXX ║ (リレー
║ ║ ─────────────────────────╢ の受信
───────────────────────────────╢ シグナル XXX ║ (リレー
バッファ ║ msg: id: "_buffer_..." ║ ║ がフック)
を更新 ║ ║ ║
║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: ping ... ║ ║
║ ║ ║
───────────────────────────────╢ ║
───────────────────────────────╢ ║
応答 ║ msg: id: "_pong" ... ║ ║
時間 ║ ║ ║
を計測 ║ ........ ║ ........ ║
║ ║ ║
╟─────────────────────────────── ║ ║
╟─────────────────────────────── ║ ║
║ cmd: quit ║ クライアントを切断 ║
║ ║ ║
....

View File

@ -116,6 +116,12 @@
** wartości: dowolny ciąg
** domyślna wartość: `+""+`
* [[option_relay.network.auth_password]] *relay.network.auth_password*
** opis: pass:none[comma separated list of hash algorithms used for password authentication in weechat protocol, among these values: "plain" (password in plain text, not hashed), "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512"), "*" means all algorithms, a name beginning with "!" is a negative value to prevent an algorithm from being used, wildcard "*" is allowed in names (examples: "*", "pbkdf2*", "*,!plain")]
** typ: ciąg
** wartości: dowolny ciąg
** domyślna wartość: `+"*"+`
* [[option_relay.network.auth_timeout]] *relay.network.auth_timeout*
** opis: pass:none[timeout (in seconds) for client authentication: connection is closed if the client is still not authenticated after this delay and the client status is set to "authentication failed" (0 = wait forever)]
** typ: liczba
@ -140,6 +146,12 @@
** wartości: 0 .. 9
** domyślna wartość: `+6+`
* [[option_relay.network.hash_iterations]] *relay.network.hash_iterations*
** opis: pass:none[number of iterations asked to the client in weechat protocol when a hashed password with algorithm PBKDF2 is used for authentication; more iterations is better in term of security but is slower to compute; this number should not be too high if your CPU is slow]
** typ: liczba
** wartości: 1 .. 1000000
** domyślna wartość: `+100000+`
* [[option_relay.network.ipv6]] *relay.network.ipv6*
** opis: pass:none[nasłuchuj domyślnie na gnieździe IPv6 (w dodatku do domyślnego IPv4); protokoły IPv4 i IPv6 mogą być wymuszane (pojedynczo lub razem) w nazwie protokołu (zobacz /help relay)]
** typ: bool
@ -152,6 +164,12 @@
** wartości: 0 .. 2147483647
** domyślna wartość: `+5+`
* [[option_relay.network.nonce_size]] *relay.network.nonce_size*
** opis: pass:none[size of nonce (in bytes), generated when a client connects; the client must use this nonce, concatenated to the client nonce and the password when hashing the password in the "init" command of the weechat protocol]
** typ: liczba
** wartości: 8 .. 128
** domyślna wartość: `+16+`
* [[option_relay.network.password]] *relay.network.password*
** opis: pass:none[hasło wymagane od klientów do połączenia z tym pośrednikiem (pusta wartość oznacza brak hasła, zobacz opcję relay.network.allow_empty_password) (uwaga: zawartość jest przetwarzana, zobacz /help eval)]
** typ: ciąg

View File

@ -305,6 +305,8 @@
./src/plugins/python/weechat-python.h
./src/plugins/relay/irc/relay-irc.c
./src/plugins/relay/irc/relay-irc.h
./src/plugins/relay/relay-auth.c
./src/plugins/relay/relay-auth.h
./src/plugins/relay/relay-buffer.c
./src/plugins/relay/relay-buffer.h
./src/plugins/relay/relay.c

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Ondřej Súkup <mimi.vx@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -11019,6 +11019,20 @@ msgid ""
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgstr ""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"čárkou rozdělený seznam pluginů pro automatické načtení při spuštění \"*\" "
"znamená všechny nalezené pluginy, jméno začínající \"!\" je negativní "
"hodnota k zabránění načtení pluginu, jména mohou začínat nebo končit \"*\" "
"pro vybrání několika pluginů (příklady: \"*\" nebo \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -11043,6 +11057,13 @@ msgid ""
"disable compression, 1 = low compression ... 9 = best compression)"
msgstr ""
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -11053,6 +11074,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "maximální počet klientů připojených k portu"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
#, fuzzy
msgid ""
"password required by clients to access this relay (empty value means no "

View File

@ -24,7 +24,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-04-03 20:03+0200\n"
"Last-Translator: Nils Görs <weechatter@arcor.de>\n"
"Language-Team: German <kde-i18n-de@kde.org>\n"
@ -12965,6 +12965,21 @@ msgstr ""
"Kleinschreibung zu unterscheiden muss die Zeichenkette mit \"(?-i)\" "
"eingeleitet werden), Beispiele: \"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"durch Kommata getrennte Liste der Erweiterungen, die beim Programmstart "
"automatisch geladen werden sollen; \"*\" lädt alle vorhandenen "
"Erweiterungen. Beginnt der Name hingegen mit \"!\" wird die Erweiterung "
"nicht geladen. Im Namen der Erweiterung kann der Platzhalter \"*\" verwendet "
"werden (Beispiele: \"*\" oder \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -12994,6 +13009,13 @@ msgstr ""
"gesendet werden sollen (0 = Kompression deaktiviert, 1 = niedrige "
"Kompression ... 9 = stärkste Kompression)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -13009,6 +13031,12 @@ msgstr ""
"maximale Anzahl an Clients die mit einem Port verbunden sein dürfen (0 = "
"keine Begrenzung)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -11364,6 +11364,20 @@ msgstr ""
"mapeada a IPv6 (como: \"::ffff:127.0.0.1\"), ejemplo: \"^((::ffff:)?"
"123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"lista de plugins separados por comas para cargar automáticamente al iniciar, "
"\"*\" significa todos los plugins encontrados, un nombre empezando con \"!\" "
"previene que el plugin se cargue, nombres pueden empezar o terminar con \"*"
"\" para indicar varios plugins (ejemplo: \"*\" o \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -11390,6 +11404,13 @@ msgstr ""
"nivel de compresión para paquetes enviados al cliente con el protocolo "
"WeeChat (0 = sin compresión, 1 = baja compresión ... 9 = mejor compresión)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -11400,6 +11421,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "número máximo de clientes conectados a un puerto"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
#, fuzzy
msgid ""
"password required by clients to access this relay (empty value means no "

View File

@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"PO-Revision-Date: 2020-04-12 20:24+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-04-14 21:29+0200\n"
"Last-Translator: Sébastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
"Language: fr\n"
@ -12693,6 +12693,22 @@ msgstr ""
"(insensible à la casse, utilisez \"(?-i)\" en début de chaîne pour la rendre "
"insensible à la casse), exemple : \"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"liste des algorithmes de hachage pour l'authentification par mot de passe "
"dans le protocole relay, parmi ces valeurs : \"plain\" (mot de passe en "
"clair, non haché), \"sha256\", \"sha512\", \"pbkdf2+sha256\", "
"\"pbkdf2+sha512\" ; \"*\" signifie tous les algorithmes, un nom commençant "
"par \"!\" est une valeur négative pour empêcher un algorithme d'être "
"utilisé, le caractère joker \"*\" est autorisé dans les noms (exemples : \"*"
"\", \"pbkdf2*\", \"*,!plain\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -12725,6 +12741,18 @@ msgstr ""
"WeeChat (0 = désactiver la compression, 1 = peu de compression ... 9 = "
"meilleure compression)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
"nombre d'itérations demandées au client dans le protocole weechat lorsqu'un "
"mot de passe haché avec l'algorithme PBKDF2 est utilisé pour "
"l'authentification ; plus d'itérations est mieux en terme de sécurité mais "
"est plus lent à calculer ; ce nombre ne doit pas être trop élevé si votre "
"micro-processeur est lent"
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -12738,6 +12766,15 @@ msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr ""
"nombre maximum de clients qui se connectent sur un port (0 = pas de limite)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
"taille du nonce (en octets), généré lorsqu'un client se connecte ; le client "
"doit utiliser ce nonce, concaténé au nonce client et au mot de passe pour "
"hacher le mot de passe dans la commande \"init\" du protocole weechat"
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -10365,6 +10365,19 @@ msgid ""
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgstr ""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"automatikusan betöltendő modulok vesszővel elválasztott listája, \"*\" "
"esetén az összes fellelt modul (az elnevezés lehet részleges, például a "
"\"perl\" elegendő \"libperl.so\" helyett)"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -10386,6 +10399,13 @@ msgid ""
"disable compression, 1 = low compression ... 9 = best compression)"
msgstr ""
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -10397,6 +10417,12 @@ msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr ""
"felhasználói parancsok maximális száma az előzményekben (0 = korlátlan)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Esteban I. Ruiz Moreno <exio4.com@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -11565,6 +11565,21 @@ msgstr ""
"ffff:127.0.0.1\",come: \"::ffff:127.0.0.1\"), esempio: \"^((::ffff:)?"
"123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"elenco separato da virgole di plugin da caricare automaticamente all'avvio, "
"\"*\" equivale a tutti i plugin trovati. un nome che comincia con \"!\" è un "
"valore negativo per impedire il caricamento di un plugin, i nomi possono "
"iniziare o finire con \"*\" per corrispondere a più plugin (esempi: \"*\" "
"oppure \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -11592,6 +11607,13 @@ msgstr ""
"WeeChat (0 = disabilita compressione, 1 = compressione bassa ... 9 = "
"compressione migliore)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -11602,6 +11624,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "numero massimo di client connessi ad una porta"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
#, fuzzy
msgid ""
"password required by clients to access this relay (empty value means no "

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: AYANOKOUZI, Ryuunosuke <i38w7i3@yahoo.co.jp>\n"
"Language-Team: Japanese <https://github.com/l/weechat/tree/master/"
@ -12196,6 +12196,19 @@ msgstr ""
"し、最初に \"(?-i)\" をつければ区別有り)、例: \"^(123\\.45\\.67\\.89|"
"192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"スタートアップ時にロードするプラグインのコンマ区切りリスト、\"*\" は見つかっ"
"た全てのプラグイン、\"!\" から始まる名前はロードしないプラグイン、名前にワイ"
"ルドカード \"*\" を使うことができます (例: \"*\" または \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -12223,6 +12236,13 @@ msgstr ""
"WeeChat プロトコルでクライアントに送信するパケットの圧縮レベル (0 = 圧縮しな"
"い、1 = 低圧縮 ... 9 = 高圧縮)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -12235,6 +12255,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "ポートに接続するクライアントの最大数 (0 = 制限なし)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-04-05 13:44+0200\n"
"Last-Translator: Krzysztof Korościk <soltys@soltys.info>\n"
"Language-Team: Polish <kde-i18n-doc@kde.org>\n"
@ -12414,6 +12414,20 @@ msgstr ""
"początku sprawi, że wielość znaków będzie miała znaczenie), przykład: "
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"oddzielona przecinkami lista wtyczek do automatycznego załadowania podczas "
"startu, \"*\" oznacza wszystkie znalezione wtyczki, nazwa zaczynająca się od "
"\"!\" powoduje nie ładowanie tej wtyczki, wildcard \"*\" jest dozwolony w "
"nazwach (przykłady: \"*\" lub \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -12442,6 +12456,13 @@ msgstr ""
"stopień kompresji pakietów wysyłanych do klienta za pomocą protokołu WeeChat "
"(0 = kompresja wyłączona, 1 = niska kompresja ... 9 = najwyższa kompresja)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -12454,6 +12475,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "maksymalna ilość klientów łączących się na port (0 = brak limitu)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Vasco Almeida <vascomalmeida@sapo.pt>\n"
"Language-Team: Portuguese <>\n"
@ -12012,6 +12012,21 @@ msgstr ""
"(não destinge maiúscula e minúscula, use \"(?-i)\" no início para "
"distinguir), exemplo: \"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"lista de plugins separados por vírgula para carregar automaticamente ao "
"iniciar, \"*\" significa todos os plugins encontrados, um nome começado com "
"\"!\" serve de valor negativo para impedir que o plugin seja carregado, pode-"
"se usar o caráter universal \"*\" nos nomes (exemplos: \"*\" ou \"*,!lua,!tcl"
"\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -12040,6 +12055,13 @@ msgstr ""
"WeeChat (0 = desativar compressão, 1 = compressão reduzida ... 9 = "
"compressão ótima)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -12052,6 +12074,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "número máximo de clientes que se conectam a uma porta (0 = sem limite)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2019-11-03 08:38+0100\n"
"Last-Translator: Eduardo Elias <camponez@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -10814,6 +10814,21 @@ msgstr ""
"expressão regular com IPs permitidos a usar o relay, por exemplo: "
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"lista separada por vírgulas dos plugins para carregar automaticamente "
"nainicialização, \"*\" significa todos os plugins encontrados, um nome "
"começando com \"!\" é um valor negativo para prevenir um plugin de ser "
"carrgado, nomes podem começar ou terminar com \"*\" para casar com vários "
"plugins (exemplos: \"*\" ou \"*,!lua,!tcl\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -10840,6 +10855,13 @@ msgstr ""
"WeeChat (0 = desabilitar compressão, 1 = compressão baixa ... 9 = melhor "
"compressão)"
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -10850,6 +10872,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "número máximo de clientes conectando-se a uma porta"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
#, fuzzy
msgid ""
"password required by clients to access this relay (empty value means no "

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2020-03-08 14:22+0100\n"
"Last-Translator: Aleksey V Zapparov AKA ixti <ixti@member.fsf.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -10401,6 +10401,19 @@ msgid ""
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgstr ""
#, fuzzy
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
"разделённый запятыми список автоматически загружаемых при запуске plug-"
"in'ов , \"*\" означает все найденные plug-in'ы (имена могут быть не полными, "
"например \"perl\" успешно загрузит \"libperl.so\")"
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -10422,6 +10435,13 @@ msgid ""
"disable compression, 1 = low compression ... 9 = best compression)"
msgstr ""
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -10432,6 +10452,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr "максимальное количество команд в истории (0 = не ограничено)"
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -306,6 +306,8 @@ SET(WEECHAT_SOURCES
./src/plugins/python/weechat-python.h
./src/plugins/relay/irc/relay-irc.c
./src/plugins/relay/irc/relay-irc.h
./src/plugins/relay/relay-auth.c
./src/plugins/relay/relay-auth.h
./src/plugins/relay/relay-buffer.c
./src/plugins/relay/relay-buffer.h
./src/plugins/relay/relay.c

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2019-11-03 08:38+0100\n"
"Last-Translator: Hasan Kiran <sunder67@hotmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -9453,6 +9453,15 @@ msgid ""
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgstr ""
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -9474,6 +9483,13 @@ msgid ""
"disable compression, 1 = low compression ... 9 = best compression)"
msgstr ""
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -9483,6 +9499,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr ""
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2020-04-12 20:23+0200\n"
"POT-Creation-Date: 2020-04-14 21:29+0200\n"
"PO-Revision-Date: 2014-08-16 10:27+0200\n"
"Last-Translator: Sébastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -9314,6 +9314,15 @@ msgid ""
"\"^(123\\.45\\.67\\.89|192\\.160\\..*)$\""
msgstr ""
msgid ""
"comma separated list of hash algorithms used for password authentication in "
"weechat protocol, among these values: \"plain\" (password in plain text, not "
"hashed), \"sha256\", \"sha512\", \"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*"
"\" means all algorithms, a name beginning with \"!\" is a negative value to "
"prevent an algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"
msgstr ""
msgid ""
"timeout (in seconds) for client authentication: connection is closed if the "
"client is still not authenticated after this delay and the client status is "
@ -9335,6 +9344,13 @@ msgid ""
"disable compression, 1 = low compression ... 9 = best compression)"
msgstr ""
msgid ""
"number of iterations asked to the client in weechat protocol when a hashed "
"password with algorithm PBKDF2 is used for authentication; more iterations "
"is better in term of security but is slower to compute; this number should "
"not be too high if your CPU is slow"
msgstr ""
msgid ""
"listen on IPv6 socket by default (in addition to IPv4 which is default); "
"protocols IPv4 and IPv6 can be forced (individually or together) in the "
@ -9344,6 +9360,12 @@ msgstr ""
msgid "maximum number of clients connecting to a port (0 = no limit)"
msgstr ""
msgid ""
"size of nonce (in bytes), generated when a client connects; the client must "
"use this nonce, concatenated to the client nonce and the password when "
"hashing the password in the \"init\" command of the weechat protocol"
msgstr ""
msgid ""
"password required by clients to access this relay (empty value means no "
"password required, see option relay.network.allow_empty_password) (note: "

View File

@ -19,13 +19,9 @@
add_library(relay MODULE
relay.c relay.h
relay-auth.c relay-auth.h
relay-buffer.c relay-buffer.h
relay-client.c relay-client.h
irc/relay-irc.c irc/relay-irc.h
weechat/relay-weechat.c weechat/relay-weechat.h
weechat/relay-weechat-msg.c weechat/relay-weechat-msg.h
weechat/relay-weechat-nicklist.c weechat/relay-weechat-nicklist.h
weechat/relay-weechat-protocol.c weechat/relay-weechat-protocol.h
relay-command.c relay-command.h
relay-completion.c relay-completion.h
relay-config.c relay-config.h
@ -35,6 +31,13 @@ add_library(relay MODULE
relay-server.c relay-server.h
relay-upgrade.c relay-upgrade.h
relay-websocket.c relay-websocket.h
# irc relay
irc/relay-irc.c irc/relay-irc.h
# weechat relay
weechat/relay-weechat.c weechat/relay-weechat.h
weechat/relay-weechat-msg.c weechat/relay-weechat-msg.h
weechat/relay-weechat-nicklist.c weechat/relay-weechat-nicklist.h
weechat/relay-weechat-protocol.c weechat/relay-weechat-protocol.h
)
set_target_properties(relay PROPERTIES PREFIX "")

View File

@ -25,20 +25,12 @@ lib_LTLIBRARIES = relay.la
relay_la_SOURCES = relay.c \
relay.h \
relay-auth.c \
relay-auth.h \
relay-buffer.c \
relay-buffer.h \
relay-client.c \
relay-client.h \
irc/relay-irc.c \
irc/relay-irc.h \
weechat/relay-weechat.c \
weechat/relay-weechat.h \
weechat/relay-weechat-msg.c \
weechat/relay-weechat-msg.h \
weechat/relay-weechat-nicklist.c \
weechat/relay-weechat-nicklist.h \
weechat/relay-weechat-protocol.c \
weechat/relay-weechat-protocol.h \
relay-command.c \
relay-command.h \
relay-completion.c \
@ -56,7 +48,17 @@ relay_la_SOURCES = relay.c \
relay-upgrade.c \
relay-upgrade.h \
relay-websocket.c \
relay-websocket.h
relay-websocket.h \
irc/relay-irc.c \
irc/relay-irc.h \
weechat/relay-weechat.c \
weechat/relay-weechat.h \
weechat/relay-weechat-msg.c \
weechat/relay-weechat-msg.h \
weechat/relay-weechat-nicklist.c \
weechat/relay-weechat-nicklist.h \
weechat/relay-weechat-protocol.c \
weechat/relay-weechat-protocol.h
relay_la_LDFLAGS = -module -no-undefined
relay_la_LIBADD = $(RELAY_LFLAGS) $(ZLIB_LFLAGS) $(GNUTLS_LFLAGS)

View File

@ -0,0 +1,458 @@
/*
* relay-auth.c - relay client authentication
*
* Copyright (C) 2003-2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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 3 of the License, or
* (at your option) any later version.
*
* WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gcrypt.h>
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-auth.h"
#include "relay-client.h"
#include "relay-config.h"
/*
* this list is sorted from the least secure to the safest algorithm:
* "plain" is plain text password, the other values are hash algorithms;
* during negotiation with the client, the highest value in this list matching
* the client supported values is used
*/
char *relay_auth_password_name[] =
{ "plain", "sha256", "sha512", "pbkdf2+sha256", "pbkdf2+sha512" };
/*
* Searches for a password authentication.
*
* Returns index in enum t_relay_auth_password,
* -1 if password authentication is not found.
*/
int
relay_auth_password_search (const char *name)
{
int i;
for (i = 0; i < RELAY_NUM_PASSWORD_AUTHS; i++)
{
if (strcmp (relay_auth_password_name[i], name) == 0)
return i;
}
/* authentication password type found */
return -1;
}
/*
* Generates a nonce: a buffer of unpredictable bytes
*
* Note: result must be freed after use.
*/
char *
relay_auth_generate_nonce ()
{
int size;
char *nonce, *nonce_hexa;
size = weechat_config_integer (relay_config_network_nonce_size);
nonce = malloc (size);
if (!nonce)
return NULL;
nonce_hexa = malloc ((size * 2) + 1);
if (!nonce_hexa)
{
free (nonce);
return NULL;
}
gcry_create_nonce ((unsigned char *)nonce, size);
weechat_string_base_encode (16, nonce, size, nonce_hexa);
free (nonce);
return nonce_hexa;
}
/*
* Checks if password received as plain text is valid.
*
* Returns:
* 1: password is valid
* 0: password is not valid
*/
int
relay_auth_check_password_plain (const char *password,
const char *relay_password)
{
if (!password || !relay_password)
return 0;
return (strcmp (password, relay_password) == 0) ? 1 : 0;
}
/*
* Authenticates with password (plain text).
*
* Returns:
* 1: authentication OK
* 0: authentication failed
*/
int
relay_auth_password (struct t_relay_client *client,
const char *password, const char *relay_password)
{
if (client->auth_password != RELAY_AUTH_PASSWORD_PLAIN)
return 0;
return relay_auth_check_password_plain (password, relay_password);
}
/*
* Parses SHA256 or SHA512 parameters from string with format:
*
* salt:hash
*
* where:
*
* salt is the salt in hexadecimal
* hash is the hashed password with the parameters above, in hexadecimal
*/
void
relay_auth_parse_sha (const char *parameters,
char **salt_hexa, char **salt, int *salt_size,
char **hash)
{
char **argv;
int argc;
*salt_hexa = NULL;
*salt = NULL;
*salt_size = 0;
*hash = NULL;
if (!parameters)
return;
argv = weechat_string_split (parameters, ":", NULL, 0, 0, &argc);
if (!argv || (argc < 2))
{
/* not enough parameters */
if (argv)
weechat_string_free_split (argv);
return;
}
/* parameter 1: salt */
*salt = malloc (strlen (argv[0]) + 1);
if (*salt)
{
*salt_size = weechat_string_base_decode (16, argv[0], *salt);
if (*salt_size > 0)
*salt_hexa = strdup (argv[0]);
else
{
free (*salt);
*salt = NULL;
}
}
/* parameter 2: the SHA256 or SHA512 hash */
*hash = strdup (argv[1]);
weechat_string_free_split (argv);
}
/*
* Parses PBKDF2 parameters from string with format:
*
* salt:iterations:hash
*
* where:
*
* salt is the salt in hexadecimal
* iterations it the number of iterations ( 1)
* hash is the hashed password with the parameters above, in hexadecimal
*/
void
relay_auth_parse_pbkdf2 (const char *parameters,
char **salt_hexa, char **salt, int *salt_size,
int *iterations, char **hash)
{
char **argv, *error;
int argc;
*salt_hexa = NULL;
*salt = NULL;
*salt_size = 0;
*iterations = 0;
*hash = NULL;
if (!parameters)
return;
argv = weechat_string_split (parameters, ":", NULL, 0, 0, &argc);
if (!argv || (argc < 3))
{
/* not enough parameters */
if (argv)
weechat_string_free_split (argv);
return;
}
/* parameter 1: salt */
*salt = malloc (strlen (argv[0]) + 1);
if (*salt)
{
*salt_size = weechat_string_base_decode (16, argv[0], *salt);
if (*salt_size > 0)
*salt_hexa = strdup (argv[0]);
else
{
free (*salt);
*salt = NULL;
}
}
/* parameter 2: iterations */
*iterations = (int)strtol (argv[1], &error, 10);
if (!error || error[0])
*iterations = 0;
/* parameter 3: the PBKDF2 hash */
*hash = strdup (argv[2]);
weechat_string_free_split (argv);
}
/*
* Checks if the salt received from the client is valid.
*
* It is valid if both conditions are true:
* 1. the salt is longer than the server nonce, so it means it includes a
* client nonce
* 2. the salt begins with the server nonce (client->nonce)
*
* Returns:
* 1: salt is valid
* 0: salt is not valid
*/
int
relay_auth_check_salt (struct t_relay_client *client, const char *salt_hexa)
{
return (salt_hexa
&& client->nonce
&& (strlen (salt_hexa) > strlen (client->nonce))
&& (weechat_strncasecmp (salt_hexa, client->nonce,
strlen (client->nonce)) == 0)) ? 1 : 0;
}
/*
* Checks if password received as SHA256/SHA512 hash is valid.
*
* Returns:
* 1: password is valid
* 0: password is not valid
*/
int
relay_auth_check_hash_sha (const char *hash_algo,
const char *salt,
int salt_size,
const char *hash_sha,
const char *relay_password)
{
char *salt_password, hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
int rc, length, hash_size;
rc = 0;
if (salt && (salt_size > 0) && hash_sha)
{
length = salt_size + strlen (relay_password);
salt_password = malloc (length);
if (salt_password)
{
memcpy (salt_password, salt, salt_size);
memcpy (salt_password + salt_size, relay_password,
strlen (relay_password));
if (weechat_crypto_hash (salt_password, length,
hash_algo,
hash, &hash_size))
{
weechat_string_base_encode (16, hash, hash_size,
hash_hexa);
if (weechat_strcasecmp (hash_hexa, hash_sha) == 0)
rc = 1;
}
free (salt_password);
}
}
return rc;
}
/*
* Checks if password received as PBKDF2 hash is valid.
*
* Returns:
* 1: password is valid
* 0: password is not valid
*/
int
relay_auth_check_hash_pbkdf2 (const char *hash_pbkdf2_algo,
const char *salt,
int salt_size,
int iterations,
const char *hash_pbkdf2,
const char *relay_password)
{
char hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
int rc, hash_size;
rc = 0;
if (hash_pbkdf2_algo && salt && (salt_size > 0) && hash_pbkdf2)
{
if (weechat_crypto_hash_pbkdf2 (relay_password,
strlen (relay_password),
hash_pbkdf2_algo,
salt, salt_size,
iterations,
hash, &hash_size))
{
weechat_string_base_encode (16, hash, hash_size, hash_hexa);
if (weechat_strcasecmp (hash_hexa, hash_pbkdf2) == 0)
rc = 1;
}
}
return rc;
}
/*
* Authenticates with password hash.
*
* Returns:
* 1: authentication OK
* 0: authentication failed
*/
int
relay_auth_password_hash (struct t_relay_client *client,
const char *hashed_password, const char *relay_password)
{
const char *pos_hash;
char *str_hash_algo;
char *hash_pbkdf2_algo, *salt_hexa, *salt, *hash_sha, *hash_pbkdf2;
int rc, auth_password, salt_size, iterations;
rc = 0;
str_hash_algo = NULL;
/* no authentication supported at all? */
if (client->auth_password < 0)
goto end;
if (!hashed_password || !relay_password)
goto end;
pos_hash = strchr (hashed_password, ':');
if (!pos_hash)
goto end;
str_hash_algo = weechat_strndup (hashed_password,
pos_hash - hashed_password);
if (!str_hash_algo)
goto end;
pos_hash++;
auth_password = relay_auth_password_search (str_hash_algo);
if (auth_password != client->auth_password)
goto end;
switch (auth_password)
{
case RELAY_AUTH_PASSWORD_SHA256:
case RELAY_AUTH_PASSWORD_SHA512:
relay_auth_parse_sha (pos_hash, &salt_hexa, &salt, &salt_size,
&hash_sha);
if (relay_auth_check_salt (client, salt_hexa)
&& relay_auth_check_hash_sha (str_hash_algo, salt, salt_size,
hash_sha, relay_password))
{
rc = 1;
}
if (salt_hexa)
free (salt_hexa);
if (salt)
free (salt);
if (hash_sha)
free (hash_sha);
break;
case RELAY_AUTH_PASSWORD_PBKDF2_SHA256:
case RELAY_AUTH_PASSWORD_PBKDF2_SHA512:
hash_pbkdf2_algo = strdup (str_hash_algo + 7);
relay_auth_parse_pbkdf2 (pos_hash, &salt_hexa, &salt, &salt_size,
&iterations, &hash_pbkdf2);
if ((iterations == client->hash_iterations)
&& relay_auth_check_salt (client, salt_hexa)
&& relay_auth_check_hash_pbkdf2 (hash_pbkdf2_algo, salt,
salt_size, iterations,
hash_pbkdf2, relay_password))
{
rc = 1;
}
if (hash_pbkdf2_algo)
free (hash_pbkdf2_algo);
if (salt_hexa)
free (salt_hexa);
if (salt)
free (salt);
if (hash_pbkdf2)
free (hash_pbkdf2);
break;
case RELAY_NUM_PASSWORD_AUTHS:
break;
}
end:
if (str_hash_algo)
free (str_hash_algo);
return rc;
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2003-2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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 3 of the License, or
* (at your option) any later version.
*
* WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_RELAY_AUTH_H
#define WEECHAT_PLUGIN_RELAY_AUTH_H
struct t_relay_client;
enum t_relay_auth_password
{
RELAY_AUTH_PASSWORD_PLAIN = 0,
RELAY_AUTH_PASSWORD_SHA256,
RELAY_AUTH_PASSWORD_SHA512,
RELAY_AUTH_PASSWORD_PBKDF2_SHA256,
RELAY_AUTH_PASSWORD_PBKDF2_SHA512,
/* number of password auths */
RELAY_NUM_PASSWORD_AUTHS,
};
extern char *relay_auth_password_name[];
extern int relay_auth_password_search (const char *name);
extern char *relay_auth_generate_nonce ();
extern int relay_auth_check_password_plain (const char *password,
const char *relay_password);
extern int relay_auth_password (struct t_relay_client *client,
const char *password,
const char *relay_password);
extern void relay_auth_parse_sha (const char *parameters,
char **salt_hexa,
char **salt,
int *salt_size,
char **hash);
extern void relay_auth_parse_pbkdf2 (const char *parameters,
char **salt_hexa,
char **salt,
int *salt_size,
int *iterations,
char **hash);
extern int relay_auth_check_salt (struct t_relay_client *client,
const char *salt_hexa);
extern int relay_auth_check_hash_sha (const char *hash_algo,
const char *salt,
int salt_size,
const char *hash_sha,
const char *relay_password);
extern int relay_auth_check_hash_pbkdf2 (const char *hash_pbkdf2_algo,
const char *salt,
int salt_size,
int iterations,
const char *hash_pbkdf2,
const char *relay_password);
extern int relay_auth_password_hash (struct t_relay_client *client,
const char *hashed_password,
const char *relay_password);
#endif /* WEECHAT_PLUGIN_RELAY_AUTH_H */

View File

@ -36,14 +36,15 @@
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-client.h"
#include "irc/relay-irc.h"
#include "weechat/relay-weechat.h"
#include "relay-auth.h"
#include "relay-config.h"
#include "relay-buffer.h"
#include "relay-network.h"
#include "relay-raw.h"
#include "relay-server.h"
#include "relay-websocket.h"
#include "irc/relay-irc.h"
#include "weechat/relay-weechat.h"
char *relay_client_status_string[] = /* status strings for display */
@ -1269,6 +1270,7 @@ struct t_relay_client *
relay_client_new (int sock, const char *address, struct t_relay_server *server)
{
struct t_relay_client *new_client;
int plain_text_password;
#ifdef HAVE_GNUTLS
int bits;
struct t_config_option *ptr_option;
@ -1295,6 +1297,14 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
new_client->protocol = server->protocol;
new_client->protocol_string = (server->protocol_string) ? strdup (server->protocol_string) : NULL;
new_client->protocol_args = (server->protocol_args) ? strdup (server->protocol_args) : NULL;
plain_text_password = weechat_string_match_list (
relay_auth_password_name[0],
(const char **)relay_config_network_auth_password_list,
1);
new_client->auth_password = (plain_text_password) ? 0 : -1;
new_client->hash_iterations = weechat_config_integer (
relay_config_network_hash_iterations);
new_client->nonce = relay_auth_generate_nonce ();
new_client->listen_start_time = server->start_time;
new_client->start_time = time (NULL);
new_client->end_time = 0;
@ -1496,6 +1506,22 @@ relay_client_new_with_infolist (struct t_infolist *infolist)
new_client->protocol_string = (str) ? strdup (str) : NULL;
str = weechat_infolist_string (infolist, "protocol_args");
new_client->protocol_args = (str) ? strdup (str) : NULL;
/* "auth_password" is new in WeeChat 2.9 */
if (weechat_infolist_search_var (infolist, "auth_password"))
new_client->auth_password = weechat_infolist_integer (infolist, "auth_password");
else
new_client->auth_password = RELAY_AUTH_PASSWORD_PLAIN;
/* "hash_iterations" is new in WeeChat 2.9 */
if (weechat_infolist_search_var (infolist, "hash_iterations"))
new_client->hash_iterations = weechat_infolist_integer (infolist, "hash_iterations");
else
new_client->hash_iterations = weechat_config_integer (
relay_config_network_hash_iterations);
/* "nonce" is new in WeeChat 2.9 */
if (weechat_infolist_search_var (infolist, "nonce"))
new_client->nonce = strdup (weechat_infolist_string (infolist, "nonce"));
else
new_client->nonce = relay_auth_generate_nonce ();
new_client->listen_start_time = weechat_infolist_time (infolist, "listen_start_time");
new_client->start_time = weechat_infolist_time (infolist, "start_time");
new_client->end_time = weechat_infolist_time (infolist, "end_time");
@ -1693,6 +1719,8 @@ relay_client_free (struct t_relay_client *client)
free (client->protocol_string);
if (client->protocol_args)
free (client->protocol_args);
if (client->nonce)
free (client->nonce);
#ifdef HAVE_GNUTLS
if (client->hook_timer_handshake)
weechat_unhook (client->hook_timer_handshake);
@ -1829,6 +1857,12 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "protocol_args", client->protocol_args))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "auth_password", client->auth_password))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "hash_iterations", client->hash_iterations))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "nonce", client->nonce))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "listen_start_time", client->listen_start_time))
return 0;
if (!weechat_infolist_new_var_time (ptr_item, "start_time", client->start_time))
@ -1905,6 +1939,12 @@ relay_client_print_log ()
relay_protocol_string[ptr_client->protocol]);
weechat_log_printf (" protocol_string . . . : '%s'", ptr_client->protocol_string);
weechat_log_printf (" protocol_args . . . . : '%s'", ptr_client->protocol_args);
weechat_log_printf (" auth_password . . . . : %d (%s)",
ptr_client->auth_password,
(ptr_client->auth_password >= 0) ?
relay_auth_password_name[ptr_client->auth_password] : "");
weechat_log_printf (" hash_iterations . . . : %d", ptr_client->hash_iterations);
weechat_log_printf (" nonce . . . . . . . . : '%s'", ptr_client->nonce);
weechat_log_printf (" listen_start_time . . : %lld", (long long)ptr_client->listen_start_time);
weechat_log_printf (" start_time. . . . . . : %lld", (long long)ptr_client->start_time);
weechat_log_printf (" end_time. . . . . . . : %lld", (long long)ptr_client->end_time);

View File

@ -106,6 +106,9 @@ struct t_relay_client
char *protocol_string; /* example: "ipv6.ssl.irc.freenode" */
char *protocol_args; /* arguments used for protocol */
/* example: server for irc protocol */
int auth_password; /* password auth (negotiated/client) */
int hash_iterations; /* hash iterations */
char *nonce; /* nonce used in salt of hashed pwd */
time_t listen_start_time; /* when listening started */
time_t start_time; /* time of client connection */
time_t end_time; /* time of client disconnection */
@ -124,6 +127,7 @@ struct t_relay_client
};
extern char *relay_client_status_string[];
extern char *relay_client_status_name[];
extern char *relay_client_msg_type_string[];
extern struct t_relay_client *relay_clients;
extern struct t_relay_client *last_relay_client;

View File

@ -32,11 +32,11 @@
#include "../weechat-plugin.h"
#include "relay.h"
#include "relay-config.h"
#include "irc/relay-irc.h"
#include "relay-client.h"
#include "relay-buffer.h"
#include "relay-network.h"
#include "relay-server.h"
#include "irc/relay-irc.h"
struct t_config_file *relay_config_file = NULL;
@ -60,12 +60,15 @@ struct t_config_option *relay_config_color_text_selected;
struct t_config_option *relay_config_network_allow_empty_password;
struct t_config_option *relay_config_network_allowed_ips;
struct t_config_option *relay_config_network_auth_password;
struct t_config_option *relay_config_network_auth_timeout;
struct t_config_option *relay_config_network_bind_address;
struct t_config_option *relay_config_network_clients_purge_delay;
struct t_config_option *relay_config_network_compression_level;
struct t_config_option *relay_config_network_hash_iterations;
struct t_config_option *relay_config_network_ipv6;
struct t_config_option *relay_config_network_max_clients;
struct t_config_option *relay_config_network_nonce_size;
struct t_config_option *relay_config_network_password;
struct t_config_option *relay_config_network_ssl_cert_key;
struct t_config_option *relay_config_network_ssl_priorities;
@ -91,6 +94,7 @@ struct t_config_option *relay_config_weechat_commands;
regex_t *relay_config_regex_allowed_ips = NULL;
regex_t *relay_config_regex_websocket_allowed_origins = NULL;
struct t_hashtable *relay_config_hashtable_irc_backlog_tags = NULL;
char **relay_config_network_auth_password_list = NULL;
/*
@ -149,6 +153,36 @@ relay_config_change_network_allowed_ips (const void *pointer, void *data,
}
}
/*
* Callback for changes on option "relay.network.auth_password".
*/
void
relay_config_change_network_auth_password (const void *pointer, void *data,
struct t_config_option *option)
{
/* make C compiler happy */
(void) pointer;
(void) data;
(void) option;
if (relay_config_network_auth_password_list)
{
weechat_string_free_split (relay_config_network_auth_password_list);
relay_config_network_auth_password_list = NULL;
}
relay_config_network_auth_password_list = weechat_string_split (
weechat_config_string (relay_config_network_auth_password),
",",
NULL,
WEECHAT_STRING_SPLIT_STRIP_LEFT
| WEECHAT_STRING_SPLIT_STRIP_RIGHT
| WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
0,
NULL);
}
/*
* Callback for changes on option "relay.network.bind_address".
*/
@ -1032,6 +1066,20 @@ relay_config_init ()
NULL, NULL, NULL,
&relay_config_change_network_allowed_ips, NULL, NULL,
NULL, NULL, NULL);
relay_config_network_auth_password = weechat_config_new_option (
relay_config_file, ptr_section,
"auth_password", "string",
N_("comma separated list of hash algorithms used for password "
"authentication in weechat protocol, among these values: \"plain\" "
"(password in plain text, not hashed), \"sha256\", \"sha512\", "
"\"pbkdf2+sha256\", \"pbkdf2+sha512\"), \"*\" means all algorithms, "
"a name beginning with \"!\" is a negative value to prevent an "
"algorithm from being used, wildcard \"*\" is allowed in names "
"(examples: \"*\", \"pbkdf2*\", \"*,!plain\")"),
NULL, 0, 0, "*", NULL, 0,
NULL, NULL, NULL,
&relay_config_change_network_auth_password, NULL, NULL,
NULL, NULL, NULL);
relay_config_network_auth_timeout = weechat_config_new_option (
relay_config_file, ptr_section,
"auth_timeout", "integer",
@ -1066,6 +1114,16 @@ relay_config_init ()
"compression)"),
NULL, 0, 9, "6", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
relay_config_network_hash_iterations = weechat_config_new_option (
relay_config_file, ptr_section,
"hash_iterations", "integer",
N_("number of iterations asked to the client in weechat protocol "
"when a hashed password with algorithm PBKDF2 is used for "
"authentication; more iterations is better in term of security but "
"is slower to compute; this number should not be too high if your "
"CPU is slow"),
NULL, 1, 1000000, "100000", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
relay_config_network_ipv6 = weechat_config_new_option (
relay_config_file, ptr_section,
"ipv6", "boolean",
@ -1082,6 +1140,15 @@ relay_config_init ()
N_("maximum number of clients connecting to a port (0 = no limit)"),
NULL, 0, INT_MAX, "5", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
relay_config_network_nonce_size = weechat_config_new_option (
relay_config_file, ptr_section,
"nonce_size", "integer",
N_("size of nonce (in bytes), generated when a client connects; "
"the client must use this nonce, concatenated to the client nonce "
"and the password when hashing the password in the \"init\" "
"command of the weechat protocol"),
NULL, 8, 128, "16", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
relay_config_network_password = weechat_config_new_option (
relay_config_file, ptr_section,
"password", "string",
@ -1294,6 +1361,7 @@ relay_config_read ()
if (rc == WEECHAT_CONFIG_READ_OK)
{
relay_config_change_network_allowed_ips (NULL, NULL, NULL);
relay_config_change_network_auth_password (NULL, NULL, NULL);
relay_config_change_irc_backlog_tags (NULL, NULL, NULL);
}
return rc;
@ -1337,4 +1405,10 @@ relay_config_free ()
weechat_hashtable_free (relay_config_hashtable_irc_backlog_tags);
relay_config_hashtable_irc_backlog_tags = NULL;
}
if (relay_config_network_auth_password_list)
{
weechat_string_free_split (relay_config_network_auth_password_list);
relay_config_network_auth_password_list = NULL;
}
}

View File

@ -39,12 +39,15 @@ extern struct t_config_option *relay_config_color_text_selected;
extern struct t_config_option *relay_config_network_allow_empty_password;
extern struct t_config_option *relay_config_network_allowed_ips;
extern struct t_config_option *relay_config_network_auth_password;
extern struct t_config_option *relay_config_network_auth_timeout;
extern struct t_config_option *relay_config_network_bind_address;
extern struct t_config_option *relay_config_network_clients_purge_delay;
extern struct t_config_option *relay_config_network_compression_level;
extern struct t_config_option *relay_config_network_hash_iterations;
extern struct t_config_option *relay_config_network_ipv6;
extern struct t_config_option *relay_config_network_max_clients;
extern struct t_config_option *relay_config_network_nonce_size;
extern struct t_config_option *relay_config_network_password;
extern struct t_config_option *relay_config_network_ssl_cert_key;
extern struct t_config_option *relay_config_network_ssl_priorities;
@ -64,6 +67,7 @@ extern struct t_config_option *relay_config_weechat_commands;
extern regex_t *relay_config_regex_allowed_ips;
extern regex_t *relay_config_regex_websocket_allowed_origins;
extern struct t_hashtable *relay_config_hashtable_irc_backlog_tags;
extern char **relay_config_network_auth_password_list;
extern int relay_config_check_network_totp_secret (const void *pointer,
void *data,

View File

@ -70,6 +70,8 @@ extern void relay_weechat_msg_add_pointer (struct t_relay_weechat_msg *msg,
void *pointer);
extern void relay_weechat_msg_add_time (struct t_relay_weechat_msg *msg,
time_t time);
extern void relay_weechat_msg_add_hashtable (struct t_relay_weechat_msg *msg,
struct t_hashtable *hashtable);
extern int relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg,
const char *path, const char *keys);
extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg,

View File

@ -31,6 +31,7 @@
#include "relay-weechat-nicklist.h"
#include "../relay-buffer.h"
#include "../relay-client.h"
#include "../relay-auth.h"
#include "../relay-config.h"
#include "../relay-raw.h"
@ -159,148 +160,151 @@ relay_weechat_protocol_is_sync (struct t_relay_client *ptr_client,
}
/*
* Parses PBKDF2 parameters from string with format:
*
* algorithm:salt:iterations:hash
*
* where:
*
* algorithm is "sha256" or "sha512"
* salt is the salt in hexadecimal
* iterations it the number of iterations ( 1)
* hash is the hashed password with the parameters above, in hexadecimal
* Replies to a client handshake command.
*/
void
relay_weechat_protocol_parse_pbkdf2 (const char *parameters,
char **algorithm,
char **salt,
int *salt_size,
int *iterations,
char **hash_pbkdf2)
relay_weechat_protocol_handshake_reply (struct t_relay_client *client,
const char *command)
{
char **argv, *error;
int argc;
struct t_relay_weechat_msg *msg;
struct t_hashtable *hashtable;
char *totp_secret, string[64];
*algorithm = NULL;
*salt = NULL;
*salt_size = 0;
*iterations = 0;
*hash_pbkdf2 = NULL;
totp_secret = weechat_string_eval_expression (
weechat_config_string (relay_config_network_totp_secret),
NULL, NULL, NULL);
if (!parameters)
return;
argv = weechat_string_split (parameters, ":", NULL, 0, 0, &argc);
if (!argv || (argc < 4))
hashtable = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (hashtable)
{
/* not enough parameters */
if (argv)
weechat_string_free_split (argv);
return;
weechat_hashtable_set (
hashtable,
"auth_password",
(client->auth_password >= 0) ?
relay_auth_password_name[client->auth_password] : "");
snprintf (string, sizeof (string), "%d", client->hash_iterations);
weechat_hashtable_set (
hashtable,
"hash_iterations",
string);
weechat_hashtable_set (
hashtable,
"nonce",
client->nonce);
weechat_hashtable_set (
hashtable,
"totp",
(totp_secret && totp_secret[0]) ? "on" : "off");
msg = relay_weechat_msg_new (command);
if (msg)
{
relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HASHTABLE);
relay_weechat_msg_add_hashtable (msg, hashtable);
/* send message */
relay_weechat_msg_send (client, msg);
relay_weechat_msg_free (msg);
}
weechat_hashtable_free (hashtable);
}
/* parameter 1: algorithm */
if ((strcmp (argv[0], "sha256") == 0)
|| (strcmp (argv[0], "sha512") == 0))
{
*algorithm = strdup (argv[0]);
}
/* parameter 2: salt */
*salt = malloc (strlen (argv[1]) + 1);
if (*salt)
*salt_size = weechat_string_base_decode (16, argv[1], *salt);
/* parameter 3: iterations */
*iterations = (int)strtol (argv[2], &error, 10);
if (!error || error[0])
*iterations = 0;
/* parameter 4: the PBKDF2 hash */
*hash_pbkdf2 = strdup (argv[3]);
weechat_string_free_split (argv);
if (totp_secret)
free (totp_secret);
}
/*
* Checks if hashed password received is valid.
*
* Format of hash_password is: algorithm:hash
*
* Returns 1 if the hashed password is valid, otherwise 0.
* Callback for command "handshake" (from client).
*/
int
relay_weechat_protocol_check_hash (const char *hashed_password,
const char *password)
RELAY_WEECHAT_PROTOCOL_CALLBACK(handshake)
{
const char *pos_hash;
char *hash_algo, hash[512 / 8], hash_hexa[((512 / 8) * 2) + 1];
char *hash_pbkdf2_algo, *salt, *hash_pbkdf2;
int rc, hash_size, salt_size, iterations;
char **options, **auths, *pos;
int i, j, index_auth, auth_found, auth_allowed, compression;
int password_received, plain_text_password;
rc = 0;
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
if (!hashed_password || !password)
goto end;
if (client->status != RELAY_STATUS_WAITING_AUTH)
return WEECHAT_RC_OK;
pos_hash = strchr (hashed_password, ':');
if (!pos_hash)
goto end;
auth_found = -1;
password_received = 0;
hash_algo = weechat_strndup (hashed_password, pos_hash - hashed_password);
if (!hash_algo)
goto end;
pos_hash++;
if ((strcmp (hash_algo, "sha256") == 0)
|| (strcmp (hash_algo, "sha512") == 0))
options = (argc > 0) ?
weechat_string_split_command (argv_eol[0], ',') : NULL;
if (options)
{
if (weechat_crypto_hash (password, strlen (password), hash_algo,
hash, &hash_size))
for (i = 0; options[i]; i++)
{
weechat_string_base_encode (16, hash, hash_size, hash_hexa);
if (weechat_strcasecmp (hash_hexa, pos_hash) == 0)
rc = 1;
}
}
else if (strcmp (hash_algo, "pbkdf2") == 0)
{
relay_weechat_protocol_parse_pbkdf2 (pos_hash,
&hash_pbkdf2_algo,
&salt,
&salt_size,
&iterations,
&hash_pbkdf2);
if (hash_pbkdf2_algo && salt && (salt_size > 0) && (iterations > 0)
&& hash_pbkdf2)
{
if (weechat_crypto_hash_pbkdf2 (password, strlen (password),
hash_pbkdf2_algo,
salt, salt_size,
iterations,
hash, &hash_size))
pos = strchr (options[i], '=');
if (pos)
{
weechat_string_base_encode (16, hash, hash_size, hash_hexa);
if (weechat_strcasecmp (hash_hexa, hash_pbkdf2) == 0)
rc = 1;
pos[0] = '\0';
pos++;
if (strcmp (options[i], "password") == 0)
{
password_received = 1;
auths = weechat_string_split (
pos,
":",
NULL,
WEECHAT_STRING_SPLIT_STRIP_LEFT
| WEECHAT_STRING_SPLIT_STRIP_RIGHT
| WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
0,
NULL);
if (auths)
{
for (j = 0; auths[j]; j++)
{
index_auth = relay_auth_password_search (
auths[j]);
if ((index_auth >= 0) && (index_auth > auth_found))
{
auth_allowed = weechat_string_match_list (
relay_auth_password_name[index_auth],
(const char **)relay_config_network_auth_password_list,
1);
if (auth_allowed)
auth_found = index_auth;
}
}
weechat_string_free_split (auths);
}
}
else if (strcmp (options[i], "compression") == 0)
{
compression = relay_weechat_compression_search (pos);
if (compression >= 0)
RELAY_WEECHAT_DATA(client, compression) = compression;
}
}
}
if (hash_pbkdf2_algo)
free (hash_pbkdf2_algo);
if (salt)
free (salt);
if (hash_pbkdf2)
free (hash_pbkdf2);
weechat_string_free_split_command (options);
}
free (hash_algo);
if (!password_received)
{
plain_text_password = weechat_string_match_list (
relay_auth_password_name[0],
(const char **)relay_config_network_auth_password_list,
1);
if (plain_text_password)
auth_found = 0;
}
end:
return rc;
client->auth_password = auth_found;
relay_weechat_protocol_handshake_reply (client, command);
return WEECHAT_RC_OK;
}
/*
@ -328,12 +332,12 @@ end:
RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
{
char **options, *pos, *password, *totp_secret, *info_totp_args, *info_totp;
char **options, *pos, *relay_password, *totp_secret, *info_totp_args, *info_totp;
int i, compression, length, password_received, totp_received;
RELAY_WEECHAT_PROTOCOL_MIN_ARGS(0);
password = weechat_string_eval_expression (
relay_password = weechat_string_eval_expression (
weechat_config_string (relay_config_network_password),
NULL, NULL, NULL);
totp_secret = weechat_string_eval_expression (
@ -357,17 +361,14 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
if (strcmp (options[i], "password") == 0)
{
password_received = 1;
if (password && (strcmp (password, pos) == 0))
if (relay_auth_password (client, pos, relay_password))
RELAY_WEECHAT_DATA(client, password_ok) = 1;
}
else if (strcmp (options[i], "password_hash") == 0)
{
password_received = 1;
if (password
&& relay_weechat_protocol_check_hash (pos, password))
{
if (relay_auth_password_hash (client, pos, relay_password))
RELAY_WEECHAT_DATA(client, password_ok) = 1;
}
}
else if (strcmp (options[i], "totp") == 0)
{
@ -405,7 +406,7 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
}
/* if no password received and password is empty, it's OK */
if (!password_received && (!password || !password[0]))
if (!password_received && (!relay_password || !relay_password[0]))
RELAY_WEECHAT_DATA(client, password_ok) = 1;
/* if no TOTP received and totp_secret is empty, it's OK */
@ -425,8 +426,8 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(init)
relay_client_set_status (client, RELAY_STATUS_AUTH_FAILED);
}
if (password)
free (password);
if (relay_password)
free (relay_password);
if (totp_secret)
free (totp_secret);
@ -1547,7 +1548,8 @@ relay_weechat_protocol_recv (struct t_relay_client *client, const char *data)
char *pos, *id, *command, **argv, **argv_eol;
int i, argc, return_code;
struct t_relay_weechat_protocol_cb protocol_cb[] =
{ { "init", &relay_weechat_protocol_cb_init },
{ { "handshake", &relay_weechat_protocol_cb_handshake },
{ "init", &relay_weechat_protocol_cb_init },
{ "hdata", &relay_weechat_protocol_cb_hdata },
{ "info", &relay_weechat_protocol_cb_info },
{ "infolist", &relay_weechat_protocol_cb_infolist },
@ -1631,13 +1633,14 @@ relay_weechat_protocol_recv (struct t_relay_client *client, const char *data)
{
if (strcmp (protocol_cb[i].name, command) == 0)
{
if ((strcmp (protocol_cb[i].name, "init") != 0)
if ((strcmp (protocol_cb[i].name, "handshake") != 0)
&& (strcmp (protocol_cb[i].name, "init") != 0)
&& (!RELAY_WEECHAT_DATA(client, password_ok)
|| !RELAY_WEECHAT_DATA(client, totp_ok)))
{
/*
* command is not "init" and password or totp are not set?
* then close connection!
* command is not handshake/init and password or totp are not
* set? then close connection!
*/
relay_client_set_status (client,
RELAY_STATUS_AUTH_FAILED);

View File

@ -40,7 +40,7 @@
#include "../relay-raw.h"
char *relay_weechat_compression_string[] = /* strings for compressions */
char *relay_weechat_compression_string[] = /* strings for compression */
{ "off", "zlib" };

View File

@ -55,7 +55,7 @@ set(LIB_WEECHAT_UNIT_TESTS_PLUGINS_SRC
unit/plugins/irc/test-irc-mode.cpp
unit/plugins/irc/test-irc-nick.cpp
unit/plugins/irc/test-irc-protocol.cpp
unit/plugins/relay/weechat/test-relay-weechat-protocol.cpp
unit/plugins/relay/test-relay-auth.cpp
)
add_library(weechat_unit_tests_plugins MODULE ${LIB_WEECHAT_UNIT_TESTS_PLUGINS_SRC})

View File

@ -72,7 +72,7 @@ lib_weechat_unit_tests_plugins_la_SOURCES = unit/plugins/irc/test-irc-color.cpp
unit/plugins/irc/test-irc-mode.cpp \
unit/plugins/irc/test-irc-nick.cpp \
unit/plugins/irc/test-irc-protocol.cpp \
unit/plugins/relay/weechat/test-relay-weechat-protocol.cpp
unit/plugins/relay/test-relay-auth.cpp
lib_weechat_unit_tests_plugins_la_LDFLAGS = -module -no-undefined

View File

@ -0,0 +1,362 @@
/*
* test-relay-auth.cpp - test client authentication functions
*
* Copyright (C) 2020 Sébastien Helleu <flashcode@flashtux.org>
*
* This file is part of WeeChat, the extensible chat client.
*
* WeeChat 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 3 of the License, or
* (at your option) any later version.
*
* WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CppUTest/TestHarness.h"
extern "C"
{
#include <stdio.h>
#include "src/plugins/relay/relay-auth.h"
}
#define WEE_CHECK_PARSE_SHA(__parameters) \
salt = (char *)0x1; \
salt_size = -1; \
hash_sha = (char *)0x1; \
relay_auth_parse_sha ( \
__parameters, \
&salt_hexa, \
&salt, \
&salt_size, \
&hash_sha);
#define WEE_CHECK_PARSE_PBKDF2(__parameters) \
salt = (char *)0x1; \
salt_size = -1; \
iterations = -1; \
hash_pbkdf2 = (char *)0x1; \
relay_auth_parse_pbkdf2 ( \
__parameters, \
&salt_hexa, \
&salt, \
&salt_size, \
&iterations, \
&hash_pbkdf2);
TEST_GROUP(RelayAuth)
{
};
/*
* Tests functions:
* relay_auth_parse_sha
*/
TEST(RelayAuth, ParseSha)
{
char *salt_hexa, *salt, *hash_sha;
const char salt_expected[4] = { 0x41, 0x42, 0x43, 0x44 }; /* "ABCD" */
int salt_size;
/* NULL string */
WEE_CHECK_PARSE_SHA(NULL);
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
POINTERS_EQUAL(NULL, hash_sha);
/* not enough parameters: 0 (expected: 2) */
WEE_CHECK_PARSE_SHA("");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
POINTERS_EQUAL(NULL, hash_sha);
/* not enough parameters: 1 (expected: 2) */
WEE_CHECK_PARSE_SHA("41424344");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
POINTERS_EQUAL(NULL, hash_sha);
/* good parameters */
WEE_CHECK_PARSE_SHA("41424344:5e884898da28047151d0e56f8dc6292773603d0d6aa"
"bbdd62a11ef721d1542d8");
STRCMP_EQUAL("41424344", salt_hexa);
MEMCMP_EQUAL(salt_expected, salt, 4);
LONGS_EQUAL(4, salt_size);
STRCMP_EQUAL("5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1"
"542d8",
hash_sha);
free (salt_hexa);
free (salt);
free (hash_sha);
/* wrong salt */
WEE_CHECK_PARSE_SHA("Z:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a"
"11ef721d1542d8");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
STRCMP_EQUAL("5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1"
"542d8",
hash_sha);
free (hash_sha);
}
/*
* Tests functions:
* relay_auth_parse_pbkdf2
*/
TEST(RelayAuth, ParsePbkdf2)
{
char *salt_hexa, *salt, *hash_pbkdf2;
const char salt_expected[4] = { 0x41, 0x42, 0x43, 0x44 }; /* "ABCD" */
int salt_size, iterations;
/* NULL string */
WEE_CHECK_PARSE_PBKDF2(NULL);
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
LONGS_EQUAL(0, iterations);
POINTERS_EQUAL(NULL, hash_pbkdf2);
/* not enough parameters: 0 (expected: 3) */
WEE_CHECK_PARSE_PBKDF2("");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
LONGS_EQUAL(0, iterations);
POINTERS_EQUAL(NULL, hash_pbkdf2);
/* not enough parameters: 1 (expected: 3) */
WEE_CHECK_PARSE_PBKDF2("41424344");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
LONGS_EQUAL(0, iterations);
POINTERS_EQUAL(NULL, hash_pbkdf2);
/* not enough parameters: 2 (expected: 3) */
WEE_CHECK_PARSE_PBKDF2("41424344:100000");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
LONGS_EQUAL(0, iterations);
POINTERS_EQUAL(NULL, hash_pbkdf2);
/* good parameters */
WEE_CHECK_PARSE_PBKDF2("41424344:100000:01757d53157ca14a1419e3a8cc1563536"
"520a60b76d2d48e7f9ac09afc945a1c");
STRCMP_EQUAL("41424344", salt_hexa);
MEMCMP_EQUAL(salt_expected, salt, 4);
LONGS_EQUAL(4, salt_size);
LONGS_EQUAL(100000, iterations);
STRCMP_EQUAL("01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc9"
"45a1c",
hash_pbkdf2);
free (salt_hexa);
free (salt);
free (hash_pbkdf2);
/* wrong salt */
WEE_CHECK_PARSE_PBKDF2("Z:100000:01757d53157ca14a1419e3a8cc1563536520a60b"
"76d2d48e7f9ac09afc945a1c");
POINTERS_EQUAL(NULL, salt_hexa);
POINTERS_EQUAL(NULL, salt);
LONGS_EQUAL(0, salt_size);
LONGS_EQUAL(100000, iterations);
STRCMP_EQUAL("01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc9"
"45a1c",
hash_pbkdf2);
free (hash_pbkdf2);
/* wrong iterations */
WEE_CHECK_PARSE_PBKDF2("41424344:abcd:01757d53157ca14a1419e3a8cc156353652"
"0a60b76d2d48e7f9ac09afc945a1c");
STRCMP_EQUAL("41424344", salt_hexa);
MEMCMP_EQUAL(salt_expected, salt, 4);
LONGS_EQUAL(4, salt_size);
LONGS_EQUAL(0, iterations);
STRCMP_EQUAL("01757d53157ca14a1419e3a8cc1563536520a60b76d2d48e7f9ac09afc9"
"45a1c",
hash_pbkdf2);
free (salt_hexa);
free (salt);
free (hash_pbkdf2);
}
/*
* Tests functions:
* relay_auth_check_password_plain
*/
TEST(RelayAuth, CheckPasswordPlain)
{
/* invalid arguments */
LONGS_EQUAL(0, relay_auth_check_password_plain (NULL, NULL));
LONGS_EQUAL(0, relay_auth_check_password_plain ("abcd", NULL));
LONGS_EQUAL(0, relay_auth_check_password_plain (NULL, "password"));
/* wrong password */
LONGS_EQUAL(0, relay_auth_check_password_plain ("test", "password"));
LONGS_EQUAL(0, relay_auth_check_password_plain ("Password", "password"));
/* good password */
LONGS_EQUAL(1, relay_auth_check_password_plain ("", ""));
LONGS_EQUAL(1, relay_auth_check_password_plain ("password", "password"));
}
/*
* Tests functions:
* relay_auth_check_hash_sha
*/
TEST(RelayAuth, CheckHashSha)
{
/* "ABCDEFGHIJKLMNOP" */
const char salt[16] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50 };
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
NULL, NULL, 0, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"", "", 0, "", ""));
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"sha256", NULL, 0, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"sha256", salt, sizeof (salt), NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"sha256", salt, sizeof (salt), "", ""));
/* SHA256: hash is for password: "wrong" */
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"sha256",
salt,
sizeof (salt),
"5d21c7a7d34f47623195ff4750bd65c34bb5f1ba131bf0086a498b2a"
"6a4edfcb",
"password"));
/* SHA256: hash is for password: "password" */
LONGS_EQUAL(1,
relay_auth_check_hash_sha (
"sha256",
salt,
sizeof (salt),
"6b1550cb48b6cd66b7152f96804b816b5ae861e4ae52ff5c7a56b7a4"
"f2fdb772",
"password"));
/* SHA512: hash is for password: "wrong" */
LONGS_EQUAL(0,
relay_auth_check_hash_sha (
"sha512",
salt,
sizeof (salt),
"527d147327d77aceeb862848b404d462ce2a11e4502eda82ce0b1be1"
"958422491ca14f3fe8b94a66c61d54639d9fbed0979025ae1073ccaa"
"a66a2d2de9416221",
"password"));
/* SHA512: hash is for password: "password" */
LONGS_EQUAL(1,
relay_auth_check_hash_sha (
"sha512",
salt,
sizeof (salt),
"49d2c9a7f7cf630b32c0cc79b331db4eec6215e2c90bcc6c43db93f8"
"847cfdf885a4a8d36b440cb47fed79e97b35380d086a5722c3a26018"
"fdc633fe56949938",
"password"));
}
/*
* Tests functions:
* relay_auth_check_hash_pbkdf2
*/
TEST(RelayAuth, CheckHashPbkdf2)
{
/* "ABCDEFGHIJKLMNOP" */
const char salt[16] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50 };
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
NULL, NULL, 0, 0, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"", "", 0, 0, "", ""));
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha256", NULL, 0, 0, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha256", salt, sizeof (salt), 0, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha256", salt, sizeof (salt), 100000, NULL, NULL));
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha256", salt, sizeof (salt), 100000, "", ""));
/* PBKDF2 (SHA256): hash is for password "wrong" */
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha256",
salt,
sizeof (salt),
100000,
"e8f92a75f5956e9dc3499775221e9ef121bf4d09bdca4391b69aa62c"
"50c2bb6b",
"password"));
/* PBKDF2 (SHA256): hash is for password "password" */
LONGS_EQUAL(1,
relay_auth_check_hash_pbkdf2 (
"sha256",
salt,
sizeof (salt),
100000,
"323d29f1762dcb5917bc8320c4eb9ea05900fc28e53cbc3e1b7f0980"
"2e35e2d0",
"password"));
/* PBKDF2 (SHA512): hash is for password "wrong" */
LONGS_EQUAL(0,
relay_auth_check_hash_pbkdf2 (
"sha512",
salt,
sizeof (salt),
100000,
"e682a3815a4d1de8d13a223932b6b0467b7d775111aae3794afb9a84"
"ee62bd50755fde725262f75d1211e8497a35c8dca8a6333bcc9f7b53"
"244f6ff567d25cfc",
"password"));
/* PBKDF2 (SHA512): hash is for password "password" */
LONGS_EQUAL(1,
relay_auth_check_hash_pbkdf2 (
"sha512",
salt,
sizeof (salt),
100000,
"db166999c1f415a40570a4bbd3a26d461f87e495da215c75135b77bf"
"910a261d3749f28264d24b546fc898908d4209704700020b8dd2bca6"
"e4698208dd5aa5f2",
"password"));
}