Module: PWN::Plugins::Pony

Defined in:
lib/pwn/plugins/pony.rb

Overview

This is a fork of the no-longer maintained ‘pony’ gem. This module’s purpose is to exist until the necessary functionality can be integrated into PWN::Plugins::MailAgent

Constant Summary collapse

@@options =
{}
@@override_options =
{}
@@subject_prefix =
false
@@append_inputs =
false

Class Method Summary collapse

Class Method Details

.add_attachments(mail, attachments) ⇒ Object

Method usage N/A



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/pwn/plugins/pony.rb', line 239

public_class_method def self.add_attachments(mail, attachments)
  attachments.each do |name, body|
    name = name.gsub(/\s+/, ' ')

    # mime-types wants to send these as "quoted-printable"
    if name.match?('.xlsx')
      mail.attachments[name] = {
        content: Base64.strict_encode64(body),
        transfer_encoding: :base64
      }
    else
      mail.attachments[name] = body
    end
    mail.attachments[name].add_content_id("<#{name}@#{Socket.gethostname}>")
  end
end

.append_inputsObject

Method usage N/A



53
54
55
# File 'lib/pwn/plugins/pony.rb', line 53

public_class_method def self.append_inputs
  @@append_inputs = true
end

.authorsObject

Author(s)

0day Inc. <[email protected]>



265
266
267
268
269
# File 'lib/pwn/plugins/pony.rb', line 265

public_class_method def self.authors
  "AUTHOR(S):
    0day Inc. <[email protected]>
  "
end

.build_html_part(options) ⇒ Object

Method usage N/A



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/pwn/plugins/pony.rb', line 190

public_class_method def self.build_html_part(options)
  Mail::Part.new(content_type: 'text/html;charset=UTF-8') do
    content_transfer_encoding 'quoted-printable'
    body Mail::Encodings::QuotedPrintable.encode(options[:html_body])
    if options[:html_body_part_header] && options[:html_body_part_header].is_a?(Hash)
      options[:html_body_part_header].each do |k, v|
        header[k] = v
      end
    end
  end
end

.build_mail(options) ⇒ Object

Method usage N/A



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/pwn/plugins/pony.rb', line 136

public_class_method def self.build_mail(options)
  mail = Mail.new do |m|
    options[:date] ||= Time.now
    options[:from] ||= 'pony@unknown'
    options[:via_options] ||= {}

    options.each do |k, v|
      next if non_standard_options.include?(k)

      m.send(k, v)
    end

    # Automatic handling of multipart messages in the underlying
    # mail library works pretty well for the most part, but in
    # the case where we have attachments AND text AND html bodies
    # we need to explicitly define a second multipart/alternative
    # boundary to encapsulate the body-parts within the
    # multipart/mixed boundary that will be created automatically.
    if options[:attachments] && options[:html_body] && options[:body]
      part(content_type: 'multipart/alternative') do |p|
        p.html_part = build_html_part(options)
        p.text_part = build_text_part(options)
      end

    # Otherwise if there is more than one part we still need to
    # ensure that they are all declared to be separate.
    elsif options[:html_body] || options[:attachments]
      m.html_part = build_html_part(options) if options[:html_body]

      m.text_part = build_text_part(options) if options[:body]

    elsif options[:body]
      # If all we have is a text body, we don't need to worry about parts.
      body options[:body]
    end

    m.delivery_method options[:via], options[:via_options]
  end

  (options[:headers] ||= {}).each do |key, value|
    mail[key] = value
  end

  add_attachments(mail, options[:attachments]) if options[:attachments]

  mail.charset = options[:charset] if options[:charset] # charset must be set after setting content_type

  mail.text_part.charset = options[:text_part_charset] if mail.multipart? && options[:text_part_charset]
  set_content_type(mail, options[:content_type])
  mail
end

.build_text_part(options) ⇒ Object

Method usage N/A



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/pwn/plugins/pony.rb', line 204

public_class_method def self.build_text_part(options)
  Mail::Part.new(content_type: 'text/plain') do
    content_type options[:charset] if options[:charset]
    body options[:body]
    if options[:body_part_header] && options[:body_part_header].is_a?(Hash)
      options[:body_part_header].each do |k, v|
        header[k] = v
      end
    end
  end
end

.default_delivery_methodObject

Method usage N/A



95
96
97
# File 'lib/pwn/plugins/pony.rb', line 95

public_class_method def self.default_delivery_method
  File.executable?(sendmail_binary) ? :sendmail : :smtp
end

.helpObject

