2 # -*- coding: utf-8 -*-
6 # Copyright © 2013-2019 RebornOS
8 # This file is part of Cnchi.
10 # Cnchi is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # Cnchi is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # The following additional terms are in effect as per Section 7 of the license:
22 # The preservation of all legal notices and author attributions in
23 # the material or in the Appropriate Legal Notices displayed
24 # by works containing it is required.
26 # You should have received a copy of the GNU General Public License
27 # along with Cnchi; If not, see <http://www.gnu.org/licenses/>.
30 """ Configures Antergos to encrypt user's home with encFS """
37 import misc.extra as misc
39 # TODO: This is unfinished and untested
42 @misc.raise_privileges
43 def backup_conf_files(dest_dir):
44 """ Copy encfs setup files """
46 "etc/security/pam_encfs.conf",
47 "etc/security/pam_env.conf",
49 "etc/pam.d/system-login",
50 "etc/pam.d/system-auth"]
51 for conf_file in conf_files:
52 path = os.path.join(dest_dir, conf_file)
53 if os.path.exists(path):
54 shutil.copy(path, path + ".cnchi")
58 @misc.raise_privileges
59 def setup_conf_files(dest_dir):
61 path = os.path.join(dest_dir, "etc/security/pam_encfs.conf")
62 with open(path, 'w') as pam_encfs:
63 pam_encfs.write("# File created by Cnchi (RebornOS Installer)\n\n")
65 "# If this is specified program will attempt to drop permissions "
66 "before running encfs.\n")
67 pam_encfs.write("drop_permissions\n\n")
69 "# This specifies which options to pass to encfs for every user.\n")
71 "# You can find encfs options by running encfs without any arguments\n")
72 pam_encfs.write("encfs_default --idle=1\n\n")
73 pam_encfs.write("# Same for fuse\n")
74 pam_encfs.write("# you can find fuse options with encfs -H\n")
75 pam_encfs.write("fuse_default allow_root,nonempty\n\n")
76 pam_encfs.write("# Added by Cnchi - RebornOS Installer\n")
77 # USERNAME SOURCE TARGET_PATH ENCFS_Options FUSE_Options
78 pam_encfs.write("-\t/home/.encfs\t-\t-v\t-\n")
80 path = os.path.join(dest_dir, "etc/security/pam_env.conf")
81 with open(path, 'a') as pam_env:
82 pam_env.write("\n# Added by Cnchi - RebornOS Installer\n")
84 "# Set the ICEAUTHORITY file location to allow GNOME to start on encfs $HOME\n")
85 pam_env.write("ICEAUTHORITY DEFAULT=/tmp/.ICEauthority_@{PAM_USER}\n")
87 path = os.path.join(dest_dir, "etc/fuse.conf")
88 with open(path, 'a') as fuse_conf:
89 fuse_conf.write("\n# Added by Cnchi - RebornOS Installer\n")
90 fuse_conf.write("user_allow_other\n")
92 path = os.path.join(dest_dir, "etc/pam.d/system-login")
93 with open(path, 'a') as system_login:
94 system_login.write("\n# Added by Cnchi - RebornOS Installer\n")
95 system_login.write("session required\tpam_encfs.so\n")
96 system_login.write("session optional\tpam_mount.so\n")
98 path = os.path.join(dest_dir, "etc/pam.d/system-auth")
99 with open(path, "a") as system_auth:
100 system_auth.write("\n# Added by Cnchi - RebornOS Installer\n")
101 system_auth.write("auth sufficient\tpam_encfs.so\n")
102 system_auth.write("auth optional\tpam_mount.so\n")
105 @misc.raise_privileges
106 def setup(username, dest_dir, password):
107 """ Encrypt user's home folder """
108 # encfs and pam_mount packages are needed
109 # and pam_encfs from AUR, too.
110 # Reference: https://wiki.debian.org/TransparentEncryptionForHomeFolder
113 backup_conf_files(dest_dir)
114 setup_conf_files(dest_dir)
115 except Exception as ex:
116 logging.error("Can't create and modify encfs configuration files.")
117 template = "An exception of type {0} occured. Arguments:\n{1!r}"
118 message = template.format(type(ex).__name__, ex.args)
119 logging.error(message)
120 logging.error("Home directory won't be encrypted.")
123 # Move user home dir out of the way
124 mount_dir = os.path.join(dest_dir, "home/", username)
125 backup_dir = os.path.join(dest_dir, "var/tmp/", username)
126 shutil.move(mount_dir, backup_dir)
128 # Create necessary dirs, encrypted and mounted(unencrypted)
129 encrypted_dir = os.path.join(dest_dir, "home/.encfs/", username)
130 os.makedirs(encrypted_dir, mode=0o755)
131 os.makedirs(mount_dir, mode=0o755)
134 shutil.chown(encrypted_dir, username, "users")
135 shutil.chown(mount_dir, username, "users")
137 # Create encrypted directory
139 cmd = ["/bin/echo", "-e", "p\n{0}\n".format(password)]
140 passw = subprocess.Popen(cmd, stdout=subprocess.PIPE)
141 cmd = ['encfs', '-S', encrypted_dir, mount_dir, "--public"]
142 encfs = subprocess.Popen(
143 cmd, stdin=passw.stdout, stdout=subprocess.PIPE)
145 if encfs.poll() != 0:
146 logging.error("Can't run encfs. Bad password?")
147 except subprocess.CalledProcessError as err:
148 logging.error("Error running %s: %s", err.cmd, err.output)
150 # Restore user home files
151 for name in os.listdir(backup_dir):
152 shutil.move(os.path.join(backup_dir, name),
153 os.path.join(mount_dir, name))
159 if __name__ == '__main__':
160 setup("test", "/", "1234")