Skip to content

Commit

Permalink
Add DirectoryClient methods for getting status vote documents from au…
Browse files Browse the repository at this point in the history
…thorities - #6
  • Loading branch information
dapphp committed Feb 15, 2022
1 parent 1c53efa commit d3df101
Show file tree
Hide file tree
Showing 4 changed files with 479 additions and 10 deletions.
143 changes: 143 additions & 0 deletions src/AuthorityStatusDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

/**
* Project: TorUtils: PHP classes for interacting with Tor
* File: CircuitStatus.php
*
* Copyright (c) 2022, Drew Phillips
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Any modifications to the library should be indicated clearly in the source code
* to inform users that the changes are not a part of the original software.
*
* @copyright 2022 Drew Phillips
* @author Drew Phillips <[email protected]>
*
*/

namespace Dapphp\TorUtils;

/**
* AuthorityStatusDocument class. This class models a Tor circuit.
*
*/
class AuthorityStatusDocument
{
/** @var int A document format version. For this code, the latest version known is "3". */
public $statusVersion = 0;

/** @var string "vote" or "consensus", depending on the type of the document */
public $voteStatus = '';

/** @var int[] A list of supported methods for generating consensuses from votes. Does not occur in consensuses. */
public $consensusMethods = [];

/** @var string The consensus method; does not occur in votes */
public $consensusMethod = '';

/** @var string|null The publication time for this status document (if a vote) */
public $published = null;

/** @var string The start of the Interval for this vote. Before this time, the consensus document produced from
* this vote is not officially in use.
*/
public $validAfter = '';

/** @var string The time at which the next consensus should be produced; before this time, there is no point in
* downloading another consensus, since there won't be a new one.
*/
public $freshUntil = '';

/** @var string The end of the Interval for this vote. After this time, all clients should try to find a more
* recent consensus.
*/
public $validUntil = '';

/** @var int The number of seconds allowed to collect votes from all authorities */
public $voteDelaySeconds = 0;

/** @var int The number of seconds allowed to collect signatures from all authorities */
public $distDelaySeconds = 0;

/** @var string[] A list of recommended Tor versions for client usage. The versions are given as defined by
* version-spec.txt. If absent, no opinion is held about client versions.
*/
public $clientVersions = [];

/** @var string[] A list of recommended Tor versions for relay usage. The versions are given as defined by
* version-spec.txt. If absent, no opinion is held about server versions.
*/
public $serverVersions = [];

/** @var string[] A space-separated list of all of the flags that this document might contain. */
public $knownFlags = [];

/** @var array A list of the internal performance thresholds that the directory authority had at the moment it was
* forming a vote.
*/
public $flagThresholds = [];

/** @var string[] */
public $recommendedClientProtocols = [];

/** @var string[] */
public $recommendedRelayProtocols = [];

/** @var string[] */
public $requiredClientProtocols = [];

/** @var string[] */
public $requiredRelayProtocols = [];

/** @var array The parameters list, if present, contains a space-separated list of case-sensitive key-value pairs.
* See param-spec.txt for a list of parameters and their meanings.
*/
public $params = [];

/** @var string The shared random value that was generated during the second-to-last shared randomness protocol run,
* encoded in base64.
*/
public $sharedRandPreviousValue = '';

/** @var string The shared random value that was generated during the latest shared
randomness protocol run, encoded in base64. */
public $sharedRandCurrentValue = '';

/** @var array */
public $authorities = [];

/** @var RouterDescriptor[] A list of relays along with their information and status according to the document. */
public $descriptors = [];

/** @var array List of optional weights to apply to router bandwidths during path selection. Appears at most once
* for a consensus. Does not appear in votes. */
public $bandwidthWeights = [];

/** @var array his is a signature of the status document, with the initial item "network-status-version", and the
* signature item "directory-signature", using the signing key. Only one entry for a vote, and at least one for a
* consensus.
*/
public $directorySignatures = [];

}
40 changes: 38 additions & 2 deletions src/DirectoryClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,39 @@ public function getServerDescriptor($fingerprint)
}
}

public function statusVoteCurrentAuthority($address = null)
{
$uri = '/tor/status-vote/current/authority.z';

$reply = $this->_request($uri, $address);

return $this->parser->parseVoteConsensusStatusDocument($reply);
}

public function statusVoteCurrentConsensus($address = null)
{
$uri = '/tor/status-vote/current/consensus.z';

$reply = $this->_request($uri, $address);

return $this->parser->parseVoteConsensusStatusDocument($reply);
}

/**
* Make an HTTP GET request to a directory server and return the response
*
* @param string $uri The URI to fetch (e.g. /tor/server/all.z)
* @param string|null $directoryServer The host:port or ip:port of the directory server to use, or null to use
* random selections from the default list
* @return \Dapphp\TorUtils\ProtocolReply If no error occurs, a ProtocolReply object is returned. The first line may
* be the HTTP status line. Implementations must tolerate the first reply line being an HTTP response code.
* @throws \Exception If the request to the directory failed (e.g. 404 Not Found, Connection Timed Out)
*/
public function get($uri, $directoryServer = null)
{
return $this->_request($uri, $directoryServer);
}

/**
* Pick a random dir authority to query and perform the HTTP request for directory info
*
Expand All @@ -379,7 +412,10 @@ private function _request($uri, $directoryServer = null)

do {
// pick a server from the list, it is randomized in __construct
if ($this->preferredServer && !$used) {
if ($directoryServer && !$used) {
$server = $directoryServer;
$used = true;
} elseif ($this->preferredServer && !$used) {
$server = $this->preferredServer;
$used = true;
} else {
Expand Down Expand Up @@ -481,7 +517,7 @@ private function _request($uri, $directoryServer = null)
if ($body === false) {
throw new \Exception('Failed to inflate response data');
}
} else if ($encoding == 'identity') {
} elseif ($encoding == 'identity') {
// nothing to do
} else {
throw new \Exception('Directory sent response in an unknown encoding: ' . $encoding);
Expand Down
Loading

0 comments on commit d3df101

Please sign in to comment.