propellor 3.2.2 → 3.2.3
raw patch · 9 files changed
+184/−280 lines, 9 files
Files
- CHANGELOG +12/−0
- debian/changelog +12/−0
- joeyconfig.hs +0/−46
- propellor.cabal +1/−2
- src/Propellor/Gpg.hs +32/−11
- src/Propellor/Property/Debootstrap.hs +14/−8
- src/Propellor/Property/SiteSpecific/IABak.hs +0/−121
- src/Propellor/Property/SiteSpecific/JoeySites.hs +69/−85
- src/wrapper.hs +44/−7
CHANGELOG view
@@ -1,3 +1,15 @@+propellor (3.2.3) unstable; urgency=medium++ * Improve extraction of gpg secret key id list, to work with gpg 2.1.+ * The propellor wrapper checks if ./config.hs exists; if so it runs+ using the configuration in the current directory, rather than+ ~/.propellor/config.hs+ * Debootstap: Fix too tight permissions lock down of debootstrapped+ chroots, which prevented non-root users from doing anything in the+ chroot.++ -- Joey Hess <id@joeyh.name> Tue, 22 Nov 2016 11:36:18 -0400+ propellor (3.2.2) unstable; urgency=medium * Added Linode.serialGrub property.
debian/changelog view
@@ -1,3 +1,15 @@+propellor (3.2.3) unstable; urgency=medium++ * Improve extraction of gpg secret key id list, to work with gpg 2.1.+ * The propellor wrapper checks if ./config.hs exists; if so it runs+ using the configuration in the current directory, rather than+ ~/.propellor/config.hs+ * Debootstap: Fix too tight permissions lock down of debootstrapped+ chroots, which prevented non-root users from doing anything in the+ chroot.++ -- Joey Hess <id@joeyh.name> Tue, 22 Nov 2016 11:36:18 -0400+ propellor (3.2.2) unstable; urgency=medium * Added Linode.serialGrub property.
joeyconfig.hs view
@@ -12,7 +12,6 @@ import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User-import qualified Propellor.Property.Group as Group import qualified Propellor.Property.Hostname as Hostname import qualified Propellor.Property.Tor as Tor import qualified Propellor.Property.Dns as Dns@@ -35,7 +34,6 @@ import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean import qualified Propellor.Property.SiteSpecific.GitHome as GitHome import qualified Propellor.Property.SiteSpecific.GitAnnexBuilder as GitAnnexBuilder-import qualified Propellor.Property.SiteSpecific.IABak as IABak import qualified Propellor.Property.SiteSpecific.Branchable as Branchable import qualified Propellor.Property.SiteSpecific.JoeySites as JoeySites import Propellor.Property.DiskImage@@ -58,7 +56,6 @@ , beaver , pell , keysafe- , iabak ] ++ monsters testvm :: Host@@ -87,7 +84,6 @@ & Apt.buildDep ["git-annex"] `period` Daily - & JoeySites.postfixClientRelay (Context "darkstar.kitenet.net") & JoeySites.dkimMilter & JoeySites.alarmClock "*-*-* 7:30" (User "joey") "/usr/bin/timeout 45m /home/joey/bin/goodmorning"@@ -113,9 +109,6 @@ gnu = host "gnu.kitenet.net" $ props & Apt.buildDep ["git-annex"] `period` Daily - & JoeySites.postfixClientRelay (Context "gnu.kitenet.net")- & JoeySites.dkimMilter- clam :: Host clam = host "clam.kitenet.net" $ props & standardSystem Unstable X86_64@@ -512,45 +505,6 @@ [ "keysafe --store-directory", datadir, "--backup-server", backupdir , "&& rsync -a --delete --max-delete 3 ", backupdir , rsyncnetbackup ]--iabak :: Host-iabak = host "iabak.archiveteam.org" $ props- & ipv4 "124.6.40.227"- & Hostname.sane- & osDebian Testing X86_64- & Systemd.persistentJournal- & Cron.runPropellor (Cron.Times "30 * * * *")- & Apt.stdSourcesList `onChange` Apt.upgrade- & Apt.installed ["git", "ssh"]- & Ssh.hostKeys (Context "iabak.archiveteam.org")- [ (SshDsa, "ssh-dss AAAAB3NzaC1kc3MAAACBAMhuYTshLxavWCpfyJxg3j/GWyIRlL3VTharsfUTzMOqyMSWantZjflfJX21z2KzFDtPEA711GYztsgMVXMrsPQInaOKNISe/R9cfgnEktKTxeppWTfw0GTNcpCeeecddU0FCPVW3a6yDoT6+Rv0jPvkQoDGmhQ40MhauMrO0mJ9AAAAFQDpCbXG8o/3Sg7wrsp5abizJoQ0yQAAAIEAxxyHo/ZhDPP+EWtDS05s5dwiDMUsxIllk1NeleAOQIyLtFkaifOeskDJybIPWYPGX1trjcPoGuXJ5GBYrRaPiu6FBvYdYMFRLr4uNBsaSHHqlHhBPkP3RzCrdUyau4XyjdE4iA0EQlO+u11A+o3f7aTuJSveM0YRfbqvaatG89EAAACAWd0h0SkRLnGjBzkou0SQfYujFY9ilhWXPWV/oOs+bieDSpvfmnaEfLSinVFRrJPvQp/dtpxPLEm+StrK3w6dmwTZVUM5JEoB1mRjBkVs6gPC9PVVg9qLpzC2/x+r5cTfrffjyRrlPdkwLKpO6oiPxTIxAyCW8ixjafkxe2hAeJo=")- , (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDP13oPRLRY0V9ZDWojb8TgHbUdE30Nq3b541TwPmlLMbYPAhldxGHkuXGlX8g9/FYP/1AgkPcxs2Uc61ZV+1Ss7q7t52f4R0bO4WHqxfdXHd9FlLzMLWxMU3aMr693pGlhnUp3/xH6O6/+bNEIo3VGGgv9XDr2cAxypS9J7X9ibHZcZ3BGvoCR+nnFJ00ERG2tREKZBPDWKk76lhCiM21fG/CSmcApXaA45FHDaM9/2Clj1sXvoS72f0hEKpl1m08sUx+F0GPzQESnKqNFl+xXdYPPbfhdrgCnDmx9tL5NnXsJU2beFiuxpICOeB1HV6DJsdlO18WqwXYhOg/2A1H3")- , (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHb0kXcrF5ThwS8wB0Hez404Zp9bz78ZxEGSqnwuF4d/N3+bymg7/HAj7l/SzRoEXKHsJ7P5320oMxBHeM16Y+k=")- ]- & Apt.installed ["etckeeper", "sudo"]- -- vital but generic tools- & Apt.installed ["vim", "screen", "tmux", "less", "emacs-nox", "netcat", "nano"]- -- tools for creating shards- & Apt.installed ["jq", "python3", "python3-aiohttp"]- & User.hasSomePassword (User "root")- & propertyList "admin accounts"- (toProps $ map User.accountFor admins- ++ map (Group.hasUser (Group "staff")) admins- ++ map Sudo.enabledFor admins)- & User.hasSomePassword (User "joey")- & GitHome.installedFor (User "joey")- & Ssh.authorizedKey (User "db48x") "ssh-rsa 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 db48x@anglachel"- & Ssh.authorizedKey (User "db48x") "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQkqIgZ7D8WHW5Y3o+fpZC/4xtv/3IQrORJrTPCt7KY db48x@erebor"- & Ssh.authorizedKey (User "hcross") "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5OhU2Lita9RdjPkX9N0w9wZnmVlednUDEx24bVn4Mk IABAK key - Harry C"- & Ssh.authorizedKey (User "kaz") "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHhFYMd9Htlf9wPZzIDyqbYYNwuo3m+kWQ9/pfAD/TE9 Kaz IABAK"- & Ssh.authorizedKey (User "yipdw") "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEo2mGPw2TTJMHp7G86hMBh6n9/+abzg1oXIIlkwWwzo trythil@aglarond"- & Ssh.noPasswords- & IABak.gitServer monsters- & IABak.registrationServer monsters- & IABak.graphiteServer- & IABak.publicFace- where- admins = map User ["joey", "db48x", "hcross", "kaz", "yipdw"] --' __|II| ,. ---- __|II|II|__ ( \_,/\
propellor.cabal view
@@ -1,5 +1,5 @@ Name: propellor-Version: 3.2.2+Version: 3.2.3 Cabal-Version: >= 1.8 License: BSD2 Maintainer: Joey Hess <id@joeyh.name>@@ -158,7 +158,6 @@ Propellor.Property.SiteSpecific.JoeySites Propellor.Property.SiteSpecific.GitAnnexBuilder Propellor.Property.SiteSpecific.Branchable- Propellor.Property.SiteSpecific.IABak Propellor.PropAccum Propellor.Utilities Propellor.CmdLine
src/Propellor/Gpg.hs view
@@ -33,21 +33,42 @@ listPubKeys :: IO [KeyId] listPubKeys = do keyring <- privDataKeyring- map fst <$> listKeys ("--list-public-keys" : useKeyringOpts keyring)+ let listopts =+ [ "--list-public-keys"+ , "--with-colons"+ , "--fixed-list-mode"+ ] ++ useKeyringOpts keyring+ gpgbin <- getGpgBin+ parse . lines <$> readProcess gpgbin listopts+ where+ parse = mapMaybe (extract . split ":")+ extract ("pub":_:_:_:f:_) = Just f+ extract _ = Nothing +-- Lists all of the user's secret keys. listSecretKeys :: IO [(KeyId, String)]-listSecretKeys = listKeys ["--list-secret-keys"]--listKeys :: [String] -> IO [(KeyId, String)]-listKeys ps = do+listSecretKeys = do gpgbin <- getGpgBin- parse . lines <$> readProcess gpgbin listopts+ parse . lines <$> readProcess gpgbin+ [ "--list-secret-keys"+ , "--with-colons"+ , "--fixed-list-mode"+ ] where- listopts = ps ++ ["--with-colons"]- parse = mapMaybe (keyIdField . split ":")- keyIdField (t:_:_:_:f:_:_:_:_:n:_)- | t == "pub" || t == "sec" = Just (f, n)- keyIdField _ = Nothing+ parse = extract [] Nothing . map (split ":")+ extract c (Just keyid) (("uid":_:_:_:_:_:_:_:_:userid:_):rest) =+ extract ((keyid, userid):c) Nothing rest+ extract c (Just keyid) rest@(("sec":_):_) =+ extract ((keyid, ""):c) Nothing rest+ extract c (Just keyid) rest@(("pub":_):_) =+ extract ((keyid, ""):c) Nothing rest+ extract c (Just keyid) (_:rest) =+ extract c (Just keyid) rest+ extract c _ [] = c+ extract c _ (("sec":_:_:_:keyid:_):rest) =+ extract c (Just keyid) rest+ extract c k (_:rest) =+ extract c k rest useKeyringOpts :: FilePath -> [String] useKeyringOpts keyring =
src/Propellor/Property/Debootstrap.hs view
@@ -51,18 +51,15 @@ built target system config = built' (setupRevertableProperty installed) target system config built' :: Property Linux -> FilePath -> System -> DebootstrapConfig -> Property Linux-built' installprop target system@(System _ arch) config =- check (unpopulated target <||> ispartial) setupprop- `requires` installprop+built' installprop target system@(System _ arch) config = + go `before` oldpermfix where+ go = check (unpopulated target <||> ispartial) setupprop+ `requires` installprop+ setupprop :: Property Linux setupprop = property ("debootstrapped " ++ target) $ liftIO $ do createDirectoryIfMissing True target- -- Don't allow non-root users to see inside the chroot,- -- since doing so can allow them to do various attacks- -- including hard link farming suid programs for later- -- exploitation.- modifyFileMode target (removeModes [otherReadMode, otherExecuteMode, otherWriteMode]) suite <- case extractSuite system of Nothing -> errorMessage $ "don't know how to debootstrap " ++ show system Just s -> pure s@@ -86,6 +83,15 @@ return True , return False )+ + -- May want to remove this after some appropriate length of time,+ -- as it's a workaround for chroots set up with too tight+ -- permissions.+ oldpermfix :: Property Linux+ oldpermfix = property ("fixed old chroot file mode") $ do+ liftIO $ modifyFileMode target $+ addModes [otherReadMode, otherExecuteMode]+ return NoChange extractSuite :: System -> Maybe String extractSuite (System (Debian _ s) _) = Just $ Apt.showSuite s
− src/Propellor/Property/SiteSpecific/IABak.hs
@@ -1,121 +0,0 @@-module Propellor.Property.SiteSpecific.IABak where--import Propellor.Base-import qualified Propellor.Property.Apt as Apt-import qualified Propellor.Property.Git as Git-import qualified Propellor.Property.Cron as Cron-import qualified Propellor.Property.File as File-import qualified Propellor.Property.Apache as Apache-import qualified Propellor.Property.User as User-import qualified Propellor.Property.Ssh as Ssh--repo :: String-repo = "https://github.com/ArchiveTeam/IA.BAK/"--userrepo :: String-userrepo = "git@gitlab.com:archiveteam/IA.bak.users.git"--publicFace :: Property DebianLike-publicFace = propertyList "iabak public face" $ props- & Git.cloned (User "root") repo "/usr/local/IA.BAK" (Just "server")- & Apt.serviceInstalledRunning "apache2"- & Cron.niceJob "graph-gen" (Cron.Times "*/10 * * * *") (User "root") "/"- "/usr/local/IA.BAK/web/graph-gen.sh"--gitServer :: [Host] -> Property (HasInfo + DebianLike)-gitServer knownhosts = propertyList "iabak git server" $ props- & Git.cloned (User "root") repo "/usr/local/IA.BAK" (Just "server")- & Git.cloned (User "root") repo "/usr/local/IA.BAK/client" (Just "master")- & Ssh.userKeys (User "root") (Context "IA.bak.users.git") sshKeys- & Ssh.knownHost knownhosts "gitlab.com" (User "root")- & Git.cloned (User "root") userrepo "/usr/local/IA.BAK/pubkeys" (Just "master")- & Apt.serviceInstalledRunning "apache2"- & "/usr/lib/cgi-bin/pushme.cgi" `File.isSymlinkedTo` File.LinkTarget "/usr/local/IA.BAK/pushme.cgi"- & File.containsLine "/etc/sudoers" "www-data ALL=NOPASSWD:/usr/local/IA.BAK/pushed.sh"- & Cron.niceJob "shardstats" (Cron.Times "*/30 * * * *") (User "root") "/"- "/usr/local/IA.BAK/shardstats-all"- & Cron.niceJob "shardmaint" Cron.Daily (User "root") "/"- "/usr/local/IA.BAK/shardmaint-fast; /usr/local/IA.BAK/shardmaint"- & Apt.installed ["git-annex"]- & Apt.installed ["libmail-sendmail-perl"]- & Cron.niceJob "expireemailer" Cron.Daily (User "root") - "/usr/local/IA.BAK"- "./expireemailer"--registrationServer :: [Host] -> Property (HasInfo + DebianLike)-registrationServer knownhosts = propertyList "iabak registration server" $ props- & User.accountFor (User "registrar")- & Ssh.userKeys (User "registrar") (Context "IA.bak.users.git") sshKeys- & Ssh.knownHost knownhosts "gitlab.com" (User "registrar")- & Git.cloned (User "registrar") repo "/home/registrar/IA.BAK" (Just "server")- & Git.cloned (User "registrar") userrepo "/home/registrar/users" (Just "master")- & Apt.serviceInstalledRunning "apache2"- & Apt.installed ["perl", "perl-modules"]- & link `File.isSymlinkedTo` File.LinkTarget "/home/registrar/IA.BAK/registrar/register.cgi"- & cmdProperty "chown" ["-h", "registrar:registrar", link]- `changesFile` link- & File.containsLine "/etc/sudoers" "www-data ALL=(registrar) NOPASSWD:/home/registrar/IA.BAK/registrar/register.pl"- & Apt.installed ["kgb-client"]- & File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" anyContext- `requires` File.dirExists "/etc/kgb-bot/"- where- link = "/usr/lib/cgi-bin/register.cgi"--sshKeys :: [(SshKeyType, Ssh.PubKeyText)]-sshKeys = - [ (SshRsa, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoiE+CPiIQyfWnl/E9iKG3eo4QzlH30vi7xAgKolGaTu6qKy4XPtl+8MNm2Dqn9QEYRVyyOT/XH0yP5dRc6uyReT8dBy03MmLkVbj8Q+nKCz5YOMTxrY3sX6RRXU1zVGjeVd0DtC+rKRT7reoCxef42LAJTm8nCyZu/enAuso5qHqBbqulFz2YXEKfU1SEEXLawtvgGck1KmCyg+pqazeI1eHWXrojQf5isTBKfPQLWVppBkWAf5cA4wP5U1vN9dVirIdw66ds1M8vnGlkTBjxP/HLGBWGYhZHE7QXjXRsk2RIXlHN9q6GdNu8+F3HXS22mst47E4UAeRoiXSMMtF5")- ]--graphiteServer :: Property (HasInfo + DebianLike)-graphiteServer = propertyList "iabak graphite server" $ props- & Apt.serviceInstalledRunning "apache2"- & Apt.installed ["libapache2-mod-wsgi", "graphite-carbon", "graphite-web"]- & File.hasContent "/etc/carbon/storage-schemas.conf"- [ "[carbon]"- , "pattern = ^carbon\\."- , "retentions = 60:90d"- , "[iabak-connections]"- , "pattern = ^iabak\\.shardstats\\.connections"- , "retentions = 1h:1y,3h:10y"- , "[iabak-default]"- , "pattern = ^iabak\\."- , "retentions = 10m:30d,1h:1y,3h:10y"- , "[default_1min_for_1day]"- , "pattern = .*"- , "retentions = 60s:1d"- ]- & graphiteCSRF- & cmdProperty "graphite-manage" ["syncdb", "--noinput"]- `assume` MadeChange- `flagFile` "/etc/flagFiles/graphite-syncdb"- & cmdProperty "graphite-manage" ["createsuperuser", "--noinput", "--username=joey", "--email=joey@localhost"]- `assume` MadeChange- `flagFile` "/etc/flagFiles/graphite-user-joey"- & cmdProperty "graphite-manage" ["createsuperuser", "--noinput", "--username=db48x", "--email=db48x@localhost"]- `assume` MadeChange- `flagFile` "/etc/flagFiles/graphite-user-db48x"- -- TODO: deal with passwords somehow- & File.ownerGroup "/var/lib/graphite/graphite.db" (User "_graphite") (Group "_graphite")- & "/etc/apache2/ports.conf" `File.containsLine` "Listen 8080"- `onChange` Apache.restarted- & Apache.siteEnabled "iabak-graphite-web"- [ "<VirtualHost *:8080>"- , " WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user=_graphite group=_graphite"- , " WSGIProcessGroup _graphite"- , " WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group=_graphite application-group=%{GLOBAL}"- , " WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi"- , " Alias /content/ /usr/share/graphite-web/static/"- , " <Location \"/content/\">"- , " SetHandler None"- , " </Location>"- , " ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log"- , " LogLevel warn"- , " CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined"- , "</VirtualHost>"- ]- where- graphiteCSRF :: Property (HasInfo + DebianLike)- graphiteCSRF = withPrivData (Password "csrf-token") (Context "iabak.archiveteam.org") $- \gettoken -> property' "graphite-web CSRF token" $ \w ->- gettoken $ \token -> ensureProperty w $ File.containsLine- "/etc/graphite/local_settings.py" ("SECRET_KEY = '"++ privDataVal token ++"'")
src/Propellor/Property/SiteSpecific/JoeySites.hs view
@@ -513,6 +513,7 @@ & Fail2Ban.jailEnabled "postfix-sasl" & "/etc/default/saslauthd" `File.containsLine` "MECHANISMS=sasldb" & Postfix.saslPasswdSet "kitenet.net" (User "errol")+ & Postfix.saslPasswdSet "kitenet.net" (User "joey") & Apt.installed ["maildrop"] & "/etc/maildroprc" `File.hasContent`@@ -531,7 +532,6 @@ & "/etc/aliases" `File.hasPrivContentExposed` ctx `onChange` Postfix.newaliases- & hasJoeyCAChain & hasPostfixCert ctx & "/etc/postfix/mydomain" `File.containsLines`@@ -578,7 +578,7 @@ , "# Filter out client relay lines from headers." , "header_checks = pcre:$config_directory/obscure_client_relay.pcre" - , "# Password auth for relaying (used by errol)"+ , "# Password auth for relaying" , "smtpd_sasl_auth_enable = yes" , "smtpd_sasl_security_options = noanonymous" , "smtpd_sasl_local_domain = kitenet.net"@@ -670,24 +670,6 @@ (Postfix.InetService Nothing "ssmtp") "smtpd" Postfix.defServiceOpts --- Configures postfix to relay outgoing mail to kitenet.net, with--- verification via tls cert.-postfixClientRelay :: Context -> Property (HasInfo + DebianLike)-postfixClientRelay ctx = Postfix.mainCfFile `File.containsLines`- -- Using smtps not smtp because more networks firewall smtp- [ "relayhost = kitenet.net:smtps"- , "smtp_tls_CAfile = /etc/ssl/certs/joeyca.pem"- , "smtp_tls_cert_file = /etc/ssl/certs/postfix.pem"- , "smtp_tls_key_file = /etc/ssl/private/postfix.pem"- , "smtp_tls_loglevel = 0"- , "smtp_use_tls = yes"- ]- `describe` "postfix client relay"- `onChange` Postfix.dedupMainCf- `onChange` Postfix.reloaded- `requires` hasJoeyCAChain- `requires` hasPostfixCert ctx- -- Configures postfix to have the dkim milter, and no other milters. dkimMilter :: Property (HasInfo + DebianLike) dkimMilter = Postfix.mainCfFile `File.containsLines`@@ -743,7 +725,73 @@ & Apache.modEnabled "cgi" & Apache.modEnabled "speling" & userDirHtml- & Apache.httpsVirtualHost' "kitenet.net" "/var/www" letos+ & Apache.httpsVirtualHost' "kitenet.net" "/var/www" letos kitenetcfg+ & alias "anna.kitenet.net"+ & apacheSite "anna.kitenet.net"+ [ "DocumentRoot /home/anna/html"+ , "<Directory /home/anna/html/>"+ , " Options Indexes ExecCGI"+ , " AllowOverride None"+ , Apache.allowAll+ , "</Directory>"+ ]+ & alias "sows-ear.kitenet.net"+ & alias "www.sows-ear.kitenet.net"+ & apacheSite "sows-ear.kitenet.net"+ [ "ServerAlias www.sows-ear.kitenet.net"+ , "DocumentRoot /srv/web/sows-ear.kitenet.net"+ , "<Directory /srv/web/sows-ear.kitenet.net>"+ , " Options FollowSymLinks"+ , " AllowOverride None"+ , Apache.allowAll+ , "</Directory>"+ , "RewriteEngine On"+ , "RewriteRule .* http://www.sowsearpoetry.org/ [L]"+ ]+ & alias "wortroot.kitenet.net"+ & alias "www.wortroot.kitenet.net"+ & apacheSite "wortroot.kitenet.net"+ [ "ServerAlias www.wortroot.kitenet.net"+ , "DocumentRoot /srv/web/wortroot.kitenet.net"+ , "<Directory /srv/web/wortroot.kitenet.net>"+ , " Options FollowSymLinks"+ , " AllowOverride None"+ , Apache.allowAll+ , "</Directory>"+ ]+ & alias "creeksidepress.com"+ & apacheSite "creeksidepress.com"+ [ "ServerAlias www.creeksidepress.com"+ , "DocumentRoot /srv/web/www.creeksidepress.com"+ , "<Directory /srv/web/www.creeksidepress.com>"+ , " Options FollowSymLinks"+ , " AllowOverride None"+ , Apache.allowAll+ , "</Directory>"+ ]+ & alias "joey.kitenet.net"+ & apacheSite "joey.kitenet.net"+ [ "DocumentRoot /var/www"+ , "<Directory /var/www/>"+ , " Options Indexes ExecCGI"+ , " AllowOverride None"+ , Apache.allowAll+ , "</Directory>"++ , "RewriteEngine On"++ , "# Old ikiwiki filenames for joey's wiki."+ , "rewritecond $1 !.*/index$"+ , "rewriterule (.+).html$ http://joeyh.name/$1/ [l]"++ , "rewritecond $1 !.*/index$"+ , "rewriterule (.+).rss$ http://joeyh.name/$1/index.rss [l]"++ , "# Redirect all to joeyh.name."+ , "rewriterule (.*) http://joeyh.name$1 [r]"+ ]+ where+ kitenetcfg = -- /var/www is empty [ "DocumentRoot /var/www" , "<Directory /var/www>"@@ -829,70 +877,6 @@ , "rewriterule /~kyle/family/wiki/(.*).html http://macleawiki.branchable.com/$1 [L]" , "rewriterule /~kyle/family/wiki/(.*).rss http://macleawiki.branchable.com/$1/index.rss [L]" , "rewriterule /~kyle/family/wiki(.*) http://macleawiki.branchable.com$1 [L]"- ]- & alias "anna.kitenet.net"- & apacheSite "anna.kitenet.net"- [ "DocumentRoot /home/anna/html"- , "<Directory /home/anna/html/>"- , " Options Indexes ExecCGI"- , " AllowOverride None"- , Apache.allowAll- , "</Directory>"- ]- & alias "sows-ear.kitenet.net"- & alias "www.sows-ear.kitenet.net"- & apacheSite "sows-ear.kitenet.net"- [ "ServerAlias www.sows-ear.kitenet.net"- , "DocumentRoot /srv/web/sows-ear.kitenet.net"- , "<Directory /srv/web/sows-ear.kitenet.net>"- , " Options FollowSymLinks"- , " AllowOverride None"- , Apache.allowAll- , "</Directory>"- , "RewriteEngine On"- , "RewriteRule .* http://www.sowsearpoetry.org/ [L]"- ]- & alias "wortroot.kitenet.net"- & alias "www.wortroot.kitenet.net"- & apacheSite "wortroot.kitenet.net"- [ "ServerAlias www.wortroot.kitenet.net"- , "DocumentRoot /srv/web/wortroot.kitenet.net"- , "<Directory /srv/web/wortroot.kitenet.net>"- , " Options FollowSymLinks"- , " AllowOverride None"- , Apache.allowAll- , "</Directory>"- ]- & alias "creeksidepress.com"- & apacheSite "creeksidepress.com"- [ "ServerAlias www.creeksidepress.com"- , "DocumentRoot /srv/web/www.creeksidepress.com"- , "<Directory /srv/web/www.creeksidepress.com>"- , " Options FollowSymLinks"- , " AllowOverride None"- , Apache.allowAll- , "</Directory>"- ]- & alias "joey.kitenet.net"- & apacheSite "joey.kitenet.net"- [ "DocumentRoot /var/www"- , "<Directory /var/www/>"- , " Options Indexes ExecCGI"- , " AllowOverride None"- , Apache.allowAll- , "</Directory>"-- , "RewriteEngine On"-- , "# Old ikiwiki filenames for joey's wiki."- , "rewritecond $1 !.*/index$"- , "rewriterule (.+).html$ http://joeyh.name/$1/ [l]"-- , "rewritecond $1 !.*/index$"- , "rewriterule (.+).rss$ http://joeyh.name/$1/index.rss [l]"-- , "# Redirect all to joeyh.name."- , "rewriterule (.*) http://joeyh.name$1 [r]" ] userDirHtml :: Property DebianLike
src/wrapper.hs view
@@ -6,6 +6,9 @@ -- This is not the propellor main program (that's config.hs). -- This bootstraps ~/.propellor/config.hs, builds it if -- it's not already built, and runs it.+--+-- If ./config.hs exists and looks like a propellor config file, +-- it instead builds and runs in the current working directory. module Main where @@ -14,31 +17,65 @@ import Propellor.Bootstrap import Utility.Monad import Utility.Directory+import Utility.FileMode import Utility.Process import Utility.Process.NonConcurrent import System.Environment (getArgs) import System.Exit-import System.Posix.Directory+import System.Posix+import Data.List import Control.Monad.IfElse+import Control.Applicative+import Prelude main :: IO () main = withConcurrentOutput $ go =<< getArgs where go ["--init"] = interactiveInit- go args = ifM (doesDirectoryExist =<< dotPropellor)- ( do- checkRepoUpToDate- buildRunConfig args- , error "Seems that ~/.propellor/ does not exist. To set it up, run: propellor --init"+ go args = ifM configInCurrentWorkingDirectory+ ( buildRunConfig args+ , ifM (doesDirectoryExist =<< dotPropellor)+ ( do+ checkRepoUpToDate+ changeWorkingDirectory =<< dotPropellor+ buildRunConfig args+ , error "Seems that ~/.propellor/ does not exist. To set it up, run: propellor --init"+ ) ) buildRunConfig :: [String] -> IO () buildRunConfig args = do- changeWorkingDirectory =<< dotPropellor unlessM (doesFileExist "propellor") $ do buildPropellor Nothing putStrLn "" putStrLn "" (_, _, _, pid) <- createProcessNonConcurrent (proc "./propellor" args) exitWith =<< waitForProcessNonConcurrent pid++configInCurrentWorkingDirectory :: IO Bool+configInCurrentWorkingDirectory = ifM (doesFileExist "config.hs")+ ( do+ -- This is a security check to avoid using the current+ -- working directory as the propellor configuration+ -- if it's not owned by the user, or is world-writable,+ -- or group writable. (Some umasks may make directories+ -- group writable, but typical ones do not.)+ s <- getFileStatus "."+ uid <- getRealUserID+ if fileOwner s /= uid+ then unsafe "you don't own the current directory"+ else if checkMode groupWriteMode (fileMode s)+ then unsafe "the current directory is group writable"+ else if checkMode otherWriteMode (fileMode s)+ then unsafe "the current directory is world-writable"+ else ifM mentionspropellor+ ( return True+ , notusing "it does not seem to be a propellor config file"+ )+ , return False+ )+ where+ unsafe s = notusing (s ++ ". This seems unsafe.")+ notusing s = error $ "Not using ./config.hs because " ++ s+ mentionspropellor = ("Propellor" `isInfixOf`) <$> readFile "config.hs"