CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/file_stat.rb
Views: 11780
1
# -*- coding: binary -*-
2
3
#
4
# This is just a container class basically, that acts like File::Struct
5
#
6
# You must supply an initialize method that somehow populates the stathash..
7
#
8
9
module Rex
10
module Post
11
12
###
13
#
14
# This class emulates the ruby FileStat class against a remote entity in a
15
# generic fashion. Refer to the ruby documentation for expected behavior.
16
#
17
###
18
class FileStat
19
20
#
21
# Basic file types.
22
#
23
@@ftypes = [
24
'fifo', 'characterSpecial', 'directory',
25
'blockSpecial', 'file', 'link', 'socket'
26
]
27
28
attr_accessor :stathash
29
30
def initialize(buf='')
31
self.stathash = {}
32
update(buf) if (buf and not buf.empty?)
33
end
34
35
def dev
36
self.stathash['st_dev']
37
end
38
def ino
39
self.stathash['st_ino']
40
end
41
def mode
42
self.stathash['st_mode']
43
end
44
def nlink
45
self.stathash['st_nlink']
46
end
47
def uid
48
self.stathash['st_uid']
49
end
50
def gid
51
self.stathash['st_gid']
52
end
53
def rdev
54
self.stathash['st_rdev']
55
end
56
def size
57
self.stathash['st_size']
58
end
59
def blksize
60
self.stathash['st_blksize']
61
end
62
def blocks
63
self.stathash['st_blocks']
64
end
65
def atime
66
::Time.at(self.stathash['st_atime'])
67
end
68
def mtime
69
::Time.at(self.stathash['st_mtime'])
70
end
71
def ctime
72
::Time.at(self.stathash['st_ctime'])
73
end
74
75
def update(buf)
76
skeys = %W{st_dev st_mode st_nlink st_uid st_gid st_rdev st_ino st_size st_atime st_mtime st_ctime}
77
svals = buf.unpack("VVVVVVQQQQQ")
78
skeys.each_index do |i|
79
self.stathash[ skeys[i] ] = svals[i]
80
end
81
end
82
83
#
84
# This handles the old 32bit st_size buf from old stageless meterpreters for backwards compatibility
85
# Maybe we can remove this in the future
86
#
87
def update32(buf)
88
skeys = %W{st_dev st_ino st_mode st_pad st_nlink st_uid st_gid st_rdev st_size st_ctime st_atime st_mtime}
89
svals = buf.unpack("VvvvvvvVVVVV")
90
skeys.each_index do |i|
91
self.stathash[ skeys[i] ] = svals[i]
92
end
93
end
94
95
#
96
# S_IFMT 0170000 bitmask for the file type bitfields
97
# S_IFSOCK 0140000 socket
98
# S_IFLNK 0120000 symbolic link
99
# S_IFREG 0100000 regular file
100
# S_IFBLK 0060000 block device
101
# S_IFDIR 0040000 directory
102
# S_IFCHR 0020000 character device
103
# S_IFIFO 0010000 fifo
104
#
105
106
# this is my own, just a helper...
107
def filetype?(mask)
108
return true if mode & 0170000 == mask
109
return false
110
end
111
112
def blockdev?
113
filetype?(060000)
114
end
115
def chardev?
116
filetype?(020000)
117
end
118
def directory?
119
filetype?(040000)
120
end
121
def file?
122
filetype?(0100000)
123
end
124
def pipe?
125
filetype?(010000) # ??? fifo?
126
end
127
def socket?
128
filetype?(0140000)
129
end
130
def symlink?
131
filetype?(0120000)
132
end
133
134
def ftype
135
return @@ftypes[(mode & 0170000) >> 13].dup
136
end
137
138
#
139
# S_ISUID 0004000 set UID bit
140
# S_ISGID 0002000 set GID bit (see below)
141
# S_ISVTX 0001000 sticky bit (see below)
142
# S_IRWXU 00700 mask for file owner permissions
143
# S_IRUSR 00400 owner has read permission
144
# S_IWUSR 00200 owner has write permission
145
# S_IXUSR 00100 owner has execute permission
146
# S_IRWXG 00070 mask for group permissions
147
# S_IRGRP 00040 group has read permission
148
# S_IWGRP 00020 group has write permission
149
# S_IXGRP 00010 group has execute permission
150
# S_IRWXO 00007 mask for permissions for others (not in group)
151
# S_IROTH 00004 others have read permission
152
# S_IWOTH 00002 others have write permission
153
# S_IXOTH 00001 others have execute permission
154
#
155
156
def perm?(mask)
157
return true if mode & mask == mask
158
return false
159
end
160
161
def setgid?
162
perm?(02000)
163
end
164
def setuid?
165
perm?(04000)
166
end
167
def sticky?
168
perm?(01000)
169
end
170
171
def executable?
172
raise NotImplementedError
173
end
174
def executable_real?
175
raise NotImplementedError
176
end
177
def grpowned?
178
raise NotImplementedError
179
end
180
def owned?
181
raise NotImplementedError
182
end
183
def readable?
184
raise NotImplementedError
185
end
186
def readable_real?
187
raise NotImplementedError
188
end
189
def writeable?
190
raise NotImplementedError
191
end
192
def writeable_real?
193
raise NotImplementedError
194
end
195
196
#
197
# Return pretty information about a file's permissions.
198
#
199
def prettymode
200
m = mode
201
om = '%06o' % m
202
perms = ''
203
204
3.times {
205
perms = ((m & 01) == 01 ? 'x' : '-') + perms
206
perms = ((m & 02) == 02 ? 'w' : '-') + perms
207
perms = ((m & 04) == 04 ? 'r' : '-') + perms
208
m >>= 3
209
}
210
211
return "#{om}/#{perms}"
212
end
213
214
#
215
# Return pretty information about a file.
216
#
217
def pretty
218
" Size: #{size} Blocks: #{blocks} IO Block: #{blksize} Type: #{rdev}\n"\
219
"Device: #{dev} Inode: #{ino} Links: #{nlink}\n"\
220
" Mode: #{prettymode}\n"\
221
" Uid: #{uid} Gid: #{gid}\n"\
222
"Access: #{atime}\n"\
223
"Modify: #{mtime}\n"\
224
"Change: #{ctime}\n"
225
end
226
227
end
228
end; end # Post/Rex
229
230