Software /
code /
prosody
Comparison
plugins/mod_console.lua @ 3669:4b56cd1302d4
mod_console: Add s2s:showcert() command to show the certificate for a domain
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 28 Nov 2010 21:03:33 +0000 |
parent | 3652:8ae10787272a |
child | 3671:b7d5fe8eb829 |
comparison
equal
deleted
inserted
replaced
3668:29a340777d7b | 3669:4b56cd1302d4 |
---|---|
559 end | 559 end |
560 | 560 |
561 return true, "Total: "..count_out.." outgoing, "..count_in.." incoming connections"; | 561 return true, "Total: "..count_out.." outgoing, "..count_in.." incoming connections"; |
562 end | 562 end |
563 | 563 |
564 local function print_subject(print, subject) | |
565 for _, entry in ipairs(subject) do | |
566 print( | |
567 (" %s: %q"):format( | |
568 entry.name or entry.oid, | |
569 entry.value:gsub("[\r\n%z%c]", " ") | |
570 ) | |
571 ); | |
572 end | |
573 end | |
574 | |
575 function def_env.s2s:showcert(domain) | |
576 local ser = require "util.serialization".serialize; | |
577 local print = self.session.print; | |
578 local domain_sessions = set.new(array.collect(keys(incoming_s2s))) | |
579 /function(session) return session.from_host == domain; end; | |
580 for local_host in values(prosody.hosts) do | |
581 local s2sout = local_host.s2sout; | |
582 if s2sout and s2sout[domain] then | |
583 domain_sessions:add(s2sout[domain]); | |
584 end | |
585 end | |
586 local cert_set = {}; | |
587 for session in domain_sessions do | |
588 local conn = session.conn; | |
589 conn = conn and conn:socket(); | |
590 if not conn.getpeercertificate then | |
591 if conn.dohandshake then | |
592 error("This version of LuaSec does not support certificate viewing"); | |
593 end | |
594 else | |
595 local cert = conn:getpeercertificate(); | |
596 if cert then | |
597 local digest = cert:digest("sha1"); | |
598 if not cert_set[digest] then | |
599 local chain_valid, chain_err = conn:getpeerchainvalid(); | |
600 cert_set[digest] = { | |
601 { | |
602 from = session.from_host, | |
603 to = session.to_host, | |
604 direction = session.direction | |
605 }; | |
606 chain_valid = chain_valid; | |
607 chain_err = chain_err; | |
608 cert = cert; | |
609 }; | |
610 else | |
611 table.insert(cert_set[digest], { | |
612 from = session.from_host, | |
613 to = session.to_host, | |
614 direction = session.direction | |
615 }); | |
616 end | |
617 end | |
618 end | |
619 end | |
620 local domain_certs = array.collect(values(cert_set)); | |
621 -- Phew. We now have a array of unique certificates presented by domain. | |
622 local print = self.session.print; | |
623 local n_certs = #domain_certs; | |
624 | |
625 if n_certs == 0 then | |
626 return "No certificates found for "..domain; | |
627 end | |
628 | |
629 local function _capitalize_and_colon(byte) | |
630 return string.upper(byte)..":"; | |
631 end | |
632 local function pretty_fingerprint(hash) | |
633 return hash:gsub("..", _capitalize_and_colon):sub(1, -2); | |
634 end | |
635 | |
636 for cert_info in values(domain_certs) do | |
637 local cert = cert_info.cert; | |
638 print("---") | |
639 print("Fingerprint (SHA1): "..pretty_fingerprint(cert:digest("sha1"))); | |
640 print(""); | |
641 local n_streams = #cert_info; | |
642 print("Currently used on "..n_streams.." stream"..(n_streams==1 and "" or "s")..":"); | |
643 for _, stream in ipairs(cert_info) do | |
644 if stream.direction == "incoming" then | |
645 print(" "..stream.to.." <- "..stream.from); | |
646 else | |
647 print(" "..stream.from.." -> "..stream.to); | |
648 end | |
649 end | |
650 print(""); | |
651 local chain_valid, err = cert_info.chain_valid, cert_info.chain_err; | |
652 local valid_identity = cert_verify_identity(domain, "xmpp-server", cert); | |
653 print("Trusted certificate: "..(chain_valid and "Yes" or ("No ("..err..")"))); | |
654 print("Issuer: "); | |
655 print_subject(print, cert:issuer()); | |
656 print(""); | |
657 print("Valid for "..domain..": "..(valid_identity and "Yes" or "No")); | |
658 print("Subject:"); | |
659 print_subject(print, cert:subject()); | |
660 end | |
661 print("---"); | |
662 return ("Showing "..n_certs.." certificate" | |
663 ..(n_certs==1 and "" or "s") | |
664 .." presented by "..domain.."."); | |
665 end | |
666 | |
564 function def_env.s2s:close(from, to) | 667 function def_env.s2s:close(from, to) |
565 local print, count = self.session.print, 0; | 668 local print, count = self.session.print, 0; |
566 | 669 |
567 if not (from and to) then | 670 if not (from and to) then |
568 return false, "Syntax: s2s:close('from', 'to') - Closes all s2s sessions from 'from' to 'to'"; | 671 return false, "Syntax: s2s:close('from', 'to') - Closes all s2s sessions from 'from' to 'to'"; |