Class: Rex::MIME::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/mime/message.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = nil) ⇒ Message

Returns a new instance of Message.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rex/mime/message.rb', line 11

def initialize(data=nil)
	self.header = Rex::MIME::Header.new
	self.parts  = []
	self.bound  = "_Part_#{rand(1024)}_#{rand(0xffffffff)}_#{rand(0xffffffff)}"
	self.content = ''
	if data
		head,body = data.split(/\r?\n\r?\n/, 2)

		self.header.parse(head)
		ctype = self.header.find('Content-Type')

		if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary=([^\s]+)/
			self.bound = $1

			chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
			self.content = chunks.shift.to_s.gsub(/\s+$/, '')
			self.content << "\r\n" if not self.content.empty?

			chunks.each do |chunk|
				break if chunk == "--"
				head,body = chunk.split(/\r?\n\r?\n/, 2)
				part = Rex::MIME::Part.new
				part.header.parse(head)
				part.content = body.gsub(/\s+$/, '')
				self.parts << part
			end
		else
			self.content = body.to_s.gsub(/\s+$/, '') + "\r\n"
		end
	end
end

Instance Attribute Details

#boundObject

Returns the value of attribute bound.



9
10
11
# File 'lib/rex/mime/message.rb', line 9

def bound
  @bound
end

#contentObject

Returns the value of attribute content.



9
10
11
# File 'lib/rex/mime/message.rb', line 9

def content
  @content
end

#headerObject

Returns the value of attribute header.



9
10
11
# File 'lib/rex/mime/message.rb', line 9

def header
  @header
end

#partsObject

Returns the value of attribute parts.



9
10
11
# File 'lib/rex/mime/message.rb', line 9

def parts
  @parts
end

Instance Method Details

#add_part(data = '', content_type = 'text/plain', transfer_encoding = "8bit", content_disposition = nil) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rex/mime/message.rb', line 84

def add_part(data='', content_type='text/plain', transfer_encoding="8bit", content_disposition=nil)
	part = Rex::MIME::Part.new

	if (content_disposition)
		part.header.set("Content-Disposition", content_disposition)
	end

	part.header.set("Content-Type", content_type)

	if (transfer_encoding)
		part.header.set("Content-Transfer-Encoding", transfer_encoding)
	end

	part.content = data
	self.parts << part
	part
end

#add_part_attachment(data, name) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/rex/mime/message.rb', line 102

def add_part_attachment(data, name)
	self.add_part(
		Rex::Text.encode_base64(data, "\r\n"),
		"application/octet-stream; name=\"#{name}\"",
		"base64",
		"attachment; filename=\"#{name}\""
	)
end

#add_part_inline_attachment(data, name) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/rex/mime/message.rb', line 112

def add_part_inline_attachment(data, name)
	self.add_part(
		Rex::Text.encode_base64(data, "\r\n"),
		"application/octet-stream; name=\"#{name}\"",
		"base64",
		"inline; filename=\"#{name}\""
	)
end

#fromObject



55
56
57
# File 'lib/rex/mime/message.rb', line 55

def from
	(self.header.find('From') || [nil, nil])[1]
end

#from=(val) ⇒ Object



51
52
53
# File 'lib/rex/mime/message.rb', line 51

def from=(val)
	self.header.set("From", val)
end

#mime_defaultsObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rex/mime/message.rb', line 67

def mime_defaults
	self.header.set("MIME-Version", "1.0")
	self.header.set("Content-Type", "multipart/mixed; boundary=\"#{self.bound}\"")
	self.header.set("Subject", '') # placeholder
	self.header.set("Date", Time.now.strftime("%a,%e %b %Y %H:%M:%S %z"))
	self.header.set("Message-ID",
		"<"+
		Rex::Text.rand_text_alphanumeric(rand(20)+40)+
		"@"+
		Rex::Text.rand_text_alpha(rand(20)+3)+
		">"
	)
	self.header.set("From", '')    # placeholder
	self.header.set("To", '')      # placeholder
end

#subjectObject



63
64
65
# File 'lib/rex/mime/message.rb', line 63

def subject
	(self.header.find('Subject') || [nil, nil])[1]
end

#subject=(val) ⇒ Object



59
60
61
# File 'lib/rex/mime/message.rb', line 59

def subject=(val)
	self.header.set("Subject", val)
end

#toObject



43
44
45
# File 'lib/rex/mime/message.rb', line 43

def to
	(self.header.find('To') || [nil, nil])[1]
end

#to=(val) ⇒ Object



47
48
49
# File 'lib/rex/mime/message.rb', line 47

def to=(val)
	self.header.set("To", val)
end

#to_sObject



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rex/mime/message.rb', line 121

def to_s
	msg = self.header.to_s + "\r\n"

	if self.content and not self.content.empty?
		msg << self.content + "\r\n"
	end

	self.parts.each do |part|
		msg << "--" + self.bound + "\r\n"
		msg << part.to_s + "\r\n"
	end

	if self.parts.length > 0
		msg << "--" + self.bound + "--\r\n"
	end

	# Force CRLF for SMTP compatibility
	msg.gsub("\r", '').gsub("\n", "\r\n")
end