Display Usage for this Module



273
274
275
276
277
278
# File 'lib/pwn/plugins/pony.rb', line 273

public_class_method def self.help
  puts "USAGE:
    This module is deprecated.  Please Use PWN::Plugins::MailAgent instead.
    #{self}.authors
  "
end

.mail(options) ⇒ Object

Send an email

Pony.mail(:to => '[email protected]', :from => '[email protected]', :subject => 'hi', :body => 'Hello there.')
Pony.mail(:to => '[email protected]', :html_body => '<h1>Hello there!</h1>', :body => "In case you can't read html, Hello there.")
Pony.mail(:to => '[email protected]', :cc => '[email protected]', :from => '[email protected]', :subject => 'hi', :body => 'Howsit!')

Raises:

  • (ArgumentError)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/pwn/plugins/pony.rb', line 61

public_class_method def self.mail(options)
  options[:body] = "#{options[:body]}/n #{options}" if @@append_inputs

  options = @@options.merge options
  options = options.merge @@override_options

  options[:subject] = "#{@@subject_prefix}#{options[:subject]}" if @@subject_prefix

  raise ArgumentError, ':to is required' unless options[:to]

  options[:via] = default_delivery_method unless options.key?(:via)

  if options.key?(:via) && options[:via] == :sendmail
    options[:via_options] ||= {}
    options[:via_options][:location] ||= sendmail_binary
  end

  deliver build_mail(options)
end

.non_standard_optionsObject

Method usage N/A



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/pwn/plugins/pony.rb', line 118

public_class_method def self.non_standard_options
  %i[
    attachments
    body
    charset
    enable_starttls_auto
    headers
    html_body
    text_part_charset
    via
    via_options
    body_part_header
    html_body_part_header
  ]
end

.optionsObject

Method usage N/A



29
30
31
# File 'lib/pwn/plugins/pony.rb', line 29

public_class_method def self.options
  @@options
end

.options=(value) ⇒ Object

Default options can be set so that they don’t have to be repeated.

Pony.options = { :from => '[email protected]', :via => :smtp, :via_options => { :host => 'smtp.yourserver.com' } }
Pony.mail(:to => 'foo@bar') # Sends mail to foo@bar from [email protected] using smtp
Pony.mail(:from => '[email protected]', :to => 'foo@bar') # Sends mail to foo@bar from [email protected] using smtp


23
24
25
# File 'lib/pwn/plugins/pony.rb', line 23

public_class_method def self.options=(value)
  @@options = value
end

.override_optionsObject

Method usage N/A



41
42
43
# File 'lib/pwn/plugins/pony.rb', line 41

public_class_method def self.override_options
  @@override_options
end

.override_options=(value) ⇒ Object

Method usage N/A



35
36
37
# File 'lib/pwn/plugins/pony.rb', line 35

public_class_method def self.override_options=(value)
  @@override_options = value
end

.permissable_optionsObject

Method usage N/A



83
84
85
# File 'lib/pwn/plugins/pony.rb', line 83

public_class_method def self.permissable_options
  standard_options + non_standard_options
end

.sendmail_binaryObject

Method usage N/A



258
259
260
261
# File 'lib/pwn/plugins/pony.rb', line 258

public_class_method def self.sendmail_binary
  sendmail = `which sendmail`.chomp
  sendmail.empty? ? '/usr/sbin/sendmail' : sendmail
end

.set_content_type(mail, user_content_type) ⇒ Object

Method usage N/A



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/pwn/plugins/pony.rb', line 218

public_class_method def self.set_content_type(mail, user_content_type)
  params = mail.content_type_parameters || {}
  case params
  when user_content_type
    content_type = user_content_type
  when mail.has_attachments?
    if mail.attachments.detect(&:inline?)
      content_type = ['multipart', 'related', params]
    else
      content_type = ['multipart', 'mixed', params]
    end
  when mail.multipart?
    content_type = ['multipart', 'alternative', params]
  else
    content_type = false
  end
  mail.content_type = content_type if content_type
end

.standard_optionsObject

Method usage N/A



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/pwn/plugins/pony.rb', line 101

public_class_method def self.standard_options
  %i[
    to
    cc
    bcc
    from
    subject
    content_type
    message_id
    sender
    reply_to
    smtp_envelope_to
  ]
end

.subject_prefix(value) ⇒ Object

Method usage N/A



47
48
49
# File 'lib/pwn/plugins/pony.rb', line 47

public_class_method def self.subject_prefix(value)
  @@subject_prefix = value
end