gtk3-listdomains.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import gi
  2. gi.require_version('Gtk', '3.0')
  3. from gi.repository import GLib, Gtk, GObject
  4. import json
  5. from nginxparser import loads
  6. import re
  7. import spur
  8. import threading
  9. import time
  10. fp = open('creds.json', 'r')
  11. creds = json.load(fp)
  12. def ssh_command(command, sudo=False):
  13. shell = spur.SshShell(
  14. hostname=creds['host'],
  15. username=creds['user'],
  16. password=creds['passphrase'],
  17. private_key_file=creds['ssh_key_path'])
  18. with shell:
  19. command_bits = command.split(" ")
  20. if sudo:
  21. command_bits.insert(0, "sudo")
  22. process = shell.spawn(command_bits)
  23. if sudo:
  24. process.stdin_write(creds['password'])
  25. result = process.wait_for_result()
  26. return result.output.decode()
  27. #
  28. # def get_check_domain_command(domain):
  29. # return "sudo openssl x509 -text -in /etc/letsencrypt/live/" + domain + "/fullchain.pem"
  30. #
  31. # def join_commands(commands):
  32. # return " && ".join(commands)
  33. class EntryWindow(Gtk.Window):
  34. def __init__(self):
  35. Gtk.Window.__init__(self, title="Entry Demo")
  36. self.set_size_request(200, 100)
  37. self.timeout_id = None
  38. vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
  39. self.add(vbox)
  40. self.progressbar = Gtk.ProgressBar(show_text=True)
  41. # self.progressbar.set_fraction(0.0)
  42. vbox.pack_start(self.progressbar, True, True, 0)
  43. hbox = Gtk.Box(spacing=6)
  44. vbox.add(hbox)
  45. self.entry_passphrase = Gtk.Entry()
  46. # https://developer.gnome.org/gtk3/stable/GtkEntry.html#gtk-entry-set-invisible-char
  47. self.entry_passphrase.set_visibility(False)
  48. # self.entry_passphrase.set_text("Enter SSH key passphrase")
  49. hbox.pack_start(self.entry_passphrase, True, True, 0)
  50. self.entry_password = Gtk.Entry()
  51. self.entry_password.set_visibility(False)
  52. # self.entry_password.set_text("Enter sudo user password")
  53. hbox.pack_start(self.entry_password, True, True, 0)
  54. self.button = Gtk.Button(label="Click Here")
  55. self.button.connect("clicked", self.on_button_clicked)
  56. hbox.pack_start(self.button, True, True, 0)
  57. #Setting up the self.grid in which the elements are to be positionned
  58. self.grid = Gtk.Grid()
  59. self.grid.set_column_homogeneous(True)
  60. self.grid.set_row_homogeneous(True)
  61. vbox.add(self.grid)
  62. #Creating the TreeStore model
  63. self.vhost_treestore = Gtk.ListStore(int, str, str)
  64. vhost_list = [
  65. # (80, "00-benoithubert.net", "benoithubert.net"),
  66. # (80, "jsx.fr", "jsx.fr")
  67. ]
  68. for vhost in vhost_list:
  69. self.vhost_treestore.append(list(vhost))
  70. self.language_filter = self.vhost_treestore.filter_new()
  71. self.language_filter.set_visible_func(self.filter_func)
  72. #creating the treeview, making it use the filter as a model, and adding the columns
  73. self.treeview = Gtk.TreeView.new_with_model(self.language_filter)
  74. for i, column_title in enumerate(["Port", "File path", "Root domain"]):
  75. renderer = Gtk.CellRendererText()
  76. column = Gtk.TreeViewColumn(column_title, renderer, text=i)
  77. self.treeview.append_column(column)
  78. self.scrollable_treelist = Gtk.ScrolledWindow()
  79. self.scrollable_treelist.set_vexpand(True)
  80. self.grid.attach(self.scrollable_treelist, 0, 0, 8, 10)
  81. self.scrollable_treelist.add(self.treeview)
  82. def filter_func(self, model, iter, data):
  83. print(model, iter, data)
  84. return True
  85. def update_progess(self, domain):
  86. self.progressbar.pulse()
  87. self.progressbar.set_text('Done: ' + domain)
  88. return False
  89. def get_https_domains(self):
  90. for d in self.domains:
  91. GLib.idle_add(self.get_https_subdomains_for_domain, d)
  92. time.sleep(0.4)
  93. def get_nginx_vhosts(self):
  94. for v in self.vhosts:
  95. GLib.idle_add(self.get_nginx_vhost, v)
  96. time.sleep(0.4)
  97. def start_thread(self, func):
  98. thread = threading.Thread(target=func)
  99. thread.daemon = True
  100. thread.start()
  101. def on_button_clicked(self, widget):
  102. decoded = ssh_command("ls /etc/nginx/sites-enabled")
  103. vhosts = decoded.split("\n")
  104. vhosts.pop()
  105. self.vhosts = vhosts
  106. self.num_vhosts = len(vhosts)
  107. self.vhosts_done = 0
  108. decoded = ssh_command("ls /etc/letsencrypt/live", True)
  109. domains = decoded.split("\n")
  110. domains.pop()
  111. self.domains = domains
  112. self.num_domains = len(domains)
  113. self.domains_done = 0
  114. self.start_thread(self.get_nginx_vhosts)
  115. # self.start_thread(self.get_https_domains)
  116. # subdomains = [self.get_https_subdomains_for_domain(d) for d in domains]
  117. # subdomains_dict = dict(zip(domains, subdomains))
  118. # print(subdomains_dict)
  119. def get_nginx_vhost(self, vhost):
  120. print(vhost)
  121. vhost_file = ssh_command("cat /etc/nginx/sites-enabled/" + vhost)
  122. parsed = loads(vhost_file)
  123. port_subdmomains = {}
  124. for server in parsed:
  125. server_inner = server[1]
  126. port = 0
  127. subdomains = []
  128. for directive in server_inner:
  129. if not port and "listen" in directive:
  130. p = re.compile('(\d+)')
  131. print('listen')
  132. ports = p.findall(directive[1])
  133. port = int(ports[0])
  134. if "server_name" in directive:
  135. print('server_name')
  136. print(directive)
  137. subd_trimmed = directive[1].strip()
  138. subdomains = subd_trimmed.split(' ')
  139. port_subdmomains[port] = subdomains
  140. for subd in subdomains:
  141. self.vhost_treestore.append([port, vhost, subd])
  142. print(port_subdmomains)
  143. self.vhosts_done += 1
  144. percent_done = self.vhosts_done * 1.0 / self.num_vhosts
  145. self.progressbar.set_fraction(percent_done)
  146. return False
  147. def get_https_subdomains_for_domain(self, domain):
  148. print(domain)
  149. p = re.compile('DNS:([0-9a-z-.]+)')
  150. cert_data = ssh_command("sudo openssl x509 -text -in /etc/letsencrypt/live/" + domain + "/fullchain.pem", True)
  151. self.domains_done += 1
  152. percent_done = self.domains_done * 1.0 / self.num_domains
  153. # print(percent_done)
  154. self.progressbar.set_fraction(percent_done)
  155. # self.progressbar.set_text('Done: ' + domain)
  156. # print(cert_data)
  157. # return p.findall (cert_data)
  158. return False
  159. def app_main():
  160. win = EntryWindow()
  161. win.connect("delete-event", Gtk.main_quit)
  162. win.show_all()
  163. if __name__ == '__main__':
  164. import signal
  165. signal.signal(signal.SIGINT, signal.SIG_DFL)
  166. # Calling GObject.threads_init() is not needed for PyGObject 3.10.2+
  167. GObject.threads_init()
  168. app_main()
  169. Gtk.main()