Mercurial > prosody-hg
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; |
