Implemented hide AKA, Minor Node::class changes, other fixes
This commit is contained in:
parent
569201e972
commit
4048289cf3
@ -60,16 +60,16 @@ class Node
|
|||||||
return $this->ftns->count();
|
return $this->ftns->count();
|
||||||
|
|
||||||
// The authenticated remote addresses
|
// The authenticated remote addresses
|
||||||
case 'aka_remote':
|
case 'aka_remote_authed':
|
||||||
return $this->ftns_authed;
|
return $this->ftns_authed;
|
||||||
|
|
||||||
|
case 'aka_remote':
|
||||||
|
return $this->ftns;
|
||||||
|
|
||||||
// Have we authenticated the remote
|
// Have we authenticated the remote
|
||||||
case 'aka_authed':
|
case 'aka_authed':
|
||||||
return $this->authed;
|
return $this->authed;
|
||||||
|
|
||||||
case 'ftn':
|
|
||||||
return ($x=$this->ftns->first()) ? $x->ftn : 'Unknown';
|
|
||||||
|
|
||||||
// The nodes password
|
// The nodes password
|
||||||
case 'password':
|
case 'password':
|
||||||
return ($this->ftns->count() && ($x=$this->ftns->first()->session('sespass'))) ? $x : '-';
|
return ($this->ftns->count() && ($x=$this->ftns->first()->session('sespass'))) ? $x : '-';
|
||||||
|
@ -42,8 +42,8 @@ abstract class Protocol
|
|||||||
protected const O_NPU = (1<<(self::O_BASE+6)); /* 0000 0000 0000 1000 0000 0000 0000 - No files pickup desired (Calling System) */
|
protected const O_NPU = (1<<(self::O_BASE+6)); /* 0000 0000 0000 1000 0000 0000 0000 - No files pickup desired (Calling System) */
|
||||||
protected const O_PUP = (1<<(self::O_BASE+7)); /* 0000 0000 0001 0000 0000 0000 0000 - Pickup files for primary address only */
|
protected const O_PUP = (1<<(self::O_BASE+7)); /* 0000 0000 0001 0000 0000 0000 0000 - Pickup files for primary address only */
|
||||||
protected const O_PUA = (1<<(self::O_BASE+8)); /* 0000 0000 0010 0000 0000 0000 0000 EMSI - Pickup files for all presented addresses */
|
protected const O_PUA = (1<<(self::O_BASE+8)); /* 0000 0000 0010 0000 0000 0000 0000 EMSI - Pickup files for all presented addresses */
|
||||||
protected const O_PWD = (1<<(self::O_BASE+9)); /* 0000 0000 0100 0000 0000 0000 0000 BINK - Node password validated */
|
protected const O_PWD = (1<<(self::O_BASE+9)); /* 0000 0000 0100 0000 0000 0000 0000 BINK - Node needs to be password validated */
|
||||||
protected const O_BAD = (1<<(self::O_BASE+10)); /* 0000 0000 1000 0000 0000 0000 0000 BOTH - NOde invalid password presented */
|
protected const O_BAD = (1<<(self::O_BASE+10)); /* 0000 0000 1000 0000 0000 0000 0000 BOTH - Node invalid password presented */
|
||||||
protected const O_RH1 = (1<<(self::O_BASE+11)); /* 0000 0001 0000 0000 0000 0000 0000 EMSI - Use RH1 for Hydra (files-after-freqs) */
|
protected const O_RH1 = (1<<(self::O_BASE+11)); /* 0000 0001 0000 0000 0000 0000 0000 EMSI - Use RH1 for Hydra (files-after-freqs) */
|
||||||
protected const O_LST = (1<<(self::O_BASE+12)); /* 0000 0010 0000 0000 0000 0000 0000 BOTH - Node is nodelisted */
|
protected const O_LST = (1<<(self::O_BASE+12)); /* 0000 0010 0000 0000 0000 0000 0000 BOTH - Node is nodelisted */
|
||||||
protected const O_INB = (1<<(self::O_BASE+13)); /* 0000 0100 0000 0000 0000 0000 0000 BOTH - Inbound session */
|
protected const O_INB = (1<<(self::O_BASE+13)); /* 0000 0100 0000 0000 0000 0000 0000 BOTH - Inbound session */
|
||||||
@ -192,7 +192,7 @@ abstract class Protocol
|
|||||||
public function session(int $type,SocketClient $client,Address $o=NULL): int
|
public function session(int $type,SocketClient $client,Address $o=NULL): int
|
||||||
{
|
{
|
||||||
if ($o->exists)
|
if ($o->exists)
|
||||||
Log::withContext(['ftn'=>$o->ftn]);
|
Log::withContext(['ftn'=>$o->address]);
|
||||||
|
|
||||||
Log::debug(sprintf('%s: + Start [%d]',__METHOD__,$type));
|
Log::debug(sprintf('%s: + Start [%d]',__METHOD__,$type));
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ abstract class Protocol
|
|||||||
|
|
||||||
Log::info(sprintf('%s: Total: %s - %d:%02d:%02d online, (%d) %lu%s sent, (%d) %lu%s received - %s',
|
Log::info(sprintf('%s: Total: %s - %d:%02d:%02d online, (%d) %lu%s sent, (%d) %lu%s received - %s',
|
||||||
__METHOD__,
|
__METHOD__,
|
||||||
$this->node->ftn,
|
$this->node->address,
|
||||||
$this->node->session_time/3600,
|
$this->node->session_time/3600,
|
||||||
$this->node->session_time%3600/60,
|
$this->node->session_time%3600/60,
|
||||||
$this->node->session_time%60,
|
$this->node->session_time%60,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Classes\Protocol;
|
namespace App\Classes\Protocol;
|
||||||
|
|
||||||
|
use App\Models\Setup;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
@ -24,11 +25,11 @@ final class Binkp extends BaseProtocol
|
|||||||
private const MAX_BLKSIZE = 0x7fff; /* max block size */
|
private const MAX_BLKSIZE = 0x7fff; /* max block size */
|
||||||
|
|
||||||
/* options */
|
/* options */
|
||||||
private const O_NO = 0;
|
private const O_NO = 0; /* I/They dont a capability? */
|
||||||
private const O_WANT = 1;
|
private const O_WANT = 1; /* I want a capability, but can be persuaded */
|
||||||
private const O_WE = 2;
|
private const O_WE = 2; /* We agree on a capability */
|
||||||
private const O_THEY = 4;
|
private const O_THEY = 4; /* They want a capability */
|
||||||
private const O_NEED = 8;
|
private const O_NEED = 8; /* I want a capability, and wont compromise */
|
||||||
private const O_EXT = 16;
|
private const O_EXT = 16;
|
||||||
private const O_YES = 32;
|
private const O_YES = 32;
|
||||||
|
|
||||||
@ -142,9 +143,23 @@ final class Binkp extends BaseProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we are originating, we'll show the remote our address in the same network
|
// If we are originating, we'll show the remote our address in the same network
|
||||||
// @todo Implement hiding our AKAs not in this network.
|
if ($this->originate) {
|
||||||
if ($this->originate)
|
if ($this->setup->optionGet(Setup::O_HIDEAKA)) {
|
||||||
|
$addresses = collect();
|
||||||
|
|
||||||
|
foreach ($this->node->aka_remote_authed as $ao)
|
||||||
|
$addresses = $addresses->merge($this->setup->system->match($ao->zone));
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting limited AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$addresses = $this->setup->system->addresses;
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting ALL our AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
}
|
||||||
|
|
||||||
$this->msgs(self::BPM_ADR,$this->setup->system->addresses->pluck('ftn')->join(' '));
|
$this->msgs(self::BPM_ADR,$this->setup->system->addresses->pluck('ftn')->join(' '));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,16 +169,16 @@ final class Binkp extends BaseProtocol
|
|||||||
{
|
{
|
||||||
Log::debug(sprintf('%s: + Start',__METHOD__));
|
Log::debug(sprintf('%s: + Start',__METHOD__));
|
||||||
|
|
||||||
if ($this->setup->opt_nd == self::O_WE || $this->setup->opt_nd == self::O_THEY)
|
if (($this->setup->opt_nd == self::O_WE) || ($this->setup->opt_nd == self::O_THEY))
|
||||||
$this->setup->opt_nd = self::O_NO;
|
$this->setup->opt_nd = self::O_NO;
|
||||||
|
|
||||||
if (! $this->setup->phone)
|
if (! $this->setup->phone)
|
||||||
$this->setup->phone = '-Unpublished-';
|
$this->setup->phone = '-Unpublished-';
|
||||||
|
|
||||||
if ( ! $this->optionGet(self::O_PWD) || $this->setup->opt_md != self::O_YES)
|
if (! $this->optionGet(self::O_PWD) || ($this->setup->opt_md != self::O_YES))
|
||||||
$this->setup->opt_cr = self::O_NO;
|
$this->setup->opt_cr = self::O_NO;
|
||||||
|
|
||||||
if (($this->setup->opt_cr&self::O_WE ) && ($this->setup->opt_cr&self::O_THEY)) {
|
if (($this->setup->opt_cr&self::O_WE) && ($this->setup->opt_cr&self::O_THEY)) {
|
||||||
dump('Enable crypting messages');
|
dump('Enable crypting messages');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -192,10 +207,10 @@ final class Binkp extends BaseProtocol
|
|||||||
if ($this->setup->opt_nd&self::O_WE || ($this->originate && ($this->setup->opt_nr&self::O_WANT) && $this->node->get_versionint() > 100))
|
if ($this->setup->opt_nd&self::O_WE || ($this->originate && ($this->setup->opt_nr&self::O_WANT) && $this->node->get_versionint() > 100))
|
||||||
$this->setup->opt_nr |= self::O_WE;
|
$this->setup->opt_nr |= self::O_WE;
|
||||||
|
|
||||||
if (($this->setup->opt_cht&self::O_WE ) && ($this->setup->opt_cht&self::O_WANT))
|
if (($this->setup->opt_cht&self::O_WE) && ($this->setup->opt_cht&self::O_WANT))
|
||||||
$this->setup->opt_cht = self::O_YES;
|
$this->setup->opt_cht = self::O_YES;
|
||||||
|
|
||||||
$this->setup->opt_mb = ($this->node->get_versionint() > 100 || ($this->setup->opt_mb&self::O_WE)) ? self::O_YES : self::O_NO;
|
$this->setup->opt_mb = (($this->node->get_versionint() > 100) || ($this->setup->opt_mb&self::O_WE)) ? self::O_YES : self::O_NO;
|
||||||
|
|
||||||
if ($this->node->get_versionint() > 100)
|
if ($this->node->get_versionint() > 100)
|
||||||
$this->sessionClear(self::SE_DELAYEOB);
|
$this->sessionClear(self::SE_DELAYEOB);
|
||||||
@ -665,9 +680,23 @@ final class Binkp extends BaseProtocol
|
|||||||
$this->optionSet(self::O_PWD);
|
$this->optionSet(self::O_PWD);
|
||||||
|
|
||||||
// If we are not the originator, we'll show our addresses in common.
|
// If we are not the originator, we'll show our addresses in common.
|
||||||
// @todo make this an option to hideAKAs or not
|
if (! $this->originate) {
|
||||||
if (! $this->originate)
|
if ($this->setup->optionGet(Setup::O_HIDEAKA)) {
|
||||||
$this->msgs(self::BPM_ADR,$this->setup->system->addresses->pluck('ftn')->join(' '));
|
$addresses = collect();
|
||||||
|
|
||||||
|
foreach ($this->node->aka_remote as $ao)
|
||||||
|
$addresses = $addresses->merge($this->setup->system->match($ao->zone));
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting limited AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$addresses = $this->setup->system->addresses;
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting ALL our AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->msgs(self::BPM_ADR,$addresses->pluck('ftn')->join(' '));
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -704,7 +733,7 @@ final class Binkp extends BaseProtocol
|
|||||||
if (! $this->send->total_count && $this->sessionGet(self::SE_NOFILES)) {
|
if (! $this->send->total_count && $this->sessionGet(self::SE_NOFILES)) {
|
||||||
// Add our mail to the queue if we have authenticated
|
// Add our mail to the queue if we have authenticated
|
||||||
if ($this->node->aka_authed)
|
if ($this->node->aka_authed)
|
||||||
foreach ($this->node->aka_remote as $ao) {
|
foreach ($this->node->aka_remote_authed as $ao) {
|
||||||
Log::debug(sprintf('%s: - Checking for any new mail to [%s]',__METHOD__,$ao->ftn));
|
Log::debug(sprintf('%s: - Checking for any new mail to [%s]',__METHOD__,$ao->ftn));
|
||||||
$this->send->mail($ao);
|
$this->send->mail($ao);
|
||||||
}
|
}
|
||||||
@ -981,7 +1010,6 @@ final class Binkp extends BaseProtocol
|
|||||||
$data = $this->skip_blanks(substr($buf,4));
|
$data = $this->skip_blanks(substr($buf,4));
|
||||||
|
|
||||||
while ($data && ($p = $this->strsep($data,' '))) {
|
while ($data && ($p = $this->strsep($data,' '))) {
|
||||||
|
|
||||||
if (! strcmp($p,'NR')) {
|
if (! strcmp($p,'NR')) {
|
||||||
$this->setup->opt_nr |= self::O_WE;
|
$this->setup->opt_nr |= self::O_WE;
|
||||||
|
|
||||||
@ -1046,7 +1074,7 @@ final class Binkp extends BaseProtocol
|
|||||||
|
|
||||||
$buf = $this->skip_blanks($buf);
|
$buf = $this->skip_blanks($buf);
|
||||||
|
|
||||||
if (($this->optionGet(self::O_PWD)) && $buf) {
|
if ($this->optionGet(self::O_PWD) && $buf) {
|
||||||
while (($t = $this->strsep($buf," \t")))
|
while (($t = $this->strsep($buf," \t")))
|
||||||
if (strcmp($t,'non-secure') == 0) {
|
if (strcmp($t,'non-secure') == 0) {
|
||||||
Log::debug(sprintf('%s: - Non Secure',__METHOD__));
|
Log::debug(sprintf('%s: - Non Secure',__METHOD__));
|
||||||
@ -1060,7 +1088,7 @@ final class Binkp extends BaseProtocol
|
|||||||
|
|
||||||
// Add our mail to the queue if we have authenticated
|
// Add our mail to the queue if we have authenticated
|
||||||
if ($this->node->aka_authed)
|
if ($this->node->aka_authed)
|
||||||
foreach ($this->node->aka_remote as $ao) {
|
foreach ($this->node->aka_remote_authed as $ao) {
|
||||||
$this->send->mail($ao);
|
$this->send->mail($ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,7 +1164,7 @@ final class Binkp extends BaseProtocol
|
|||||||
($this->setup->opt_nd&self::O_THEY) ? ' ND' : '',
|
($this->setup->opt_nd&self::O_THEY) ? ' ND' : '',
|
||||||
($this->setup->opt_mb&self::O_WANT) ? ' MB' : '',
|
($this->setup->opt_mb&self::O_WANT) ? ' MB' : '',
|
||||||
($this->setup->opt_cht&self::O_WANT) ? ' CHAT' : '',
|
($this->setup->opt_cht&self::O_WANT) ? ' CHAT' : '',
|
||||||
((! ($this->setup->opt_nd&self::O_WE)) != (! ($this->setup->opt_nd&self::O_THEY))) ? ' NDA': '',
|
(! ($this->setup->opt_nd&self::O_WE) != (! ($this->setup->opt_nd&self::O_THEY))) ? ' NDA': '',
|
||||||
(($this->setup->opt_cr&self::O_WE) && ($this->setup->opt_cr&self::O_THEY )) ? ' CRYPT' : '');
|
(($this->setup->opt_cr&self::O_WE) && ($this->setup->opt_cr&self::O_THEY )) ? ' CRYPT' : '');
|
||||||
|
|
||||||
if (strlen($tmp))
|
if (strlen($tmp))
|
||||||
@ -1144,7 +1172,7 @@ final class Binkp extends BaseProtocol
|
|||||||
|
|
||||||
// Add our mail to the queue if we have authenticated
|
// Add our mail to the queue if we have authenticated
|
||||||
if ($this->node->aka_authed)
|
if ($this->node->aka_authed)
|
||||||
foreach ($this->node->aka_remote as $ao) {
|
foreach ($this->node->aka_remote_authed as $ao) {
|
||||||
$this->send->mail($ao);
|
$this->send->mail($ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,10 +181,24 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
|
|||||||
// @todo We need to evaluate what the remote presents
|
// @todo We need to evaluate what the remote presents
|
||||||
$compat_codes = $this->originate ? ['ZMO','ARC','XMA'] : ['ZMO'];
|
$compat_codes = $this->originate ? ['ZMO','ARC','XMA'] : ['ZMO'];
|
||||||
|
|
||||||
|
// Only show our AKAs relevant to the site we are ccmmunicating with
|
||||||
|
if ($this->setup->optionGet(Setup::O_HIDEAKA)) {
|
||||||
|
$addresses = collect();
|
||||||
|
|
||||||
|
foreach ($this->node->aka_remote as $ao)
|
||||||
|
$addresses = $addresses->merge($this->setup->system->match($ao->zone));
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting limited AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$addresses = $this->setup->system->addresses;
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s: - Presenting ALL our AKAs [%s]',__METHOD__,$addresses->pluck('ftn')->join(',')));
|
||||||
|
}
|
||||||
|
|
||||||
// Site address, password and compatibility
|
// Site address, password and compatibility
|
||||||
// @todo Only show the AKAs that is relevant to the node we are connecting to
|
|
||||||
$makedata .= sprintf('{EMSI}{%s}{%s}{%s}{%s}',
|
$makedata .= sprintf('{EMSI}{%s}{%s}{%s}{%s}',
|
||||||
$this->setup->system->addresses->pluck('ftn')->join(' '),
|
$addresses->pluck('ftn')->join(' '),
|
||||||
$this->node->password == '-' ? '' : $this->node->password,
|
$this->node->password == '-' ? '' : $this->node->password,
|
||||||
join(',',$link_codes),
|
join(',',$link_codes),
|
||||||
join(',',$compat_codes),
|
join(',',$compat_codes),
|
||||||
@ -1169,7 +1183,7 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
|
|||||||
// See if there is anything to add to the outbound
|
// See if there is anything to add to the outbound
|
||||||
// Add our mail to the queue if we have authenticated
|
// Add our mail to the queue if we have authenticated
|
||||||
if ($this->node->aka_authed)
|
if ($this->node->aka_authed)
|
||||||
foreach ($this->node->aka_remote as $ao) {
|
foreach ($this->node->aka_remote_authed as $ao) {
|
||||||
$this->send->mail($ao);
|
$this->send->mail($ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,12 @@ class ZoneController extends Controller
|
|||||||
$o->{$key} = $request->post($key);
|
$o->{$key} = $request->post($key);
|
||||||
|
|
||||||
$o->save();
|
$o->save();
|
||||||
|
$zo = Zone::where('zone_id',$request->zone_id)
|
||||||
|
->where('domain_id',$request->domain_id)
|
||||||
|
->singleOrFail();
|
||||||
|
|
||||||
// Find the zones 0/0 address, and assign it to this host.
|
// Find the zones 0/0 address, and assign it to this host.
|
||||||
$ao = Address::where('zone_id',$request->zone_id)
|
$ao = Address::where('zone_id',$zo->id)
|
||||||
->where('region_id',0)
|
->where('region_id',0)
|
||||||
->where('host_id',0)
|
->where('host_id',0)
|
||||||
->where('node_id',0)
|
->where('node_id',0)
|
||||||
@ -76,6 +79,7 @@ class ZoneController extends Controller
|
|||||||
if (! $ao) {
|
if (! $ao) {
|
||||||
$ao = new Address;
|
$ao = new Address;
|
||||||
$ao->forceFill([
|
$ao->forceFill([
|
||||||
|
'zone_id'=>$zo->id,
|
||||||
'region_id'=>0,
|
'region_id'=>0,
|
||||||
'host_id'=>0,
|
'host_id'=>0,
|
||||||
'node_id'=>0,
|
'node_id'=>0,
|
||||||
|
@ -82,6 +82,7 @@ class Setup extends Model
|
|||||||
{
|
{
|
||||||
parent::__construct($attributes);
|
parent::__construct($attributes);
|
||||||
|
|
||||||
|
// @todo These option should be in setup?
|
||||||
$this->binkp_options = ['m','d','r','b'];
|
$this->binkp_options = ['m','d','r','b'];
|
||||||
|
|
||||||
/* EMSI SETTINGS */
|
/* EMSI SETTINGS */
|
||||||
@ -142,6 +143,8 @@ class Setup extends Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BINKP OPTIONS: BINKP_OPT_* */
|
||||||
|
|
||||||
public function binkpOptionClear(int $key): void
|
public function binkpOptionClear(int $key): void
|
||||||
{
|
{
|
||||||
$this->binkp &= ~$key;
|
$this->binkp &= ~$key;
|
||||||
@ -157,6 +160,8 @@ class Setup extends Model
|
|||||||
$this->binkp |= $key;
|
$this->binkp |= $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GENERAL OPTIONS: O_* */
|
||||||
|
|
||||||
public function optionClear(int $key): void
|
public function optionClear(int $key): void
|
||||||
{
|
{
|
||||||
$this->options &= ~$key;
|
$this->options &= ~$key;
|
||||||
|
@ -77,8 +77,8 @@ use App\Models\Setup;
|
|||||||
<h3>Site Permissions</h3>
|
<h3>Site Permissions</h3>
|
||||||
|
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="hideaka" name="options[hideaka]" value="{{ Setup::O_HIDEAKA }}" @if(old('options.hideaka',$o->binkpOptionGet(Setup::O_HIDEAKA))) checked @endif disabled>
|
<input class="form-check-input" type="checkbox" id="hideaka" name="options[hideaka]" value="{{ Setup::O_HIDEAKA }}" @if(old('options.hideaka',$o->optionGet(Setup::O_HIDEAKA))) checked @endif>
|
||||||
<label class="form-check-label" for="hideaka">Hide AKA to different Domains <sup>not implemented</sup></label>
|
<label class="form-check-label" for="hideaka">Hide AKA to different Domains</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user