LINUX.ORG.RU

Ещё один jabber-shell


0

0

Идея витает в воздухе давно, есть несколько реализаций разной степени запущенности. Большинство использует Net::XMPP и Net::Jabber и имеют проблемы.

Этот скрипт использует AnyEvent::XMPP и основан на примере в исходниках оного. Работает.

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use utf8;
use locale;
use open qw( :utf8 :std );
use Getopt::Long qw(:config bundling);
use AnyEvent;
use AnyEvent::XMPP::Client;
use AnyEvent::XMPP::Ext::Disco;
use AnyEvent::XMPP::Ext::Version;
use AnyEvent::XMPP::Namespaces qw/xmpp_ns/;


my $SCRIPT = $0;
my $VERSION = '0.1';
my $PORT = '5222';
my $PASSWORD = '';
my @ADMINS = ();
my $JID = '';
my $DEBUG = 0;
my $TLS = 1;
my $HTTP = 0;

sub usage
{
    print <<USAGE;
Jabber shell v$VERSION: shell robot to execute commands via jabber

Usage: $SCRIPT [options]


Options (default in brackets):
    --jid,      -j  jabber ID, e. g. 'name\@jabber.org' or 'name\@jabber.org/resource'
    --password, -w  password for the account ($PASSWORD)
    --port,     -p  port to connect ($PORT)

    --admin,    -a  authorized accounts to execute commands from (@ADMINS)

    --[no]debug     turn debug on/off ($DEBUG)

    --help,     -h  this help message


Examples:

$SCRIPT -j solo\@jabber.ru/home -w qwerty --admin buck\@jabber.org

USAGE

    exit (0);
}

GetOptions(
    'port|p=i'       => \$PORT,
    'password|passwd|w=s'   => \$PASSWORD,
    'admin|a=s'      => \@ADMINS,
    'debug|d!'       => \$DEBUG,
    'jid|jabber|j=s' => \$JID,
    'help|h'         => sub {usage}
);

unless ($JID)
{
    usage();
}


my $j       = AnyEvent->condvar;
my $cl      = AnyEvent::XMPP::Client->new (debug => $DEBUG);
my $disco   = AnyEvent::XMPP::Ext::Disco->new;
my $version = AnyEvent::XMPP::Ext::Version->new;

$cl->add_extension ($disco);
$cl->add_extension ($version);

$cl->set_presence (undef, "Jabber shell bot v$VERSION", 1);

$cl->add_account ($JID, $PASSWORD);
warn "connecting to $JID...\n";

$cl->reg_cb (
   session_ready => sub {
      my ($cl, $acc) = @_;
      warn "connected!\n";
   },
   contact_request_subscribe => sub {
      my ($cl, $acc, $roster, $contact) = @_;
      $contact->send_subscribed;
      warn 'Subscribed to ' . $contact->jid . "\n";
   },
   error => sub {
      my ($cl, $acc, $error) = @_;
      warn 'Error encountered: ' . $error->string . "\n";
      $j->broadcast;
   },
   disconnect => sub {
      warn "Got disconnected: [@_]\n";
      $j->broadcast;
   },
   message => sub {
      my ($cl, $acc, $msg) = @_;
      return unless $msg;
      my $cmd = $msg->any_body;
      my $adm = $msg->from;

      warn "# $adm -> $cmd:\n";

      my $repl = $msg->make_reply;

      if ($adm ~~ @ADMINS)
      {
          my $out = '';
          if ($cmd =~ s/^\s*cd\s+//)
          {
             $out = chdir($cmd) ? `pwd` : 'Failed'
          } else
          {
              $out = `$cmd 2>&1`
          }
          if ($out)
          {
            warn $out;
            $repl->add_body($out);
          }
      } else
      {
          warn "Forbidden.\n";
          $repl->add_body('Forbidden');
      }

      $repl->send;
   },
);

$cl->start;

$j->wait;

exit(0);
☆☆

Ответ на: комментарий от ip1981

>В идеале, конечно, надо иметь поРноценную сессию с shell Неплохая опечатка:)

Dikar ★★
()
Ответ на: комментарий от mv

Похоже тема дискуссии не соответствует ожиданиям топикстартера:)

Dikar ★★
()
Ответ на: комментарий от provaton

> Юзкейсы?

по моему опыту, такие штуки используют, когда кажется, что это то, что нужно, для того, чтобы убедиться, что это не то, что нужно.

name_no ★★
()

интереснее xml-rpc over jabber
как минимум секурнее ;]

hizel ★★★★★
()
Ответ на: комментарий от ip1981

Хренасе юзкейс. Никогда бы не подумал. Это ваша реальная задача? Ну, решение вполне ничего себе так.

provaton ★★★★★
()
Ответ на: комментарий от ip1981

> надо иметь полноценную сессию с shell

Тут больше не сессии не хватает, а терминала. Редактор не запустить, а без этого уже особо не поадминишь.

provaton ★★★★★
()

Это все так, игрушки. В моем боте тоже есть такая "фича", так, пару команд выполнить, не более того. Что например будет если набрать sudo ls или просто cat и можно ли отправить Ctrl+C? =) Как уже говорили нужен терминал, хотя может будет проще поднять PPPoJ.

Lucky1 ★★★
()
Ответ на: комментарий от Lucky1

Зато это лучше, чем на команду ifconfig -a получить ответ "Ух-ты!" :-)

А на команду "upgradepkg" - "я это уже делал"

:-)

ip1981 ☆☆
() автор топика
Ответ на: комментарий от ip1981

>Зато это лучше, чем на команду ifconfig -a получить ответ "Ух-ты!" :-)
>А на команду "upgradepkg" - "я это уже делал"


Если это про талисмана, то это не моя разработка =) А вообще такое у него вроде отключается.

Lucky1 ★★★
()
Ответ на: комментарий от Lucky1

Нет, это человеческий фактор ;-)

ip1981 ☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.