Auto create Domains/Zones as systems present their AKAs to us
This commit is contained in:
parent
55a2a67b8d
commit
d5d4a0d781
@ -35,6 +35,7 @@ class Node
|
|||||||
|
|
||||||
private Collection $ftns; // The FTNs of the remote system
|
private Collection $ftns; // The FTNs of the remote system
|
||||||
private Collection $ftns_authed; // The FTNs we have validated
|
private Collection $ftns_authed; // The FTNs we have validated
|
||||||
|
private Collection $ftns_other; // Other FTN addresses presented
|
||||||
private bool $authed; // Have we authenticated the remote.
|
private bool $authed; // Have we authenticated the remote.
|
||||||
|
|
||||||
private int $options; // This nodes capabilities/options
|
private int $options; // This nodes capabilities/options
|
||||||
@ -46,6 +47,7 @@ class Node
|
|||||||
$this->start_time = Carbon::now();
|
$this->start_time = Carbon::now();
|
||||||
$this->ftns = collect();
|
$this->ftns = collect();
|
||||||
$this->ftns_authed = collect();
|
$this->ftns_authed = collect();
|
||||||
|
$this->ftns_other = collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,6 +74,10 @@ class Node
|
|||||||
case 'aka_authed':
|
case 'aka_authed':
|
||||||
return $this->authed;
|
return $this->authed;
|
||||||
|
|
||||||
|
// FTNs that we dont know about
|
||||||
|
case 'aka_other':
|
||||||
|
return $this->ftns_other;
|
||||||
|
|
||||||
// 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 : '-';
|
||||||
@ -125,6 +131,17 @@ class Node
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'ftn_other':
|
||||||
|
// Ignore any duplicate FTNs that we get
|
||||||
|
if ($this->ftns_other->search($value) !== FALSE) {
|
||||||
|
Log::debug(sprintf('%s: - Ignoring Duplicate FTN [%s]',__METHOD__,$value->ftn));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ftns_other->push($value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 'system':
|
case 'system':
|
||||||
case 'sysop':
|
case 'sysop':
|
||||||
case 'location':
|
case 'location':
|
||||||
@ -159,26 +176,40 @@ class Node
|
|||||||
public function auth(string $password,string $challenge=''): int
|
public function auth(string $password,string $challenge=''): int
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('%s:+ auth [%s]',self::LOGKEY,$password));
|
Log::debug(sprintf('%s:+ auth [%s]',self::LOGKEY,$password));
|
||||||
|
$so = NULL;
|
||||||
|
|
||||||
// Make sure we havent been here already
|
// Make sure we havent been here already
|
||||||
if ($this->ftns_authed->count())
|
if ($this->ftns_authed->count())
|
||||||
throw new Exception('Already authed');
|
throw new Exception('Already authed');
|
||||||
|
|
||||||
foreach ($this->ftns as $o) {
|
foreach ($this->ftns as $o) {
|
||||||
if (! $o->session('sespass'))
|
if (! $sespass=$o->session('sespass'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If we have challenge, then we are doing MD5
|
// If we have challenge, then we are doing MD5
|
||||||
$exp_pwd = $challenge ? $this->md5_challenge($o->session('sespass'),$challenge) : $o->session('sespass');
|
$exp_pwd = $challenge ? $this->md5_challenge($sespass,$challenge) : $sespass;
|
||||||
|
|
||||||
if ($exp_pwd === $password) {
|
if ($exp_pwd === $password) {
|
||||||
$o->system->last_session = Carbon::now();
|
if (! $so)
|
||||||
$o->system->save();
|
$so = $o->system;
|
||||||
|
|
||||||
|
// Make sure we are the same system
|
||||||
|
if ($so->id !== $o->system->id) {
|
||||||
|
Log::alert(sprintf('%s:! AKA [%s] is from a different system?',self::LOGKEY,$o->ftn),['so'=>$so->name]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$this->ftns_authed->push($o);
|
$this->ftns_authed->push($o);
|
||||||
$this->authed = TRUE;
|
$this->authed = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->authed) {
|
||||||
|
$o->system->last_session = Carbon::now();
|
||||||
|
$o->system->save();
|
||||||
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('%s:= auth, we authed [%d] addresses',self::LOGKEY,$this->ftns_authed->count()));
|
Log::debug(sprintf('%s:= auth, we authed [%d] addresses',self::LOGKEY,$this->ftns_authed->count()));
|
||||||
return $this->ftns_authed->count();
|
return $this->ftns_authed->count();
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Log;
|
|||||||
use App\Classes\File\{Receive,Send};
|
use App\Classes\File\{Receive,Send};
|
||||||
use App\Classes\Sock\SocketClient;
|
use App\Classes\Sock\SocketClient;
|
||||||
use App\Classes\Sock\SocketException;
|
use App\Classes\Sock\SocketException;
|
||||||
use App\Models\{Address,Setup};
|
use App\Models\{Address,Setup,System};
|
||||||
|
|
||||||
abstract class Protocol
|
abstract class Protocol
|
||||||
{
|
{
|
||||||
@ -313,6 +313,19 @@ abstract class Protocol
|
|||||||
(($rc & self::S_MASK) == self::S_OK) ? 'Successful' : 'Failed',
|
(($rc & self::S_MASK) == self::S_OK) ? 'Successful' : 'Failed',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// Add unknown FTNs to the DB
|
||||||
|
if ($this->node->aka_remote_authed->count()) {
|
||||||
|
$so = $this->node->aka_remote_authed->first()->system;
|
||||||
|
} else {
|
||||||
|
$so = System::where('name','Discovered System')->single();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($so && $so->exists) {
|
||||||
|
foreach ($this->node->aka_other as $aka) {
|
||||||
|
Address::findFTN($aka,TRUE,$so);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @todo Log to history log in the DB.
|
// @todo Log to history log in the DB.
|
||||||
//if ($this->node->start_time && $this->setup->cfg('CFG_HISTORY')) {}
|
//if ($this->node->start_time && $this->setup->cfg('CFG_HISTORY')) {}
|
||||||
|
|
||||||
|
@ -632,6 +632,7 @@ final class Binkp extends BaseProtocol
|
|||||||
if (! ($o = Address::findFTN($rem_aka))) {
|
if (! ($o = Address::findFTN($rem_aka))) {
|
||||||
Log::debug(sprintf('%s: ? AKA is UNKNOWN [%s]',self::LOGKEY,$rem_aka));
|
Log::debug(sprintf('%s: ? AKA is UNKNOWN [%s]',self::LOGKEY,$rem_aka));
|
||||||
|
|
||||||
|
$this->node->ftn_other = $rem_aka;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +303,8 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
|
|||||||
try {
|
try {
|
||||||
if (! ($o = Address::findFTN($rem_aka))) {
|
if (! ($o = Address::findFTN($rem_aka))) {
|
||||||
Log::debug(sprintf('%s: ? AKA is UNKNOWN [%s]',self::LOGKEY,$rem_aka));
|
Log::debug(sprintf('%s: ? AKA is UNKNOWN [%s]',self::LOGKEY,$rem_aka));
|
||||||
|
|
||||||
|
$this->node->ftn_other = $rem_aka;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,13 +343,15 @@ class Address extends Model
|
|||||||
/**
|
/**
|
||||||
* Find a record in the DB for a node string, eg: 10:1/1.0
|
* Find a record in the DB for a node string, eg: 10:1/1.0
|
||||||
*
|
*
|
||||||
* @param string $ftn
|
* @param string $address
|
||||||
|
* @param bool $create
|
||||||
|
* @param System|null $so
|
||||||
* @return Address|null
|
* @return Address|null
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function findFTN(string $ftn): ?self
|
public static function findFTN(string $address,bool $create=FALSE,System $so=NULL): ?self
|
||||||
{
|
{
|
||||||
$ftn = self::parseFTN($ftn);
|
$ftn = self::parseFTN($address);
|
||||||
|
|
||||||
// Are we looking for a region address
|
// Are we looking for a region address
|
||||||
if (($ftn['f'] === 0) && $ftn['p'] === 0) {
|
if (($ftn['f'] === 0) && $ftn['p'] === 0) {
|
||||||
@ -411,6 +413,60 @@ class Address extends Model
|
|||||||
})
|
})
|
||||||
->single();
|
->single();
|
||||||
|
|
||||||
|
if ($create) {
|
||||||
|
if (! $so)
|
||||||
|
throw new Exception(sprintf('%s:AKA create requested for [%s], but system not provided',self::LOGKEY,$address));
|
||||||
|
|
||||||
|
if (! $ftn['d']) {
|
||||||
|
Log::alert(sprintf('%s:! Refusing to create address [%s] no domain available',self::LOGKEY,$address));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::debug(sprintf('%s:Creating AKA [%s] for [%s]',self::LOGKEY,$address,$so->name));
|
||||||
|
|
||||||
|
// Check Domain exists
|
||||||
|
Domain::unguard();
|
||||||
|
$do = Domain::singleOrNew(['name'=>$ftn['d']]);
|
||||||
|
Domain::reguard();
|
||||||
|
|
||||||
|
if (! $do->exists) {
|
||||||
|
$do->public = TRUE;
|
||||||
|
$do->active = TRUE;
|
||||||
|
$do->notes = 'Auto created';
|
||||||
|
$do->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create zone
|
||||||
|
Zone::unguard();
|
||||||
|
$zo = Zone::singleOrNew(['domain_id'=>$do->id,'zone_id'=>$ftn['z']]);
|
||||||
|
Zone::reguard();
|
||||||
|
|
||||||
|
if (! $zo->exists) {
|
||||||
|
$zo->active = TRUE;
|
||||||
|
$zo->notes = 'Auto created';
|
||||||
|
$zo->system_id = System::where('name','Discovered System')->single()->id;
|
||||||
|
$do->zones()->save($zo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $zo->active || ! $do->active) {
|
||||||
|
Log::alert(sprintf('%s:! Refusing to create address [%s] in disabled zone or domain',self::LOGKEY,$address));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Address, assigned to $so
|
||||||
|
$o = new self;
|
||||||
|
$o->active = TRUE;
|
||||||
|
$o->zone_id = $zo->id;
|
||||||
|
$o->region_id = 0;
|
||||||
|
$o->host_id = $ftn['n'];
|
||||||
|
$o->node_id = $ftn['f'];
|
||||||
|
$o->point_id = $ftn['p'];
|
||||||
|
$o->role = self::NODE_UNKNOWN;
|
||||||
|
$so->addresses()->save($o);
|
||||||
|
}
|
||||||
|
|
||||||
return ($o && $o->system->active) ? $o : NULL;
|
return ($o && $o->system->active) ? $o : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class Domain extends Model
|
|||||||
|
|
||||||
/* ATTRIBUTES */
|
/* ATTRIBUTES */
|
||||||
|
|
||||||
public function getHomePageAttribute(string $value): string
|
public function getHomePageAttribute(?string $value): string
|
||||||
{
|
{
|
||||||
//0xFD2FB528
|
//0xFD2FB528
|
||||||
return $this->castAttribute('homepage',$value) ?: 'No available information at the moment.';
|
return $this->castAttribute('homepage',$value) ?: 'No available information at the moment.';
|
||||||
|
Loading…
Reference in New Issue
Block a user