Module: Groat::SMTPD::Extensions::Authentication

Defined in:
lib/groat/smtpd/extensions/authentication.rb,
lib/groat/smtpd/extensions/mechanism-login.rb

Defined Under Namespace

Modules: ClassMethods, Login

Constant Summary collapse

BASE64_VALID =
/\A[A-Z0-9\/+]*=*\Z/i

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(mod) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/groat/smtpd/extensions/authentication.rb', line 89

def self.included mod
  puts "Included RFC 4954: Authentication"
  mod.extend ClassMethods
  mod.inheritable_attr(:auth_mechanisms)
  mod.auth_mechanisms = {}
  mod.ehlo_keyword :auth, :auth_params, :show_auth_keyword?
  mod.verb :auth, :smtp_verb_auth
  mod.mail_param :auth, :mail_param_auth
  mod.auth_mechanism :plain, :auth_mech_plain, :secure?
  super
end

Instance Method Details

#auth_mech_plain(arg) ⇒ Object

RFC 4616



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/groat/smtpd/extensions/authentication.rb', line 107

def auth_mech_plain(arg)
  response_bad_command_parameter(:message => "Encrypted session required", 
                                 :terminate => false) unless secure?
  pipelinable unless arg.nil?
  check_command_group
  if arg.nil?
    toclient "334 \r\n"
    arg = fromclient
    arg.chomp!
  end
  if arg.eql? '*'
    response_syntax_error(:message => "Authentication Quit")
  end
  if arg !~ BASE64_VALID
    response_syntax_error(:message => "Bad response")
  end
  decoded = Base64.decode64(arg) 
  cid, zid, pass = decoded.split("\000")
  res = validate_auth_plain(cid, zid, pass)
  if res
    @authenticated = true
    response_auth_ok
  end
end

#auth_mechanism_method(name) ⇒ Object



132
133
134
135
136
137
# File 'lib/groat/smtpd/extensions/authentication.rb', line 132

def auth_mechanism_method(name)
  mech = self.class.auth_mechanisms[name]
  unless mech.nil?
    self.class.auth_mechanisms[name][:method]
  end
end

#auth_paramsObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/groat/smtpd/extensions/authentication.rb', line 49

def auth_params
  list = []
  self.class.auth_mechanisms.each do |k, v|
    valid = false

    if v[:condition].nil?
      valid = true
    else
      valid = send v[:condition]
    end

    list << k if valid
  end
  list
end

#authenticated?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/groat/smtpd/extensions/authentication.rb', line 45

def authenticated?
  @authenticated
end

#mail_param_auth(param) ⇒ Object



157
158
159
160
# File 'lib/groat/smtpd/extensions/authentication.rb', line 157

def mail_param_auth(param)
  @mail_auth = from_xtext param
  puts "MAIL AUTH=#{@mail_auth}"
end

#reset_buffersObject



40
41
42
43
# File 'lib/groat/smtpd/extensions/authentication.rb', line 40

def reset_buffers
  @mail_auth = nil
  super
end

#reset_connectionObject



35
36
37
38
# File 'lib/groat/smtpd/extensions/authentication.rb', line 35

def reset_connection
  @authenticated = false
  super
end

#response_auth_failure(args = {}) ⇒ Object



84
85
86
87
# File 'lib/groat/smtpd/extensions/authentication.rb', line 84

def response_auth_failure(args = {})
  defaults = {:code => 535, :message => "Credentials Invalid"}
  reply defaults.merge(args)
end

#response_auth_ok(args = {}) ⇒ Object



69
70
71
72
# File 'lib/groat/smtpd/extensions/authentication.rb', line 69

def response_auth_ok(args = {})
  defaults = {:code => 235, :message => "Authentication Succeeded"}
  reply defaults.merge(args)
end

#response_auth_required(args = {}) ⇒ Object



79
80
81
82
# File 'lib/groat/smtpd/extensions/authentication.rb', line 79

def response_auth_required(args = {})
  defaults = {:code => 530, :message => "Authentication required"}
  reply defaults.merge(args)
end

#response_auth_temp_fail(args = {}) ⇒ Object



74
75
76
77
# File 'lib/groat/smtpd/extensions/authentication.rb', line 74

def response_auth_temp_fail(args = {})
  defaults = {:code => 454, :message => "Temporary Failure"}
  reply defaults.merge(args)
end

#show_auth_keyword?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/groat/smtpd/extensions/authentication.rb', line 65

def show_auth_keyword?
  not authenticated?
end

#smtp_verb_auth(args) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/groat/smtpd/extensions/authentication.rb', line 141

def smtp_verb_auth(args)
  response_bad_syntax unless esmtp?
  response_bad_sequence(:message => 'Already authenticated', 
                        :terminate=> false) if authenticated?
  response_bad_sequence if in_mail_transaction? 
  mechanism, *initial_response = args.split(" ")
  response_bad_command_parameter if mechanism.nil?
  response_bad_command_parameter if initial_response.count > 1
  if initial_response.count == 1 and initial_response[0] !~ BASE64_VALID
    response_bad_command_parameter
  end
  mechanism = mechanism.to_s.upcase.intern
  response_bad_command_parameter if auth_mechanism_method(mechanism).nil?
  send auth_mechanism_method(mechanism), initial_response[0]
end

#validate_auth_plain(cid, zid, pass) ⇒ Object



102
103
104
# File 'lib/groat/smtpd/extensions/authentication.rb', line 102

def validate_auth_plain(cid, zid, pass)
  response_auth_temp_fail
end