diff --git a/Makefile b/Makefile index 0549fd6d7..44e4356df 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ default: config dirs template css docs all: default predepend: - sudo sh -c "apt-get install augeas-tools libpython2.7 pandoc psmisc python2.7 python-augeas python-passlib python-bcrypt python-bjsonrpc python-cheetah python-cherrypy3 python-simplejson sudo" + sudo sh -c "apt-get install augeas-tools libpython2.7 pandoc psmisc python2.7 python-augeas python-bcrypt python-bjsonrpc python-cheetah python-cherrypy3 python-django python-passlib python-simplejson sudo" git submodule init git submodule update touch predepend @@ -32,6 +32,7 @@ install: default apache-install freedombox-setup-install cp -a sudoers.d $(DESTDIR)/etc/sudoers.d cp -a *.py modules templates $(DESTDIR)$(PYDIR)/ cp share/init.d/plinth $(DESTDIR)/etc/init.d + cp -a lib/* $(DESTDIR)/usr/lib install plinth $(DESTDIR)/usr/bin/ mkdir -p $(DESTDIR)/var/lib/plinth/cherrypy_sessions $(DESTDIR)/var/log/plinth $(DESTDIR)/var/run mkdir -p $(DESTDIR)/var/lib/plinth/data diff --git a/actions/firewall b/actions/firewall new file mode 100755 index 000000000..88a921d2b --- /dev/null +++ b/actions/firewall @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- mode: python -*- +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +""" +Configuration helper for Plinth firewall inteface +""" + +import argparse +import os +import re +import subprocess + + +def parse_arguments(): + """Return parsed command line arguments as dictionary""" + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') + + # Get installed status + subparsers.add_parser('get-installed', + help='Get whether firewalld is installed') + + # Get status + subparsers.add_parser('get-status', help='Get whether firewalld is running') + + # Get service status + subparsers.add_parser('get-enabled-services', help='Get list of enabled services') + + # Add a service + add_service = subparsers.add_parser('add-service', help='Add a service') + add_service.add_argument('service', help='Name of the service to add') + + # Remove a service status + remove_service = subparsers.add_parser('remove-service', help='Remove a service') + remove_service.add_argument('service', help='Name of the service to remove') + + return parser.parse_args() + + +def subcommand_get_installed(_): + """Print whether firewalld is installed""" + with open('/dev/null', 'w') as file_handle: + status = subprocess.call(['which', 'firewalld'], stdout=file_handle) + + print 'installed' if not status else 'not installed' + + +def subcommand_get_status(_): + """Print status of the firewalld service""" + subprocess.call(['firewall-cmd', '--state']) + + +def subcommand_get_enabled_services(_): + """Print the status of variours services""" + subprocess.call(['firewall-cmd', '--list-services']) + + +def subcommand_add_service(arguments): + """Permit a service in the firewall""" + subprocess.call(['firewall-cmd', '--add-service', arguments.service]) + subprocess.call(['firewall-cmd', '--permanent', '--add-service', arguments.service]) + + +def subcommand_remove_service(arguments): + """Block a service in the firewall""" + subprocess.call(['firewall-cmd', '--remove-service', arguments.service]) + subprocess.call(['firewall-cmd', '--permanent', '--remove-service', arguments.service]) + + +def main(): + """Parse arguments and perform all duties""" + arguments = parse_arguments() + + subcommand = arguments.subcommand.replace('-', '_') + subcommand_method = globals()['subcommand_' + subcommand] + subcommand_method(arguments) + + +if __name__ == "__main__": + main() diff --git a/lib/firewalld/services/xmpp-bosh.xml b/lib/firewalld/services/xmpp-bosh.xml new file mode 100644 index 000000000..039f9cc3b --- /dev/null +++ b/lib/firewalld/services/xmpp-bosh.xml @@ -0,0 +1,6 @@ + + + XMPP (Jabber) web client + Extensible Messaging and Presence Protocol (XMPP) web client protocol allows web based chat clients such as JWChat to connect to the XMPP (Jabber) server. This is also know as the Bidirectional-streams Over Synchronous HTTP (BOSH) protocol. Enable this if you run an XMPP (Jabber) server and you wish web clients to connect to your server. + + diff --git a/lib/firewalld/services/xmpp-client.xml b/lib/firewalld/services/xmpp-client.xml new file mode 100644 index 000000000..d31bd537c --- /dev/null +++ b/lib/firewalld/services/xmpp-client.xml @@ -0,0 +1,6 @@ + + + XMPP (Jabber) client + Extensible Messaging and Presence Protocol (XMPP) client connection protocol allows XMPP (Jabber) clients such as Empathy, Pidgin, Kopete and Jitsi to connect to an XMPP (Jabber) server. Enable this if you run an XMPP (Jabber) server and you wish clients to be able to connect to the server and communicate with each other. + + diff --git a/lib/firewalld/services/xmpp-server.xml b/lib/firewalld/services/xmpp-server.xml new file mode 100644 index 000000000..3656d96da --- /dev/null +++ b/lib/firewalld/services/xmpp-server.xml @@ -0,0 +1,6 @@ + + + XMPP (Jabber) server + Extensible Messaging and Presence Protocol (XMPP) server connection protocols allows multiple XMPP (Jabber) servers to work in a fedrated fashion. Users on one server will be able to see the presence of and communicate with users on another servers. Enable this if you run an XMPP (Jabber) server and you wish users on your server to communicate with users on other XMPP servers. + + diff --git a/lib/freedombox/first-run.d/90_firewall b/lib/freedombox/first-run.d/90_firewall new file mode 100755 index 000000000..dadd7fe74 --- /dev/null +++ b/lib/freedombox/first-run.d/90_firewall @@ -0,0 +1,48 @@ +#!/bin/sh + +# Setup firewall rules for all the enabled services + +# Ideally all non essential services are enabled from Plinth +# which automatically takes care of enabling appropirate firewall +# ports. This file is used then for essential services and services +# that are not yet configurable from Plinth. + +# HTTP (JWChat, ownCloud) +firewall-cmd --permanent --add-service=http + +# HTTPS (Plinth, JWChat, ownCloud) +firewall-cmd --permanent --add-service=https + +# Tor +firewall-cmd --permanent --add-port=9050/tcp + +# NTP +firewall-cmd --permanent --add-service=ntp + +# DNS +firewall-cmd --permanent --add-service=dns + +# mDNS +firewall-cmd --permanent --add-service=mdns + +# DHCP +firewall-cmd --permanent --add-service=dhcp + +# Bootp Server and Client (not enabled) +#firewall-cmd --permanent --add-port=67/tcp +#firewall-cmd --permanent --add-port=67/udp +#firewall-cmd --permanent --add-port=68/tcp +#firewall-cmd --permanent --add-port=68/udp + +# LDAP (not enabled) +#firewall-cmd --permanent --add-service=ldap +#firewall-cmd --permanent --add-service=ldaps + +# OpenVPN (not enabled) +#firewall-cmd --permanent --add-service=openvpn + +# Privoxy +firewall-cmd --permanent --add-port=8118/tcp + +# Obfsproxy +firewall-cmd --permanent --add-port=40202/tcp diff --git a/modules/firewall.py b/modules/firewall.py new file mode 120000 index 000000000..1d198303f --- /dev/null +++ b/modules/firewall.py @@ -0,0 +1 @@ +installed/system/firewall.py \ No newline at end of file diff --git a/modules/installed/apps/owncloud.py b/modules/installed/apps/owncloud.py index 26da6ac1b..1f335ea36 100644 --- a/modules/installed/apps/owncloud.py +++ b/modules/installed/apps/owncloud.py @@ -5,6 +5,7 @@ from plugin_mount import PagePlugin, FormPlugin from forms import Form import actions import cfg +import service from util import Message class Owncloud(PagePlugin, FormPlugin): @@ -15,13 +16,22 @@ class Owncloud(PagePlugin, FormPlugin): self.register_page("apps.owncloud") cfg.html_root.apps.menu.add_item("Owncloud", "icon-picture", "/apps/owncloud", 35) + self.service = service.Service('owncloud', _('ownCloud'), + ['http', 'https'], + enabled=self.is_enabled) + + def is_enabled(self): + """Return whether ownCloud is enabled""" + output, error = actions.run('owncloud-setup', 'status') + if error: + raise Exception('Error getting ownCloud status: %s' % error) + + return 'enable' in output.split() + @cherrypy.expose @require() def index(self, **kwargs): - output, error = actions.run("owncloud-setup", 'status') - if error: - raise Exception("something is wrong: " + error) - owncloud_enable = "enable" in output.split() + owncloud_enable = self.is_enabled() if 'submitted' in kwargs: owncloud_enable = self.process_form(kwargs) @@ -65,4 +75,8 @@ class Owncloud(PagePlugin, FormPlugin): opts.append('no'+key) actions.superuser_run("owncloud-setup", opts, async=True) + # Send a signal to other modules that the service is + # enabled/disabled + self.service.notify_enabled(self, checkedinfo['enable']) + return checkedinfo['enable'] diff --git a/modules/installed/router/pagekite.py b/modules/installed/router/pagekite.py index be767560b..666d1a0fe 100644 --- a/modules/installed/router/pagekite.py +++ b/modules/installed/router/pagekite.py @@ -41,7 +41,7 @@ class PageKite(PagePlugin): self.register_page("router.setup.pagekite") self.register_page("router.setup.pagekite.configure") cfg.html_root.router.setup.menu.add_item( - "Public Visibility (PageKite)", "icon-flag", + _("Public Visibility (PageKite)"), "icon-flag", "/router/setup/pagekite", 50) @cherrypy.expose @@ -51,15 +51,15 @@ class PageKite(PagePlugin): del kwargs # Unused main = _(""" -

PageKite is a system for exposing FreedomBox services when you +

PageKite is a system for exposing {box_name} services when you don't have a direct connection to the Internet. You only need this -service if your FreedomBox services are unreachable from the rest of +service if your {box_name} services are unreachable from the rest of the Internet. This includes the following situations: