comparison plugins/mod_admin_telnet.lua @ 5720:449399a7e136

Merge
author Matthew Wild <mwild1@gmail.com>
date Sat, 29 Jun 2013 14:45:47 +0100
parents e66bbfdf588e
children 7722372aa087
comparison
equal deleted inserted replaced
5719:84025249fc04 5720:449399a7e136
15 15
16 local _G = _G; 16 local _G = _G;
17 17
18 local prosody = _G.prosody; 18 local prosody = _G.prosody;
19 local hosts = prosody.hosts; 19 local hosts = prosody.hosts;
20 local incoming_s2s = prosody.incoming_s2s;
21 20
22 local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" }; 21 local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" };
23 22
24 local iterators = require "util.iterators"; 23 local iterators = require "util.iterators";
25 local keys, values = iterators.keys, iterators.values; 24 local keys, values = iterators.keys, iterators.values;
482 end 481 end
483 482
484 function def_env.hosts:add(name) 483 function def_env.hosts:add(name)
485 end 484 end
486 485
486 local function session_flags(session, line)
487 line = line or {};
488 if session.cert_identity_status == "valid" then
489 line[#line+1] = "(secure)";
490 elseif session.secure then
491 line[#line+1] = "(encrypted)";
492 end
493 if session.compressed then
494 line[#line+1] = "(compressed)";
495 end
496 if session.smacks then
497 line[#line+1] = "(sm)";
498 end
499 if session.ip and session.ip:match(":") then
500 line[#line+1] = "(IPv6)";
501 end
502 return table.concat(line, " ");
503 end
504
487 def_env.c2s = {}; 505 def_env.c2s = {};
488 506
489 local function show_c2s(callback) 507 local function show_c2s(callback)
490 for hostname, host in pairs(hosts) do 508 for hostname, host in pairs(hosts) do
491 for username, user in pairs(host.sessions or {}) do 509 for username, user in pairs(host.sessions or {}) do
517 end 535 end
518 if (not match_jid) or jid:match(match_jid) then 536 if (not match_jid) or jid:match(match_jid) then
519 count = count + 1; 537 count = count + 1;
520 local status, priority = "unavailable", tostring(session.priority or "-"); 538 local status, priority = "unavailable", tostring(session.priority or "-");
521 if session.presence then 539 if session.presence then
522 status = session.presence:child_with_name("show"); 540 status = session.presence:get_child_text("show") or "available";
523 if status then 541 end
524 status = status:get_text() or "[invalid!]"; 542 print(session_flags(session, { " "..jid.." - "..status.."("..priority..")" }));
525 else
526 status = "available";
527 end
528 end
529 print(" "..jid.." - "..status.."("..priority..")");
530 end 543 end
531 end); 544 end);
532 return true, "Total: "..count.." clients"; 545 return true, "Total: "..count.." clients";
533 end 546 end
534 547
563 end 576 end
564 end); 577 end);
565 return true, "Total: "..count.." sessions closed"; 578 return true, "Total: "..count.." sessions closed";
566 end 579 end
567 580
568 local function session_flags(session, line)
569 if session.cert_identity_status == "valid" then
570 line[#line+1] = "(secure)";
571 elseif session.secure then
572 line[#line+1] = "(encrypted)";
573 end
574 if session.compressed then
575 line[#line+1] = "(compressed)";
576 end
577 if session.smacks then
578 line[#line+1] = "(sm)";
579 end
580 if session.conn and session.conn:ip():match(":") then
581 line[#line+1] = "(IPv6)";
582 end
583 return table.concat(line, " ");
584 end
585 581
586 def_env.s2s = {}; 582 def_env.s2s = {};
587 function def_env.s2s:show(match_jid) 583 function def_env.s2s:show(match_jid)
588 local _print = self.session.print;
589 local print = self.session.print; 584 local print = self.session.print;
590 585
591 local count_in, count_out = 0,0; 586 local count_in, count_out = 0,0;
592 587 local s2s_list = { };
593 for host, host_session in pairs(hosts) do 588
594 print = function (...) _print(host); _print(...); print = _print; end 589 local s2s_sessions = module:shared"/*/s2s/sessions";
595 for remotehost, session in pairs(host_session.s2sout) do 590 for _, session in pairs(s2s_sessions) do
596 if (not match_jid) or remotehost:match(match_jid) or host:match(match_jid) then 591 local remotehost, localhost, direction;
597 count_out = count_out + 1; 592 if session.direction == "outgoing" then
598 print(session_flags(session, {" ", host, "->", remotehost})); 593 direction = "->";
599 if session.sendq then 594 count_out = count_out + 1;
600 print(" There are "..#session.sendq.." queued outgoing stanzas for this connection"); 595 remotehost, localhost = session.to_host or "?", session.from_host or "?";
596 else
597 direction = "<-";
598 count_in = count_in + 1;
599 remotehost, localhost = session.from_host or "?", session.to_host or "?";
600 end
601 local sess_lines = { l = localhost, r = remotehost,
602 session_flags(session, { "", direction, remotehost or "?",
603 "["..session.type..tostring(session):match("[a-f0-9]*$").."]" })};
604
605 if (not match_jid) or remotehost:match(match_jid) or localhost:match(match_jid) then
606 table.insert(s2s_list, sess_lines);
607 local print = function (s) table.insert(sess_lines, " "..s); end
608 if session.sendq then
609 print("There are "..#session.sendq.." queued outgoing stanzas for this connection");
610 end
611 if session.type == "s2sout_unauthed" then
612 if session.connecting then
613 print("Connection not yet established");
614 if not session.srv_hosts then
615 if not session.conn then
616 print("We do not yet have a DNS answer for this host's SRV records");
617 else
618 print("This host has no SRV records, using A record instead");
619 end
620 elseif session.srv_choice then
621 print("We are on SRV record "..session.srv_choice.." of "..#session.srv_hosts);
622 local srv_choice = session.srv_hosts[session.srv_choice];
623 print("Using "..(srv_choice.target or ".")..":"..(srv_choice.port or 5269));
624 end
625 elseif session.notopen then
626 print("The <stream> has not yet been opened");
627 elseif not session.dialback_key then
628 print("Dialback has not been initiated yet");
629 elseif session.dialback_key then
630 print("Dialback has been requested, but no result received");
601 end 631 end
602 if session.type == "s2sout_unauthed" then 632 end
603 if session.connecting then 633 if session.type == "s2sin_unauthed" then
604 print(" Connection not yet established"); 634 print("Connection not yet authenticated");
605 if not session.srv_hosts then 635 elseif session.type == "s2sin" then
606 if not session.conn then 636 for name in pairs(session.hosts) do
607 print(" We do not yet have a DNS answer for this host's SRV records"); 637 if name ~= session.from_host then
608 else 638 print("also hosts "..tostring(name));
609 print(" This host has no SRV records, using A record instead");
610 end
611 elseif session.srv_choice then
612 print(" We are on SRV record "..session.srv_choice.." of "..#session.srv_hosts);
613 local srv_choice = session.srv_hosts[session.srv_choice];
614 print(" Using "..(srv_choice.target or ".")..":"..(srv_choice.port or 5269));
615 end
616 elseif session.notopen then
617 print(" The <stream> has not yet been opened");
618 elseif not session.dialback_key then
619 print(" Dialback has not been initiated yet");
620 elseif session.dialback_key then
621 print(" Dialback has been requested, but no result received");
622 end 639 end
623 end 640 end
624 end 641 end
625 end 642 end
626 local subhost_filter = function (h) 643 end
627 return (match_jid and h:match(match_jid)); 644
628 end 645 -- Sort by local host, then remote host
629 for session in pairs(incoming_s2s) do 646 table.sort(s2s_list, function(a,b)
630 if session.to_host == host and ((not match_jid) or host:match(match_jid) 647 if a.l == b.l then return a.r < b.r; end
631 or (session.from_host and session.from_host:match(match_jid)) 648 return a.l < b.l;
632 -- Pft! is what I say to list comprehensions 649 end);
633 or (session.hosts and #array.collect(keys(session.hosts)):filter(subhost_filter)>0)) then 650 local lasthost;
634 count_in = count_in + 1; 651 for _, sess_lines in ipairs(s2s_list) do
635 print(session_flags(session, {" ", host, "<-", session.from_host or "(unknown)"})); 652 if sess_lines.l ~= lasthost then print(sess_lines.l); lasthost=sess_lines.l end
636 if session.type == "s2sin_unauthed" then 653 for _, line in ipairs(sess_lines) do print(line); end
637 print(" Connection not yet authenticated"); 654 end
638 end
639 for name in pairs(session.hosts) do
640 if name ~= session.from_host then
641 print(" also hosts "..tostring(name));
642 end
643 end
644 end
645 end
646
647 print = _print;
648 end
649
650 for session in pairs(incoming_s2s) do
651 if not session.to_host and ((not match_jid) or session.from_host and session.from_host:match(match_jid)) then
652 count_in = count_in + 1;
653 print("Other incoming s2s connections");
654 print(" (unknown) <- "..(session.from_host or "(unknown)"));
655 end
656 end
657
658 return true, "Total: "..count_out.." outgoing, "..count_in.." incoming connections"; 655 return true, "Total: "..count_out.." outgoing, "..count_in.." incoming connections";
659 end 656 end
660 657
661 local function print_subject(print, subject) 658 local function print_subject(print, subject)
662 for _, entry in ipairs(subject) do 659 for _, entry in ipairs(subject) do
684 end 681 end
685 682
686 function def_env.s2s:showcert(domain) 683 function def_env.s2s:showcert(domain)
687 local ser = require "util.serialization".serialize; 684 local ser = require "util.serialization".serialize;
688 local print = self.session.print; 685 local print = self.session.print;
689 local domain_sessions = set.new(array.collect(keys(incoming_s2s))) 686 local s2s_sessions = module:shared"/*/s2s/sessions";
690 /function(session) return session.from_host == domain and session or nil; end; 687 local domain_sessions = set.new(array.collect(values(s2s_sessions)))
691 for local_host in values(prosody.hosts) do 688 /function(session) return (session.to_host == domain or session.from_host == domain) and session or nil; end;
692 local s2sout = local_host.s2sout;
693 if s2sout and s2sout[domain] then
694 domain_sessions:add(s2sout[domain]);
695 end
696 end
697 local cert_set = {}; 689 local cert_set = {};
698 for session in domain_sessions do 690 for session in domain_sessions do
699 local conn = session.conn; 691 local conn = session.conn;
700 conn = conn and conn:socket(); 692 conn = conn and conn:socket();
701 if not conn.getpeerchain then 693 if not conn.getpeerchain then
782 .." presented by "..domain.."."); 774 .." presented by "..domain..".");
783 end 775 end
784 776
785 function def_env.s2s:close(from, to) 777 function def_env.s2s:close(from, to)
786 local print, count = self.session.print, 0; 778 local print, count = self.session.print, 0;
787 779 local s2s_sessions = module:shared"/*/s2s/sessions";
788 if not (from and to) then 780
781 local match_id;
782 if from and not to then
783 match_id, from = from;
784 elseif not to then
789 return false, "Syntax: s2s:close('from', 'to') - Closes all s2s sessions from 'from' to 'to'"; 785 return false, "Syntax: s2s:close('from', 'to') - Closes all s2s sessions from 'from' to 'to'";
790 elseif from == to then 786 elseif from == to then
791 return false, "Both from and to are the same... you can't do that :)"; 787 return false, "Both from and to are the same... you can't do that :)";
792 end 788 end
793 789
794 if hosts[from] and not hosts[to] then 790 for _, session in pairs(s2s_sessions) do
795 -- Is an outgoing connection 791 local id = session.type..tostring(session):match("[a-f0-9]+$");
796 local session = hosts[from].s2sout[to]; 792 if (match_id and match_id == id)
797 if not session then 793 or (session.from_host == from and session.to_host == to) then
798 print("No outgoing connection from "..from.." to "..to) 794 print(("Closing connection from %s to %s [%s]"):format(session.from_host, session.to_host, id));
799 else
800 (session.close or s2smanager.destroy_session)(session); 795 (session.close or s2smanager.destroy_session)(session);
801 count = count + 1; 796 count = count + 1 ;
802 print("Closed outgoing session from "..from.." to "..to); 797 end
803 end 798 end
804 elseif hosts[to] and not hosts[from] then
805 -- Is an incoming connection
806 for session in pairs(incoming_s2s) do
807 if session.to_host == to and session.from_host == from then
808 (session.close or s2smanager.destroy_session)(session);
809 count = count + 1;
810 end
811 end
812
813 if count == 0 then
814 print("No incoming connections from "..from.." to "..to);
815 else
816 print("Closed "..count.." incoming session"..((count == 1 and "") or "s").." from "..from.." to "..to);
817 end
818 elseif hosts[to] and hosts[from] then
819 return false, "Both of the hostnames you specified are local, there are no s2s sessions to close";
820 else
821 return false, "Neither of the hostnames you specified are being used on this server";
822 end
823
824 return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s"); 799 return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s");
825 end 800 end
826 801
827 function def_env.s2s:closeall(host) 802 function def_env.s2s:closeall(host)
828 local count = 0; 803 local count = 0;
829 804 local s2s_sessions = module:shared"/*/s2s/sessions";
830 if not host or type(host) ~= "string" then return false, "wrong syntax: please use s2s:closeall('hostname.tld')"; end 805 for _,session in pairs(s2s_sessions) do
831 if hosts[host] then 806 if not host or session.from_host == host or session.to_host == host then
832 for session in pairs(incoming_s2s) do 807 session:close();
833 if session.to_host == host then
834 (session.close or s2smanager.destroy_session)(session);
835 count = count + 1; 808 count = count + 1;
836 end 809 end
837 end 810 end
838 for _, session in pairs(hosts[host].s2sout) do
839 (session.close or s2smanager.destroy_session)(session);
840 count = count + 1;
841 end
842 else
843 for session in pairs(incoming_s2s) do
844 if session.from_host == host then
845 (session.close or s2smanager.destroy_session)(session);
846 count = count + 1;
847 end
848 end
849 for _, h in pairs(hosts) do
850 if h.s2sout[host] then
851 (h.s2sout[host].close or s2smanager.destroy_session)(h.s2sout[host]);
852 count = count + 1;
853 end
854 end
855 end
856
857 if count == 0 then return false, "No sessions to close."; 811 if count == 0 then return false, "No sessions to close.";
858 else return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s"); end 812 else return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s"); end
859 end 813 end
860 814
861 def_env.host = {}; def_env.hosts = def_env.host; 815 def_env.host = {}; def_env.hosts = def_env.host;