Ferreteria/v0.6/clade/IO/Aspect/Connx/Process/SSH2

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | IO‎ | Aspect‎ | Connx
Jump to navigation Jump to search
The item documented here has been removed and is no longer in use.
This functionality has been moved to IO\Aspect\Connx\Stream\Runner\Remote.

Code

Full contents as of 2026-02-10, just before deletion (but with comment-out removed):

<?php namespace Woozalia\Ferret\IO\Aspect\Connx\Stream\Stream\Process;
// DOCS:

#use posix_getlogin;
use ssh2_auth_agent;
use ssh2_connect;
#use ssh2_tunnel;
// NOTE: These ^ require the php-ssh2 package.

/* CommOp* [c,i] */ use Woozalia\Ferret\IO\Aspect\Connx\aux\itWent\{ cCommOp as CommOpClass, iCommOp as CommOpIface };
/* Base*  [ca,i] */ use Woozalia\Ferret\IO\Aspect\Connx\Stream\Runner\{ caRemote as BaseClass, iRemote as BaseIface };
/* CLineIface    */ use Woozalia\Ferret\Sys\Data\Codec\aux\iCmdLine as CLineIface;
/* CredsIface    */ use Woozalia\Ferret\IO\Aspect\iCreds as CredsIface;
/* QRes*   [c,i] */ use Woozalia\Ferret\Data\Mem\QVar\{cRes as QResClass, iRes as QResIface };
/* Result* [c,i] */ use Woozalia\Ferret\IO\Aspect\Connx\aux\itWent\{ cProcOp as ResultClass, iProcOp as ResultIface };
/* StreamClass   */ use Woozalia\Ferret\IO\Aspect\Connx\Stream\Native\cGeneric as StreamClass;
/* Tunnel* [c,i] */ use Woozalia\Ferret\IO\Aspect\Connx\aux\{ cTunnel as TunnelClass, iTunnel as TunnelIface };

//* 2026-02-02 moved to Connx\Stream\Runner\Remote
interface iSSH2 extends BaseIface {
    // OBJECTS
    #function OCred() : CredsIface;
}
class cSSH2 extends BaseClass implements iSSH2 {

    // ++ CONFIG ++ //

    public function SType()             : string { return 'ssh plug'; }

    // -- CONFIG -- //
    // ++ LIFECYCLE ++ //

    protected function ActualOpen() : CommOpIface {

        $oAct = $this->ItWentLike();

        // [+STANDARD CODE]: get connection specs

        $oCred = $this->OCred();
        $oSock = $this->OSock();
        $oHost = $oSock->OHost();
        $sUser = $oCred->QSUser()->GetIt();
        $sHost = $oHost->QSAddr()->GetIt();
        $onPort = $oHost->QIPort();

        // [-STANDARD CODE]

        if ($onPort->HasIt()) {
            $nPort = $onPort->GetIt();
            $ftRem = "$sUser@$sHost:$nPort";
        } else {
            $ftRem = "$sUser@$sHost";
        }

        echo "Opening SSH connection to [$ftRem]...".CRLF;
        try {
            if ($onPort->HasIt()) {
                $rSSH = @ssh2_connect($sHost, $nPort);
            } else {
                $rSSH = @ssh2_connect($sHost); // use ssh2_connect's default port
            }
        } catch (\Exception $e) {
            $rSSH = FALSE;
            echo $e;
            $this->AmHere('TODO 2025-12-07: better diagnostics');
        }
        if ($rSSH === FALSE) {
            $arErr = error_get_last();
            $oScrn = self::Screen();
            echo $oScrn->ErrorIt('Connection error').': '.$arErr['message'].CRLF;
            die();
        }
        $this->QNative()->SetIt($rSSH);

        $ftUser = self::Screen()->GreenIt($sUser);
        echo "Authenticating remote user '$ftUser'...".CRLF;
        @$rok = ssh2_auth_agent($rSSH,$sUser);
        $ok = ($rok !== FALSE);
        $oAct->SetOkay($ok);
        if ($ok) {
            $oAct->AddMsgString("User authenticated.");
        } else {
            $oAct->AddMsgString("SSH connection failed.");
        }
        return $oAct;
    }
    protected function ActualShut() : CommOpIface {
        $rConn = $this->QNative()->GetIt();
        $ok = ssh2_disconnect($rConn);
        $oAct = $this->ItWentLike();
        $oAct->SetOkay($ok);
        return $oAct;
    }

    // -- LIFECYCLE -- //
    // ++ UI ++ //

    public function DescribeInline() : string { return 'SSH -> '.$this->TargetString(); }
    protected function TargetString() : string {

        #echo $this->ReflectThis()->Report();

        $oCred = $this->OCred();
        #$oSock = $this->OSock();
        #$oHost = $oSock->OHost();
        $oHost = $this->OHost();

        $sUser = $oCred->QSUser()->GetIt();
        $sHost = $oHost->QSAddr()->GetIt();
        $onPort = $oHost->QIPort();

        if ($onPort->HasIt()) {
            $nPort = $onPort->GetIt();
            $ftRem = "$sUser@$sHost:$nPort";
        } else {
            $ftRem = "$sUser@$sHost";
        }

        $oServer = $this->OServer();
        $ftRem .= ' => '.$oServer->DescribeInline();

        return $ftRem;
    }

    // -- UI -- //
    // ++ OBJECTS ++ //

    private $osNat = NULL; protected function QNative() : QResIface { return $this->osNat ?? ($this->osNat = QResClass::AsNew()); }

    public function NewTunnel(CredsIface $oICreds, ?int $nPortLocal=NULL) : TunnelIface {
        return new TunnelClass($this->Creds(),$oICreds,$nPortLocal);
    }

    // -- OBJECTS -- //
    // ++ ACTION ++ //

    // DOCS: https://wooz.dev/Ferreteria/v0.6/clade/IO/Aspect/Connx/Plug/Shell/Remote/SSH/@fx/DoCommand
    public function DoCommand(CLineIface $oCmd) : ResultIface {
      $this->AmHere("COMMAND for ssh: ".$oCmd->AsString());
        $rStrm = $this->QNative()->GetIt();
        $rRecv = ssh2_exec($rStrm, $oCmd->AsString());
        $oStream = StreamClass::FromNative($rRecv);
        $oCommOp = $oStream->PullBytes();
        #echo $oCommOp->VIEW_AsBlock();

        $oProcOp = new ResultClass;
        $oProcOp->CopyFrom($oCommOp);

        return $oProcOp;
    }

    // -- ACTION -- //
}