summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzul <azul@leap.se>2013-10-17 12:05:26 +0200
committerAzul <azul@leap.se>2013-10-17 12:05:26 +0200
commit9f4b1bcf315f09fd6d302ad187281ec4ed443f04 (patch)
treef17d3bcda2b5ead308c21b6abef108153cd9fbf1
parenta6f196d0bfe632408db7350829507478b825b1a8 (diff)
blacklist system logins for aliases and logins
We blacklist based on three things: * blacklist in APP_CONFIG[:handle_blacklist] * emails in RFC 2142 * usernames in /etc/passwd The latter two can be allowed by explicitly whitelisting them in APP_CONFIG[:handle_whitelist]. We stick to blocking names that have been configured as both blacklisted and whitelisted - better be save than sorry.
-rw-r--r--config/defaults.yml7
-rw-r--r--users/app/models/local_email.rb33
-rw-r--r--users/test/unit/local_email_test.rb31
3 files changed, 70 insertions, 1 deletions
diff --git a/config/defaults.yml b/config/defaults.yml
index 8d81668..66ec639 100644
--- a/config/defaults.yml
+++ b/config/defaults.yml
@@ -18,6 +18,11 @@ common: &common
pagination_size: 30
auth:
token_expires_after: 60
+ # handles that will be blocked from being used as logins or email aliases
+ # in addition to the ones in /etc/passwd and http://tools.ietf.org/html/rfc2142
+ handle_blacklist: [certmaster, ssladmin, arin-admin, administrator, www-data, maildrop]
+ # handles that will be allowed despite being in /etc/passwd or rfc2142
+ handle_whitelist: []
development:
<<: *dev_ca
@@ -43,4 +48,4 @@ production:
admins: []
domain: example.net
payment: []
-# logfile: /path/to/your/logs
+ # logfile: /path/to/your/logs
diff --git a/users/app/models/local_email.rb b/users/app/models/local_email.rb
index 6303bb6..2b4c65e 100644
--- a/users/app/models/local_email.rb
+++ b/users/app/models/local_email.rb
@@ -1,5 +1,10 @@
class LocalEmail < Email
+ BLACKLIST_FROM_RFC2142 = [
+ 'postmaster', 'hostmaster', 'domainadmin', 'webmaster', 'www',
+ 'abuse', 'noc', 'security', 'usenet', 'news', 'uucp',
+ 'ftp', 'sales', 'marketing', 'support', 'info'
+ ]
def self.domain
APP_CONFIG[:domain]
@@ -11,6 +16,8 @@ class LocalEmail < Email
:message => "needs to end in @#{domain}"
}
+ validate :handle_allowed
+
def initialize(s)
super
append_domain_if_needed
@@ -32,4 +39,30 @@ class LocalEmail < Email
end
end
+ def handle_allowed
+ errors.add(:handle, "is reserved.") if handle_reserved?
+ end
+
+ def handle_reserved?
+ # *ARRAY in a case statement tests if ARRAY includes the handle.
+ case handle
+ when *APP_CONFIG[:handle_blacklist]
+ true
+ when *APP_CONFIG[:handle_whitelist]
+ false
+ when *BLACKLIST_FROM_RFC2142
+ true
+ else
+ handle_in_passwd?
+ end
+ end
+
+ def handle_in_passwd?
+ begin
+ !!Etc.getpwnam(handle)
+ rescue ArgumentError
+ # handle was not found
+ return false
+ end
+ end
end
diff --git a/users/test/unit/local_email_test.rb b/users/test/unit/local_email_test.rb
index b25f46f..20ee7f1 100644
--- a/users/test/unit/local_email_test.rb
+++ b/users/test/unit/local_email_test.rb
@@ -24,6 +24,37 @@ class LocalEmailTest < ActiveSupport::TestCase
assert_equal ["needs to end in @#{LocalEmail.domain}"], local.errors[:email]
end
+ test "blacklists rfc2142" do
+ black_listed = LocalEmail.new('hostmaster')
+ assert !black_listed.valid?
+ end
+
+ test "blacklists etc passwd" do
+ black_listed = LocalEmail.new('nobody')
+ assert !black_listed.valid?
+ end
+
+ test "whitelist overwrites automatic blacklists" do
+ with_config handle_whitelist: ['nobody', 'hostmaster'] do
+ white_listed = LocalEmail.new('nobody')
+ assert white_listed.valid?
+ white_listed = LocalEmail.new('hostmaster')
+ assert white_listed.valid?
+ end
+ end
+
+ test "blacklists from config" do
+ black_listed = LocalEmail.new('www-data')
+ assert !black_listed.valid?
+ end
+
+ test "blacklist from config overwrites whitelist" do
+ with_config handle_whitelist: ['www-data'] do
+ black_listed = LocalEmail.new('www-data')
+ assert !black_listed.valid?
+ end
+ end
+
def handle
@handle ||= Faker::Internet.user_name
end