groat-smtpd 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Help
25
+ def self.included mod
26
+ puts "Included HELP verb"
27
+ mod.ehlo_keyword :help
28
+ mod.verb :help, :smtp_verb_help
29
+ end
30
+
31
+ def smtp_verb_help(args)
32
+ verbs = known_verbs.map{|x| x.to_s.upcase}
33
+ msg = ["Acceptable commands"]
34
+ while not verbs.empty?
35
+ msg << verbs.shift(4).map{|x| "%-8s" % x}.join(" ")
36
+ end
37
+ reply :code=>214, :message=>msg
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Authentication
25
+ module Login
26
+ def self.included mod
27
+ puts "Included Non-standard LOGIN Authentication Mechanism"
28
+ raise SMTPExtensionError.new("LOGIN auth mechanism requires AUTH") unless mod.ehlo_keyword_known? :auth
29
+ mod.auth_mechanism :login, :auth_mech_login, :secure?
30
+ super
31
+ end
32
+
33
+ def validate_auth_login(user, pass)
34
+ response_auth_temp_fail
35
+ end
36
+
37
+ def auth_mech_login(arg)
38
+ response_bad_command_parameter(:message => "Encrypted session required",
39
+ :terminate => false) unless secure?
40
+ check_command_group
41
+ unless arg.nil?
42
+ response_syntax_error(:message => "LOGIN does not allow initial response")
43
+ end
44
+ # Outlook requires "Username:" (vs the draft which says "User Name")
45
+ toclient "334 " + Base64.encode64("Username:").strip + "\r\n"
46
+ r = fromclient.chomp
47
+ if r.eql? '*'
48
+ response_syntax_error(:message => "Authentication Quit")
49
+ end
50
+ if r !~ BASE64_VALID
51
+ response_syntax_error(:message => "Bad response")
52
+ end
53
+ username = Base64.decode64(r)
54
+ # Outlook requires "Password:" (vs the draft which says "Password")
55
+ toclient "334 " + Base64.encode64("Password:").strip + "\r\n"
56
+ r = fromclient.chomp
57
+ if r.eql? '*'
58
+ response_syntax_error(:message => "Authentication Quit")
59
+ end
60
+ if r !~ BASE64_VALID
61
+ response_syntax_error(:message => "Bad response")
62
+ end
63
+ password = Base64.decode64(r)
64
+ res = validate_auth_login(username, password)
65
+ if res
66
+ @authenticated = true
67
+ response_auth_ok
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,41 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module No_Soliciting
25
+ def self.included mod
26
+ puts "Included RFC 3865:NO_SOLICITING"
27
+ mod.ehlo_keyword :"no-soliciting", :solicitation_keywords
28
+ mod.mail_param :solicit, :smtp_verb_solicit
29
+ end
30
+
31
+ def solicitation_keywords
32
+ end
33
+
34
+ def mail_param_solicit(param)
35
+ @mail_solicit = param
36
+ puts "MAIL SOLICIT=#{@mail_solicit}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Onex
25
+ def self.included mod
26
+ puts "Included non-RFC specified verb: ONEX"
27
+ mod.ehlo_keyword :onex
28
+ mod.verb :onex, :smtp_verb_onex
29
+ end
30
+
31
+ def smtp_verb_onex(args)
32
+ response_ok
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Pipelining
25
+ def reset_connection
26
+ @pipelinable = false
27
+ super
28
+ end
29
+
30
+ def self.included(klass)
31
+ puts "Included RFC 2920: Pipelining"
32
+ klass.after_all_verbs do |verb|
33
+ puts "After #{verb}"
34
+ @pipelinable = false
35
+ end
36
+ klass.before_verb :rset, :pipelinable
37
+ klass.before_verb :mail, :pipelinable
38
+ klass.before_verb :send, :pipelinable
39
+ klass.before_verb :soml, :pipelinable
40
+ klass.before_verb :saml, :pipelinable
41
+ klass.before_verb :rcpt, :pipelinable
42
+ super
43
+ end
44
+
45
+ def pipelinable
46
+ @pipelinable = true
47
+ end
48
+
49
+ def check_command_group
50
+ if not esmtp? or not @pipelinable
51
+ if clientdata?
52
+ response_bad_sequence
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,46 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Size
25
+ def self.included mod
26
+ puts "Included RFC 1870: Message Size Declaration"
27
+ mod.ehlo_keyword :size, :max_mail_size
28
+ mod.mail_param :size, :mail_param_size
29
+ super
30
+ end
31
+
32
+ def mail_param_size(param)
33
+ if (param !~ /\A[0-9]{1,20}\Z/)
34
+ response_bad_parameter(:message => "Numeric size required")
35
+ end
36
+ @mail_size = param
37
+ puts "MAIL SIZE=#{@mail_size}"
38
+ end
39
+
40
+ def max_mail_size
41
+ "0"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,69 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ require 'openssl'
22
+
23
+ module Groat
24
+ module SMTPD
25
+ module Extensions
26
+ module StartTLS
27
+ def self.included mod
28
+ puts "Included RFC 3207: STARTTLS"
29
+ mod.ehlo_keyword :starttls, nil, :show_starttls_keyword?
30
+ mod.verb :starttls, :smtp_verb_starttls
31
+ end
32
+
33
+ def reset_connection
34
+ @secure = false
35
+ super
36
+ end
37
+
38
+ def set_ssl_context(ctx)
39
+ @sslctx = ctx
40
+ end
41
+
42
+ def show_starttls_keyword?
43
+ not secure?
44
+ end
45
+
46
+ def secure?
47
+ @secure
48
+ end
49
+
50
+ def smtp_verb_starttls(args)
51
+ check_command_group
52
+ response_syntax_error unless args.empty?
53
+ response_bad_sequence unless esmtp?
54
+ # § 4.2 "A client MUST NOT attempt to start a TLS session if a TLS
55
+ # session is already active"
56
+ response_bad_sequence if secure?
57
+ toclient "220 Ready to start TLS\r\n"
58
+ ssl = OpenSSL::SSL::SSLSocket.new(@s, @sslctx)
59
+ ssl.accept
60
+ @s = ssl
61
+ # http://www.imc.org/ietf-smtp/mail-archive/msg05452.html
62
+ reset_connection
63
+ @secure = true
64
+ true
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,37 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ module Groat
22
+ module SMTPD
23
+ module Extensions
24
+ module Verbose
25
+ def self.included mod
26
+ puts "Included non-RFC specified verb: VERB"
27
+ mod.ehlo_keyword :verb
28
+ mod.verb :verb, :smtp_verb_verbose
29
+ end
30
+
31
+ def smtp_verb_verbose(args)
32
+ response_ok
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ # vim: set sw=2 sts=2 ts=2 et syntax=ruby: #
2
+ =begin license
3
+ Copyright 2011 Novell, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Author(s):
18
+ Peter Bowen <pzbowen@gmail.com> Ottawa, Ontario, Canada
19
+ =end
20
+
21
+ require 'gserver'
22
+ require 'groat/smtpd/smtp'
23
+
24
+ module Groat
25
+ module SMTPD
26
+ class Server < GServer
27
+ @server_class = Groat::SMTPD::SMTP
28
+
29
+ def initialize(server_class = nil, *args)
30
+ @server_class = server_class unless server_class.nil?
31
+ super(*args)
32
+ end
33
+
34
+ def serve(io)
35
+ @server_class.new.serve(io)
36
+ end
37
+ end
38
+ end
39
+ end