actionmailer_x509 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ public/tmp/*
2
+ tmp/*
3
+ tags
4
+ public/tmp/*
5
+ log/*
6
+ config/database.yml
7
+ *.swp
8
+ *.swo
9
+ *.dump
10
+ *~
11
+ public/*/cache/*
12
+ config/environments/development.rb
13
+ .bundle
14
+ db/*.sqlite3
15
+ tmp/**/*
16
+ rerun.txt
17
+ .bundle\n
18
+ .rvmrc
data/BSD-LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2008, Fabien Penso
2
+
3
+ All rights reserved.
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ * Neither the name of the University of California, Berkeley nor the
13
+ names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.rdoc ADDED
@@ -0,0 +1,160 @@
1
+ = ActionmailerX509
2
+
3
+ petRUShka, Fabien Penso
4
+
5
+ == DESCRIPTION
6
+
7
+ This plugin allows you to send X509 signed mails with Rails 3 ActionMailer. If you want to sign mails with Rails 2, you should use original plugin: https://github.com/penso/actionmailer_x509
8
+
9
+ It has been tested with Rails 3.0.3.
10
+
11
+ == Creation of the certificates
12
+
13
+ (1) Generate your own Certificate Authority (CA).
14
+
15
+ openssl genrsa -des3 -out ca.key 4096
16
+ openssl req -new -x509 -days 365 -key ca.key -out ca.crt
17
+
18
+ (2) Generate a server key and request for signing (csr).
19
+
20
+ Note : use your email address for the Common Name (CN) field
21
+
22
+ openssl genrsa -des3 -out server.key 4096
23
+ openssl req -new -key server.key -out server.csr
24
+
25
+ (3) Sign the certificate signing request (csr) with the self-created
26
+ certificate authority (CA) that you made earlier.
27
+
28
+ openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
29
+
30
+ (3 bis) or self sign your certificate with the same key.
31
+
32
+ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
33
+
34
+ (4) Compute all thoses files into a PCKS#12 file (so you can include it in your mailer):
35
+
36
+ openssl pkcs12 -export -in server.crt -inkey server.key -certfile ca.key -name "My Cert" -out name-cert.p12
37
+
38
+ == Extracting the files from a PKCS#12 file
39
+
40
+ If you have a PKCS#12 file, usualy named .p12, you can extract the required files with
41
+ the following commands.
42
+
43
+ (1) Extract the private key
44
+
45
+ openssl pkcs12 -in file_input.p12 -clcerts -nocerts -out file_out.key -nodes
46
+
47
+ (2) Extract the certificate
48
+
49
+ openssl pkcs12 -in file_input.p12 -clcerts -nokeys -out file_out.crt -nodes
50
+
51
+ Please note the -nodes to leave the private key uncrypted, use -des if you wish
52
+ to protect it.
53
+
54
+ == INSTALLING THE PLUGIN
55
+
56
+ Put this line in your Gemfile
57
+
58
+ gem 'actionmailer_x509'
59
+
60
+ == USING THE PLUGIN
61
+
62
+ If you wish to send a signed email you just need to put new informations in
63
+ your ActionMailer model.
64
+
65
+ class FooMailer < ActionMailer::Base
66
+
67
+ def sending_method(email, from , subject = "Empty subject for signed")
68
+ # If you want to sign the mail
69
+ x509_sign true
70
+ x509_cert "certs/yourwebsite.crt"
71
+ x509_key "certs/yourwebsite.key"
72
+ # In case your certificate has a passphrase
73
+ x509_passphrase "my passphrase for the certificate"
74
+
75
+ mail(:subject => subject, :to => email, :from => from)
76
+ end
77
+
78
+ You can also specify the certificate and key in your environment file:
79
+
80
+ ActionMailer::Base.default_x509_sign = true
81
+ ActionMailer::Base.default_x509_cert = "certs/server.crt"
82
+ ActionMailer::Base.default_x509_key = "certs/server.key"
83
+
84
+ == USING TEST
85
+
86
+ You can benchmark the plugin with:
87
+
88
+ rake actionmailer_x509:performance_test
89
+
90
+ Send yourself a signed mail with:
91
+
92
+ rake actionmailer_x509:send_test
93
+
94
+ Verify the plugin generates valid signature
95
+
96
+ rake actionmailer_x509:verify_signature
97
+
98
+ Generate a signed mail in a local file
99
+
100
+ rake actionmailer_x509:generate_mail
101
+
102
+ == REQUIREMENTS
103
+
104
+ * Ruby 1.8 or later
105
+ * Rails 3.0 or later
106
+ * OpenSSL 0.9.8e or later and Ruby/OpenSSL 1.8.6.36 or later
107
+
108
+ == Mail User Agent tested
109
+
110
+ We checked with the following MUA for making sure the signed mails are
111
+ readable.
112
+
113
+ * Mutt 1.5: OK
114
+ * Outlook 2007: OK
115
+ * iPhone: The message appears without the signature but no other problem
116
+ * Thunderbird 5.0: OK
117
+ * Evolution 2.12: OK
118
+ * Apple Mail.app: OK
119
+ * Google Mail: A file smime.p3s appears as attachment
120
+ * Yandex Mail: A file smime.p3s appears as attachment
121
+ * Opera Mail: A file smime.p3s appears as attachment
122
+
123
+ == AUTHORS
124
+
125
+ Porting to Rails 3\\Mail from Rails 2\\Tmail and wrap code in gem was done by petRUShka <petrushkin@yandex.ru>.
126
+
127
+ Original development for Rails 2.0.1 was done by Fabien Penso <fabien.penso@conovae.com> from
128
+ CONOVAE http://www.conovae.com for Dimelo http://www.dimelo.fr
129
+
130
+ Special thanks to Geal[http://stackoverflow.com/users/203955/geal] for noticing on error.
131
+
132
+ This code is under the BSD license.
133
+
134
+ == LICENSE
135
+
136
+ Copyright (c) 2011, petRUShka, 2008, Fabien Penso
137
+
138
+ All rights reserved.
139
+ Redistribution and use in source and binary forms, with or without
140
+ modification, are permitted provided that the following conditions are met:
141
+
142
+ * Redistributions of source code must retain the above copyright
143
+ notice, this list of conditions and the following disclaimer.
144
+ * Redistributions in binary form must reproduce the above copyright
145
+ notice, this list of conditions and the following disclaimer in the
146
+ documentation and/or other materials provided with the distribution.
147
+ * Neither the name of the University of California, Berkeley nor the
148
+ names of its contributors may be used to endorse or promote products
149
+ derived from this software without specific prior written permission.
150
+
151
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
152
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154
+ DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
155
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
156
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
157
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
158
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
159
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
160
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/gempackagetask'
2
+
3
+ spec = Gem::Specification.load(Dir['*.gemspec'].first)
4
+ gem = Rake::GemPackageTask.new(spec)
5
+ gem.define
6
+
7
+ desc "Push gem to rubygems.org"
8
+ task :push => :gem do
9
+ sh "gem push #{gem.package_dir}/#{gem.gem_file}"
10
+ end
@@ -0,0 +1,13 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "actionmailer_x509"
3
+ s.version = "0.3.0"
4
+ s.authors = ["petRUShka", "Fabien Penso", "CONOVAE"]
5
+ s.email = "petrushkin@yandex.ru"
6
+ s.files = `git ls-files`.split("\n")
7
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
8
+ s.homepage = "http://github.com/petRUShka/actionmailer_x509"
9
+ s.require_path = "lib"
10
+ s.rubygems_version = "1.3.5"
11
+ s.summary = "This Rails 3 plugin allows you to send X509 signed mails."
12
+ end
13
+
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + '/lib/actionmailer_x509'
2
+ require File.dirname(__FILE__) + '/lib/models/notifier.rb'
3
+
4
+ #ActionMailer::Base.send(:include, Conovae::ActionMailerX509)
data/install.rb ADDED
File without changes
@@ -0,0 +1,181 @@
1
+ # Copyright (c) 2007 Fabien Penso <fabien.penso@conovae.com>
2
+ #
3
+ # actionmailer_x509 is a rails plugin to allow X509 outgoing mail to be X509
4
+ # signed.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright
12
+ # notice, this list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright
14
+ # notice, this list of conditions and the following disclaimer in the
15
+ # documentation and/or other materials provided with the distribution.
16
+ # * Neither the name of the University of California, Berkeley nor the
17
+ # names of its contributors may be used to endorse or promote products
18
+ # derived from this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
21
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
24
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ require 'actionmailer_x509/railtie' if defined?(Rails)
31
+ require "openssl"
32
+
33
+ module ActionMailer #:nodoc:
34
+ class Base #:nodoc:
35
+ @@default_x509_sign = false
36
+ @@default_x509_crypt = false # not used, for later.
37
+ @@default_x509_cert = nil
38
+ @@default_x509_key = nil
39
+ @@default_x509_sign_method = :smime
40
+ @@default_x509_crypt_method = :smime # not used, for later.
41
+ @@default_x509_passphrase = nil
42
+
43
+ # Should we sign the outgoing mail?
44
+ adv_attr_accessor :x509_sign
45
+
46
+ # Should we crypt the outgoing mail?. NOTE: not used yet.
47
+ adv_attr_accessor :x509_crypt
48
+
49
+ # Which certificate will be used for signing.
50
+ adv_attr_accessor :x509_cert
51
+
52
+ # Which private key will be used for signing.
53
+ adv_attr_accessor :x509_key
54
+
55
+ # Which signing method is used. NOTE: For later, if needed.
56
+ adv_attr_accessor :x509_sign_method
57
+
58
+ # Which crypting method is used. NOTE: not used yet.
59
+ adv_attr_accessor :x509_crypt_method
60
+
61
+ # Passphrase for the key, if needed.
62
+ adv_attr_accessor :x509_passphrase
63
+
64
+
65
+
66
+ # We replace the create! methods and run a new method if signing is required
67
+ def initialize_with_sign(method_name, *parameters)
68
+ mail = initialize_without_sign(method_name, *parameters)
69
+
70
+ x509_initvar()
71
+
72
+ # If we need to sign the outgoing mail.
73
+ if should_sign?
74
+ if logger
75
+ logger.debug("actionmailer_x509: We should sign the mail with #{@x509_sign_method} method.")
76
+ end
77
+ __send__("x509_sign_#{@x509_sign_method}", mail)
78
+ end
79
+
80
+ end
81
+ alias_method_chain :initialize, :sign
82
+
83
+ # X509 SMIME signing
84
+ def x509_sign_smime(mail)
85
+ if logger
86
+ logger.debug("actionmailer_x509: X509 SMIME signing with cert #{@x509_cert} and key #{@x509_key}")
87
+ end
88
+
89
+ # We should set content_id, otherwise Mail will set content_id after signing and will broke sign
90
+ mail.content_id ||= nil
91
+
92
+ # We can remove the headers from the older mail we encapsulate.
93
+ # Leaving allows to have the headers signed too within the encapsulated
94
+ # email, but MUAs make no use of them... :(
95
+ #
96
+ # mail.subject = nil
97
+ # mail.to = nil
98
+ # mail.cc = nil
99
+ # mail.from = nil
100
+ # mail.date = nil
101
+ # headers.each { |k, v| mail[k] = nil }
102
+ # mail['Content-Type'] = 'text/plain'
103
+ # mail.mime_version = nil
104
+
105
+ # We load certificate and private key
106
+ cert = OpenSSL::X509::Certificate.new( File::read(@x509_cert) )
107
+ prv_key = OpenSSL::PKey::RSA.new( File::read(@x509_key), @x509_passphrase)
108
+
109
+ begin
110
+ # Sign the mail
111
+ # NOTE: the one following line is the slowest part of this code, signing is sloooow
112
+ p7sign = OpenSSL::PKCS7.sign(cert,prv_key,mail.encoded, [], OpenSSL::PKCS7::DETACHED)
113
+ smime0 = OpenSSL::PKCS7::write_smime(p7sign)
114
+
115
+ # Adding the signature part to the older mail
116
+ newm = Mail.new(smime0)
117
+
118
+ # We need to overwrite the content-type of the mail so MUA notices this is a signed mail
119
+ # newm.content_type = 'multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; '
120
+ newm.delivery_method(mail.delivery_method.class, mail.delivery_method.settings)
121
+ newm.subject = mail.subject
122
+ newm.to = mail.to
123
+ newm.cc = mail.cc
124
+ newm.from = mail.from
125
+ newm.mime_version = mail.mime_version
126
+ newm.date = mail.date
127
+ # newm.body = "This is an S/MIME signed message\n"
128
+ # headers.each { |k, v| m[k] = v } # that does nothing in general
129
+
130
+ # NOTE: We can not use this as we need a B64 encoded signature, and no
131
+ # methods provides it within the Ruby OpenSSL library... :(
132
+ #
133
+ # We add the signature
134
+ # signature = Mail.new
135
+ # signature.mime_version = '1.0'
136
+ # signature['Content-Type'] = 'application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"'
137
+ # signature['Content-Transfer-Encoding'] = 'base64'
138
+ # signature['Content-Disposition'] = 'attachment; filename="smime.p7m"'
139
+ # signature.body = p7sign.to_s
140
+ # newm.parts << signature
141
+
142
+ @_message = newm
143
+ rescue Exception => detail
144
+ logger.error("Error while SMIME signing the mail : #{detail}")
145
+ end
146
+
147
+ ## logger.debug("x509_sign_smime, resulted email\n-------------( test X509 )----------\n#{m.encoded}\n-------------( test X509 )----------")
148
+
149
+ end
150
+
151
+ # X509 SMIME crypting
152
+ def x509_crypt_smime(mail)
153
+ logger.debug("X509 SMIME crypting")
154
+ end
155
+
156
+ protected
157
+
158
+ # Shall we sign the mail?
159
+ def should_sign?
160
+ if @x509_sign == true
161
+ if not @x509_cert.nil? and not @x509_key.nil?
162
+ return true
163
+ else
164
+ logger.info "X509 signing required, but no certificate and key files configured"
165
+ end
166
+ end
167
+ return false
168
+ end
169
+
170
+ # Initiate from the default class attributes
171
+ def x509_initvar
172
+ @x509_sign ||= @@default_x509_sign
173
+ @x509_crypt ||= @@default_x509_crypt
174
+ @x509_cert ||= @@default_x509_cert
175
+ @x509_key ||= @@default_x509_key
176
+ @x509_sign_method ||= @@default_x509_sign_method
177
+ @x509_crypt_method ||= @@default_x509_crypt_method
178
+ @x509_passphrase ||= @@default_x509_passphrase
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,10 @@
1
+ require 'actionmailer_x509'
2
+ require 'rails'
3
+ module ActionMailerX509
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load "tasks/actionmailer_x509.rake"
7
+ load "tasks/tiny_performance_test.rake"
8
+ end
9
+ end
10
+ end
data/lib/certs/ca.crt ADDED
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFXTCCA0WgAwIBAgIJAPl1qZNbDf/TMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3
+ BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
4
+ aWRnaXRzIFB0eSBMdGQwHhcNMTEwNzA2MDkxNjAzWhcNMTIwNzA1MDkxNjAzWjBF
5
+ MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
6
+ ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
7
+ CgKCAgEAtrRXDvD1ynBeIMBcAYobJMtCqHvJVHFKZ7B44zP/otUB3y02rpCYust8
8
+ W6Dy+JF62M1+X1y/x13c8+/jkx+niGXheu5q5hVMQ3r643ZY7lWxnHg8cN6mKxQJ
9
+ +USQHF65zHeJM7pm2SpcJL6DSd8VUINpyucaQ7S0HEyuFPsu1b5y2RzdzMQva3+P
10
+ zufij2hZz6gnacBg/nPq5ujFg0Xqynk6SVJZ3i/WGC5YLx+ZOl0eQd96ww3Qab+r
11
+ zk05RVOqXxvnsexnQqf9a3rqjY/uks2pIYG4P4UAIA68L42VZNJarUORK0hmMBMY
12
+ Qryrj+EIejCOvZAgkwoQ+x0idmuQClKh1Vy2sypsf17DaBnPdLHnHIYQjVqUwhbc
13
+ 2HrWChZGvZ3EazUbAPO1nCx601L9RWDG4Nd90MGpNefBHl6ycg8Y2b5KNcETDCEk
14
+ 1OjHnU69vOyO+3CxB9TJYPPTMtV27aIxm/8osE3anrT0Cpk+cV+VRm61TrJn8gMy
15
+ pmfz9uxLXuUhsI+p0Ux7gDXMTSjLA+urls9I9HFWR4/SG0+2/htiFcTmAmxZTFI8
16
+ IX6MGQTAgm+sAPOai9HqzwLbZ4IXbTTWk8akrgEBU/E94gd5gV+ZA5exNbtYma4/
17
+ Ey4gBMasEfKEdaQMgGpv0k4A4XvTx3NbULkmy8SvigerV+CVuD0CAwEAAaNQME4w
18
+ HQYDVR0OBBYEFLPHmzX5GySDNz58MsJjPoKB4dRTMB8GA1UdIwQYMBaAFLPHmzX5
19
+ GySDNz58MsJjPoKB4dRTMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggIB
20
+ ADQs04X5cCpI2otnrShO8+2lF+D0uzLT2nAYl6ohxwHBgmQfn8tsHaA/e3eUg1Cm
21
+ KwH8xFCd4602uJ97lhAclsVETL4m0QeJ8iTF4uOOdIJ7cLaNRaQUI5PrdquO7o+b
22
+ wfbs7zsXfi3KwwIAVlKTfTrVWuU2+Hnf+rbyW0NIqVFgJ3XB6+dZldfkIPUDD3M6
23
+ aEqT7VNt/y0HGzACNA6/b9KpXrJMJS84LFaI13Eeuc9X7olLEElx8qZXeq9cOZoh
24
+ wwaUiofH5qBWTfqmR4+EIgfIOpfLeUaDqDRluQMTftyPR3Pow7/eB/KW2gGU8L/c
25
+ 16/5RbllERAQkSYLU9j/d8heW0/zRC7A1sNKImnTCLMotlZ1mnICFGh8AcKciScM
26
+ ptC4tckzca5AV3JxXOMUBC3q9PjfMwKVPAPr2uZFIT4c4VniUmSg/RPLJOGqRaCW
27
+ LlFD1dKE+jt1QHy0/rmk6GHnN0aff8PrGabKXQrL8KhvrI9LeEiWd8P2cWNXvVY6
28
+ +xiYwtE1atQpeblB/QWPkk6SX9njEf5iio5j979h/K9yJzpHmVrN8xOOep6UqPwB
29
+ HPwKC1S+xbpR3v3G+wytl9gwi1yQHgYmi++ez2mKEEt85nKW3dm1Dvmg2FlOs2d9
30
+ hQ+ishaBRUt9yRTb0uy065LuxCnKaD3/09vzRLPBeFRu
31
+ -----END CERTIFICATE-----
data/lib/certs/ca.key ADDED
@@ -0,0 +1,54 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ Proc-Type: 4,ENCRYPTED
3
+ DEK-Info: DES-EDE3-CBC,20AB4C981735CF97
4
+
5
+ +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
54
+ -----END RSA PRIVATE KEY-----
File without changes
@@ -0,0 +1,30 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFJTCCAw0CAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV
3
+ BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
4
+ ZDAgFw0xMTA3MDYwOTMzNTBaGA8yMDk0MDgyNDA5MzM1MFowajELMAkGA1UEBhMC
5
+ QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
6
+ dHMgUHR5IEx0ZDEjMCEGCSqGSIb3DQEJARYUcGV0cnVzaGtpbkB5YW5kZXgucnUw
7
+ ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDHzHFo6kiVWqcMRyXYMsLr
8
+ pwBXd/9NAk5MIOSJyM64Nv6SHHL5Ppkee1PuLyyXpH46iSxG7kPcWGqwfG/CxykS
9
+ xNgfDGVP6yDuUy/r/vHmduvPRA7nTQC8PWjRa01l/90Jwj/9cshU5hm7wW+nXFnr
10
+ 4FSmPAKkABxpU0MORGaGQLKHUIT7f7NjJN7Qg4ErLdtix1TgQbK5v3CFIHx5p1bW
11
+ OnsbBfVxwKcEWPkZ7Uj0VbLNkaaviRrEmL1FZhv/7DzL+vpIOVcArM+SNyYqxlys
12
+ s619/KXOjOCGkj+bUkUcOD7MdFNE9aaQHSpTBf3j++AxO9eAy0FiBgJdEwJ3jFEc
13
+ iw7P/5h/hk8ZPfN/1SeWTEqMkfrpqIRmcP/8V1lF1nw2hoLvvU/giPU8XC0ZsULp
14
+ WFdmp85thS3XfNGPyTOGWyvNbCaIN7Rh5DNtPSE2LbAffNzuhcn5PIkFc5t9S/ni
15
+ dcQMnlPmSrkNfLNM0AC9nKbq81QxwyT8KDOZ3eJvb6ju52q1Co3N67KF+CFfVg2N
16
+ FU9WkkkKwD7xfnFdHf8hT+OoLYlxXhdXsRCf1Diu/Ap4ZldlmY41ndBwpAXiDAwB
17
+ R+EPV086LlkLhGIaK1cxMGzMG/SbnXKev3QrsvH2ii9aKaYXaJZcot4MoAla+kkO
18
+ 7Etx049uU2+zjp6rwashTQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQB1WrdGLJv3
19
+ YFWfQYYJDKLQG5aTbKZ4ATeR3T3So9UQpiriICM1bNUfPxx2zvBCF+wbfGdTB7uU
20
+ ENXEz6qWzhjN8E1MKoeq5XCdIiW5Bu8YmN1VTMlzoNgo5b13AptrYg7oFYvaaHNQ
21
+ gOXS1R8AYRxA5DKVzfaDxY4+MERe8aDFMr4vryO4o/A1f8P+hfd09dylOFiK9l6l
22
+ +STvOpESfqOL7dZgmtryJPLKFVHLLreh8i7PzZO7aiixazUx3B1qHisYyY9W5Bh3
23
+ iabgIQjsNG2Ktqbm4MxpXwlVqVmgDg7x9hPWB/PZha7NiegoTktt/pWQ6J+x7HY2
24
+ BDH0BRLdZzK+wgOpXLFCbbln+f16lfzbCqKQyeGWbb6fsw7nVjvindXWCnZgBbty
25
+ T9WuAtoCRfn4x4X75Kcac6ywRHJlPCU6y/KWYNJ9MP+cVoRi7xvpeld75V2TVocF
26
+ CqUawAId7XWvNh6kifMz7FCY9feaMV/r4VrNux99jFYA5QwgvJkEssaIW+wlEj3l
27
+ +suTxhIPt9aTROJfhT16R6mTiYNejPSiT2FMDru8PxaU7S5h2awsXGkSex0PWSmy
28
+ 7bI8rOOIKNR5WQZs+3+FvyqJ6AV3vEYJ8TiRA20D/Wb3jLED96qEKbMxRLto7VRC
29
+ kjDVtS3lkVU/4Hx51KttPtvmWDavkZP5aw==
30
+ -----END CERTIFICATE-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIIErzCCApcCAQAwajELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
3
+ ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEjMCEGCSqGSIb3DQEJ
4
+ ARYUcGV0cnVzaGtpbkB5YW5kZXgucnUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
5
+ ggIKAoICAQDHzHFo6kiVWqcMRyXYMsLrpwBXd/9NAk5MIOSJyM64Nv6SHHL5Ppke
6
+ e1PuLyyXpH46iSxG7kPcWGqwfG/CxykSxNgfDGVP6yDuUy/r/vHmduvPRA7nTQC8
7
+ PWjRa01l/90Jwj/9cshU5hm7wW+nXFnr4FSmPAKkABxpU0MORGaGQLKHUIT7f7Nj
8
+ JN7Qg4ErLdtix1TgQbK5v3CFIHx5p1bWOnsbBfVxwKcEWPkZ7Uj0VbLNkaaviRrE
9
+ mL1FZhv/7DzL+vpIOVcArM+SNyYqxlyss619/KXOjOCGkj+bUkUcOD7MdFNE9aaQ
10
+ HSpTBf3j++AxO9eAy0FiBgJdEwJ3jFEciw7P/5h/hk8ZPfN/1SeWTEqMkfrpqIRm
11
+ cP/8V1lF1nw2hoLvvU/giPU8XC0ZsULpWFdmp85thS3XfNGPyTOGWyvNbCaIN7Rh
12
+ 5DNtPSE2LbAffNzuhcn5PIkFc5t9S/nidcQMnlPmSrkNfLNM0AC9nKbq81QxwyT8
13
+ KDOZ3eJvb6ju52q1Co3N67KF+CFfVg2NFU9WkkkKwD7xfnFdHf8hT+OoLYlxXhdX
14
+ sRCf1Diu/Ap4ZldlmY41ndBwpAXiDAwBR+EPV086LlkLhGIaK1cxMGzMG/SbnXKe
15
+ v3QrsvH2ii9aKaYXaJZcot4MoAla+kkO7Etx049uU2+zjp6rwashTQIDAQABoAAw
16
+ DQYJKoZIhvcNAQEFBQADggIBAKmseKzIrSxGyoMMw/FOc7K7NiMKV0mzw4DCbtQ5
17
+ B6ArkV3eui41oAZ7l0rW6seRuPZJTyNUDi1SqTK0oiUOmR2GzR0maaMrhMIRoX9T
18
+ eNmjwK02PzogIAODaczqomznfnCPRdcbq/Lz4iUSbLZilAGfj9RXCwRuvj0V/Lin
19
+ Sxzht0+pFws+t2ofQiaD7+MIT3hP9+gljqrfAWcCdWC5rmcpVSXjk/8v3bBUm+Km
20
+ c/10rMq3P13gbo4BzzVEmdNmUbfnT8yXs+akypP+SlBbg4V5ubrKoNPy1v+tWaZ0
21
+ +L3YAFogMFOzXNUmjHKmiENnqdwTCt7cStYwZ+dUc8ZKZUzVF7/JbL/i+llX3fjZ
22
+ vAGWAZXHD1+i4vJ8IJv4h2+/UBgRk5LmAH5fjNC8Ay50NQyLA/FTAVAsYdu+arfM
23
+ RTrcIpQiTy5v1QQYD2OqqX7VcwfBPEMUwM+x6eVgwsrqbK7p8DANhNNiWNqzwXFl
24
+ N87o0HGMuATHTGyB965r/FPpUdvetOjCmENZ0bMCvQmexNzQUdnrbaqcHEKn5lmQ
25
+ Qymf/lvsGHN8gobxzEmc1WeMrrfJexui6HR846EI4V5/kPhKGJUORkrtnXVGfKe6
26
+ xftdAobLYJt7iqvnjmsKAbyUnW44TFl66j7PFyVa2u0knZRM4EQLw2JWewcNPQll
27
+ ejcy
28
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,54 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ Proc-Type: 4,ENCRYPTED
3
+ DEK-Info: DES-EDE3-CBC,2E3CACC6B03CCE9D
4
+
5
+ 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
54
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,24 @@
1
+ class Notifier < ActionMailer::Base #:nodoc:
2
+
3
+ # self.template_root = "#{File.dirname(__FILE__)}/../views/"
4
+ self.prepend_view_path("#{File.dirname(__FILE__)}/../views/")
5
+
6
+ def fufu(email, from, subject = "Empty subject")
7
+ mail(:to => email, :subject => subject, :from => from)
8
+ end
9
+
10
+ def fufusigned(email, from ,
11
+ subject = "Empty subject for signed",
12
+ cert = "#{File.dirname(__FILE__)}/../certs/server.crt",
13
+ key = "#{File.dirname(__FILE__)}/../certs/server.key")
14
+
15
+ x509_sign true
16
+ x509_cert cert
17
+ x509_key key
18
+ x509_passphrase "demo"
19
+
20
+ mail(:subject => subject, :to => email, :from => from) do |format|
21
+ format.text {render 'fufu'}
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,69 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'models/notifier'
5
+
6
+ namespace :actionmailer_x509 do
7
+ desc "Sending a mail, for test."
8
+ task(:send_test => :environment) do
9
+ if ENV['email'].nil?
10
+ puts "You should call the rake task like\nrake actionmailer_x509:send_test email=yourmail@yourdomain.com\n"
11
+ else
12
+ puts "Note: Please make sure you have configured ActionMailer."
13
+ puts "The mail sent might be stoped by antispam."
14
+ puts "If you wish to verify the signature, please include"
15
+ puts "#{File.dirname(__FILE__)}/../certs/ca.crt"
16
+ puts "as an authority in your MUA. Remove it after your test!!!\n\n"
17
+ puts "Emailing <#{ENV['email']}>"
18
+ Notifier.fufusigned("#{ENV['email']}", "demo@foobar.com", "Signed mail at #{Time.now.to_s}").deliver
19
+ end
20
+ end
21
+
22
+
23
+ desc "Performance test."
24
+ task(:performance_test => :environment) do
25
+ require 'benchmark'
26
+
27
+ n = 100
28
+ Benchmark.bm do |x|
29
+ x.report("#{n} mails without signature: ") {
30
+ for i in 1..n do
31
+ Notifier.fufu("<destination@foobar.com>", "<demo@foobar.com>")
32
+ end
33
+ }
34
+ x.report("#{n} mails with signature: ") {
35
+ for i in 1..n do
36
+ Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>")
37
+ end
38
+ }
39
+ end
40
+ end
41
+
42
+ desc "Generates a signed mail in a file."
43
+ task(:generate_mail => :environment) do
44
+ mail = Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>")
45
+ path = ENV['mail']
46
+ path = "tmp/signed_mail.txt" if path.nil?
47
+ File.open(path, "w") do |f|
48
+ f.write mail.encoded
49
+ end
50
+ puts "Signed mail is at #{path}."
51
+ puts "You can use mail=filename as argument to change it." if ENV['mail'].nil?
52
+ end
53
+
54
+ desc "Check if signature is valid."
55
+ task(:verify_signature => :environment) do
56
+ require 'tempfile'
57
+ mail = Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>")
58
+
59
+ tf = Tempfile.new('actionmailer_x509')
60
+ tf.write mail.encoded
61
+ tf.flush
62
+
63
+ comm = "openssl smime -verify -in #{tf.path} -CAfile #{File.dirname(__FILE__)}/../lib/certs/ca.crt > /dev/null"
64
+
65
+ puts "Using openssl command to verify signature..."
66
+ system(comm)
67
+
68
+ end
69
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright (c) 2007 Fabien Penso <fabien.penso@conovae.com>
2
+ #
3
+ # A simple test to show how slow is the Ruby/SSL signature function
4
+ #
5
+ # All rights reserved.
6
+
7
+ require 'rake'
8
+ require 'rake/testtask'
9
+ require 'rake/rdoctask'
10
+ require "openssl"
11
+
12
+ def sign_single_body_pipe
13
+
14
+ body = <<"EOF"
15
+ Date: Fri, 01 Jan 2008 11:57:45 +0100
16
+ From: demo@foobar.com
17
+ To: destination@foobar.com
18
+ Subject: Empty subject for signed
19
+ Mime-Version: 1.0
20
+
21
+ This is the body of the mail
22
+ EOF
23
+
24
+ require 'tempfile'
25
+
26
+ tf = Tempfile.new('actionmailer_x509')
27
+ tf.write body
28
+ tf.flush
29
+
30
+ tf2 = Tempfile.new('actionmailer_x509')
31
+ tf2.flush
32
+
33
+ comm = "openssl smime -sign -passin pass:demo -in #{tf.path} -text -out #{tf2.path} -signer #{File.dirname(__FILE__)}/../lib/certs/server.crt -inkey #{File.dirname(__FILE__)}/../lib/certs/server.key"
34
+
35
+ system(comm)
36
+
37
+ end
38
+
39
+ def sign_single_body
40
+
41
+ body = <<"EOF"
42
+ Date: Fri, 01 Jan 2008 11:57:45 +0100
43
+ From: demo@foobar.com
44
+ To: destination@foobar.com
45
+ Subject: Empty subject for signed
46
+ Mime-Version: 1.0
47
+
48
+ This is the body of the mail
49
+ EOF
50
+
51
+ cert = OpenSSL::X509::Certificate.new( File::read("#{File.dirname(__FILE__)}/../lib/certs/server.crt") )
52
+ prv_key = OpenSSL::PKey::RSA.new( File::read("#{File.dirname(__FILE__)}/../lib/certs/server.key"), "demo")
53
+
54
+ p7sign = OpenSSL::PKCS7.sign(cert,prv_key,body, [], OpenSSL::PKCS7::DETACHED)
55
+
56
+ #smime0 = OpenSSL::PKCS7::write_smime(p7sign)
57
+
58
+ end
59
+
60
+ namespace :actionmailer_x509 do
61
+
62
+ #desc "Tiny Performance test."
63
+ task(:tiny_performance_test => :environment) do
64
+ require 'benchmark'
65
+
66
+ n = 100
67
+ Benchmark.bm do |x|
68
+ x.report("#{n} loops with pipe") {
69
+ for i in 1..n do
70
+ sign_single_body_pipe
71
+ end
72
+ }
73
+ x.report("#{n} loops Ruby/SSL") {
74
+ for i in 1..n do
75
+ sign_single_body
76
+ end
77
+ }
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,3 @@
1
+ This is the signed part of the mail
2
+
3
+ This is the 3rd line, to make sure...
@@ -0,0 +1,79 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/helper'
4
+ require File.dirname(__FILE__) + '/../init'
5
+
6
+ class ActionmailerX509Test < Test::Unit::TestCase #:nodoc:
7
+
8
+ # If we want to sign a message, verify a signature is attached
9
+ def test_signed
10
+ mail = Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>")
11
+
12
+ assert_equal mail.delivery_method.settings[:address], 'smtp.com'
13
+ assert_equal mail.from, [ "demo@foobar.com" ]
14
+
15
+ found = false
16
+ for part in mail.parts do
17
+ if part.content_type =~ /application\/x-pkcs7-signature/
18
+ found = true
19
+ break
20
+ end
21
+ end
22
+ assert_equal found, true
23
+
24
+ require 'tempfile'
25
+
26
+ tf = Tempfile.new('actionmailer_x509')
27
+ tf.write mail.encoded
28
+ tf.flush
29
+
30
+ comm = "openssl smime -verify -in #{tf.path} -CAfile #{File.dirname(__FILE__)}/../lib/certs/ca.crt 2>&1"
31
+
32
+ success = false
33
+ output = IO.popen(comm)
34
+ while output.gets do
35
+ if $_ =~ /^Verification successful/
36
+ success = true
37
+ end
38
+ end
39
+ assert_equal(success, true)
40
+ end
41
+
42
+ # If we want no signature, verify not signature is attached to the mail
43
+ def test_not_signed
44
+ mail = Notifier.fufu("<destination@foobar.com>", "<demo@foobar.com>")
45
+
46
+ found = false
47
+ for part in mail.parts do
48
+ puts part.content_type
49
+ if part.content_type =~ /application\/x-pkcs7-signature/
50
+ found = true
51
+ break
52
+ end
53
+ end
54
+ assert_equal found, false
55
+ end
56
+
57
+ # If we want to sign a message but no certificate is on the filesystem
58
+ def test_signed_with_no_certs
59
+ crashed = false
60
+ begin
61
+ mail = Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>", "", "/tmp/doesnotexist")
62
+ rescue Errno::ENOENT => detail
63
+ crashed = true
64
+ end
65
+
66
+ assert_equal(crashed, true)
67
+ end
68
+
69
+ # If we want to sign a message but incorrect certificate is given
70
+ def test_signed_incorrect_certs
71
+ crashed = false
72
+ begin
73
+ mail = Notifier.fufusigned("<destination@foobar.com>", "<demo@foobar.com>", "", "#{File.dirname(__FILE__)}/../lib/certs/server.key")
74
+ rescue OpenSSL::X509::CertificateError => detail
75
+ crashed = true
76
+ end
77
+ assert_equal(crashed, true)
78
+ end
79
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'test/unit'
2
+
3
+ unless defined?(ActiveRecord)
4
+ plugin_root = File.join(File.dirname(__FILE__), '..')
5
+
6
+ # first look for a symlink to a copy of the framework
7
+ if framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
8
+ puts "found framework root: #{framework_root}"
9
+ # this allows for a plugin to be tested outside an app
10
+ $:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
11
+ else
12
+ # is the plugin installed in an application?
13
+ app_root = plugin_root + '/../../..'
14
+
15
+ if File.directory? app_root + '/config'
16
+ puts 'using config/boot.rb'
17
+ ENV['RAILS_ENV'] = 'test'
18
+ require File.expand_path(app_root + '/config/boot')
19
+ else
20
+ # simply use installed gems if available
21
+ puts 'using rubygems'
22
+ require 'rubygems'
23
+ gem 'actionpack'; gem 'activerecord'
24
+ end
25
+ end
26
+
27
+ require 'action_mailer'
28
+
29
+ # ActiveSupport::Dependencies.autoload_paths.unshift "#{plugin_root}/lib"
30
+ require plugin_root + '/lib/models/notifier'
31
+ end
32
+
33
+ ActionMailer::Base.smtp_settings = {
34
+ :address => "smtp.com",
35
+ :port => 465,
36
+ :domain => 'test.com',
37
+ :user_name => 'user',
38
+ :password => 'pass',
39
+ :authentication => 'login',
40
+ :enable_starttls_auto => true
41
+ }
42
+
data/uninstall.rb ADDED
File without changes
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: actionmailer_x509
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.3.0
6
+ platform: ruby
7
+ authors:
8
+ - petRUShka
9
+ - Fabien Penso
10
+ - CONOVAE
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2011-07-31 00:00:00 +04:00
16
+ default_executable:
17
+ dependencies: []
18
+
19
+ description:
20
+ email: petrushkin@yandex.ru
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files: []
26
+
27
+ files:
28
+ - .gitignore
29
+ - BSD-LICENSE
30
+ - README.rdoc
31
+ - Rakefile
32
+ - actionmailer_x509.gemspec
33
+ - init.rb
34
+ - install.rb
35
+ - lib/actionmailer_x509.rb
36
+ - lib/actionmailer_x509/railtie.rb
37
+ - lib/certs/ca.crt
38
+ - lib/certs/ca.key
39
+ - lib/certs/name-cert.p12
40
+ - lib/certs/server.crt
41
+ - lib/certs/server.csr
42
+ - lib/certs/server.key
43
+ - lib/models/notifier.rb
44
+ - lib/tasks/actionmailer_x509.rake
45
+ - lib/tasks/tiny_performance_test.rake
46
+ - lib/views/notifier/fufu.erb
47
+ - test/actionmailer_x509_test.rb
48
+ - test/helper.rb
49
+ - uninstall.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/petRUShka/actionmailer_x509
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.6.2
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: This Rails 3 plugin allows you to send X509 signed mails.
78
+ test_files:
79
+ - test/actionmailer_x509_test.rb
80
+ - test/helper.rb