Moved filesystem related commands to kippo/commands/fs.py

git-svn-id: https://kippo.googlecode.com/svn/trunk@160 951d7100-d841-11de-b865-b3884708a8e2
This commit is contained in:
desaster
2010-07-13 17:06:32 +00:00
parent eb708a2f08
commit d089b564b6
3 changed files with 273 additions and 262 deletions

View File

@@ -12,4 +12,5 @@ __all__ = [
'dice', 'dice',
'adduser', 'adduser',
'last', 'last',
'fs',
] ]

View File

@@ -1,10 +1,8 @@
# Copyright (c) 2009 Upi Tamminen <desaster@gmail.com> # Copyright (c) 2009 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information # See the COPYRIGHT file for more information
import os, time, anydbm, datetime, getopt import os, time, anydbm, datetime
from copy import deepcopy, copy
from kippo.core.honeypot import HoneyPotCommand from kippo.core.honeypot import HoneyPotCommand
from kippo.core.fs import *
from twisted.internet import reactor from twisted.internet import reactor
from kippo.core.config import config from kippo.core.config import config
@@ -15,241 +13,6 @@ class command_whoami(HoneyPotCommand):
self.writeln(self.honeypot.user.username) self.writeln(self.honeypot.user.username)
commands['/usr/bin/whoami'] = command_whoami commands['/usr/bin/whoami'] = command_whoami
class command_cat(HoneyPotCommand):
def call(self):
for arg in self.args:
path = self.fs.resolve_path(arg, self.honeypot.cwd)
if not path or not self.fs.exists(path):
self.writeln('bash: cat: %s: No such file or directory' % arg)
return
f = self.fs.getfile(path)
realfile = self.fs.realfile(f, '%s/%s' % \
(self.honeypot.env.cfg.get('honeypot', 'contents_path'), path))
if realfile:
f = file(realfile, 'rb')
self.write(f.read())
f.close()
commands['/bin/cat'] = command_cat
class command_cd(HoneyPotCommand):
def call(self):
if not self.args:
path = '/root'
else:
path = self.args[0]
try:
newpath = self.fs.resolve_path(path, self.honeypot.cwd)
newdir = self.fs.get_path(newpath)
except IndexError:
newdir = None
if newdir is None:
self.writeln('bash: cd: %s: No such file or directory' % path)
return
if not self.fs.is_dir(newpath):
self.writeln('-bash: cd: %s: Not a directory' % path)
return
self.honeypot.cwd = newpath
commands['cd'] = command_cd
class command_rm(HoneyPotCommand):
def call(self):
recursive = False
for f in self.args:
if f.startswith('-') and 'r' in f:
recursive = True
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
self.writeln(
'rm: cannot remove `%s\': No such file or directory' % f)
continue
basename = path.split('/')[-1]
contents = [x for x in dir]
for i in dir[:]:
if i[A_NAME] == basename:
if i[A_TYPE] == T_DIR and not recursive:
self.writeln(
'rm: cannot remove `%s\': Is a directory' % \
i[A_NAME])
else:
dir.remove(i)
commands['/bin/rm'] = command_rm
class command_cp(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("cp: missing file operand")
self.writeln("Try `cp --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args,
'-abdfiHlLPpRrsStTuvx')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
return
recursive = False
for opt in optlist:
if opt[0] in ('-r', '-a', '-R'):
recursive = True
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("cp: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `cp --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("cp: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
not recursive:
self.writeln(
"cp: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("cp: cannot create regular file " + \
"`%s': No such file or directory" % (dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"cp: cannot stat `%s': No such file or directory" % (src,))
continue
if not recursive and self.fs.is_dir(resolv(src)):
self.writeln("cp: omitting directory `%s'" % (src,))
continue
s = deepcopy(self.fs.getfile(resolv(src)))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest.rstrip('/'))
if outfile in [x[A_NAME] for x in dir]:
dir.remove([x for x in dir if x[A_NAME] == outfile][0])
s[A_NAME] = outfile
dir.append(s)
commands['/bin/cp'] = command_cp
class command_mv(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("mv: missing file operand")
self.writeln("Try `mv --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args, '-bfiStTuv')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
self.exit()
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("mv: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `mv --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("mv: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
len(sources) != 1:
self.writeln(
"mv: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("mv: cannot create regular file " + \
"`%s': No such file or directory" % \
(dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"mv: cannot stat `%s': No such file or directory" % \
(src,))
continue
s = self.fs.getfile(resolv(src))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest)
if dir != os.path.dirname(resolv(src)):
s[A_NAME] = outfile
dir.append(s)
sdir = self.fs.get_path(os.path.dirname(resolv(src)))
sdir.remove(s)
else:
s[A_NAME] = outfile
commands['/bin/mv'] = command_mv
class command_mkdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if self.fs.exists(path):
self.writeln(
'mkdir: cannot create directory `%s\': File exists' % f)
return
ok = self.fs.mkdir(path, 0, 0, 4096, 16877)
if not ok:
self.writeln(
'mkdir: cannot create directory `%s\': ' % f + \
'No such file or directory')
return
commands['/bin/mkdir'] = command_mkdir
class command_rmdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if len(self.fs.get_path(path)):
self.writeln(
'rmdir: failed to remove `%s\': Directory not empty' % f)
continue
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
dir = None
if not dir or f not in [x[A_NAME] for x in dir]:
self.writeln(
'rmdir: failed to remove `%s\': ' % f + \
'No such file or directory')
continue
for i in dir[:]:
if i[A_NAME] == f:
dir.remove(i)
commands['/bin/rmdir'] = command_rmdir
class command_uptime(HoneyPotCommand): class command_uptime(HoneyPotCommand):
def call(self): def call(self):
self.writeln(' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \ self.writeln(' %s up 14 days, 3:53, 0 users, load average: 0.08, 0.02, 0.01' % \
@@ -361,11 +124,6 @@ class command_id(HoneyPotCommand):
self.writeln('uid=0(root) gid=0(root) groups=0(root)') self.writeln('uid=0(root) gid=0(root) groups=0(root)')
commands['/usr/bin/id'] = command_id commands['/usr/bin/id'] = command_id
class command_pwd(HoneyPotCommand):
def call(self):
self.writeln(self.honeypot.cwd)
commands['/bin/pwd'] = command_pwd
class command_passwd(HoneyPotCommand): class command_passwd(HoneyPotCommand):
def start(self): def start(self):
self.write('Enter new UNIX password: ') self.write('Enter new UNIX password: ')
@@ -422,25 +180,6 @@ class command_history(HoneyPotCommand):
count += 1 count += 1
commands['history'] = command_history commands['history'] = command_history
class command_touch(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln('touch: missing file operand')
self.writeln('Try `touch --help\' for more information.')
return
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if not self.fs.exists(os.path.dirname(path)):
self.writeln(
'touch: cannot touch `%s`: no such file or directory' % \
(path))
return
if self.fs.exists(path):
# FIXME: modify the timestamp here
continue
self.fs.mkfile(path, 0, 0, 0, 33188)
commands['/bin/touch'] = command_touch
class command_date(HoneyPotCommand): class command_date(HoneyPotCommand):
def call(self): def call(self):
time = datetime.datetime.utcnow(); time = datetime.datetime.utcnow();

271
kippo/commands/fs.py Normal file
View File

@@ -0,0 +1,271 @@
# Copyright (c) 2010 Upi Tamminen <desaster@gmail.com>
# See the COPYRIGHT file for more information
import os, getopt
from copy import deepcopy, copy
from kippo.core.honeypot import HoneyPotCommand
from kippo.core.fs import *
from twisted.internet import reactor
commands = {}
class command_cat(HoneyPotCommand):
def call(self):
for arg in self.args:
path = self.fs.resolve_path(arg, self.honeypot.cwd)
if not path or not self.fs.exists(path):
self.writeln('bash: cat: %s: No such file or directory' % arg)
return
f = self.fs.getfile(path)
realfile = self.fs.realfile(f, '%s/%s' % \
(self.honeypot.env.cfg.get('honeypot', 'contents_path'), path))
if realfile:
f = file(realfile, 'rb')
self.write(f.read())
f.close()
commands['/bin/cat'] = command_cat
class command_cd(HoneyPotCommand):
def call(self):
if not self.args:
path = '/root'
else:
path = self.args[0]
try:
newpath = self.fs.resolve_path(path, self.honeypot.cwd)
newdir = self.fs.get_path(newpath)
except IndexError:
newdir = None
if newdir is None:
self.writeln('bash: cd: %s: No such file or directory' % path)
return
if not self.fs.is_dir(newpath):
self.writeln('-bash: cd: %s: Not a directory' % path)
return
self.honeypot.cwd = newpath
commands['cd'] = command_cd
class command_rm(HoneyPotCommand):
def call(self):
recursive = False
for f in self.args:
if f.startswith('-') and 'r' in f:
recursive = True
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
self.writeln(
'rm: cannot remove `%s\': No such file or directory' % f)
continue
basename = path.split('/')[-1]
contents = [x for x in dir]
for i in dir[:]:
if i[A_NAME] == basename:
if i[A_TYPE] == T_DIR and not recursive:
self.writeln(
'rm: cannot remove `%s\': Is a directory' % \
i[A_NAME])
else:
dir.remove(i)
commands['/bin/rm'] = command_rm
class command_cp(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("cp: missing file operand")
self.writeln("Try `cp --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args,
'-abdfiHlLPpRrsStTuvx')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
return
recursive = False
for opt in optlist:
if opt[0] in ('-r', '-a', '-R'):
recursive = True
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("cp: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `cp --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("cp: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
not recursive:
self.writeln(
"cp: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("cp: cannot create regular file " + \
"`%s': No such file or directory" % (dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"cp: cannot stat `%s': No such file or directory" % (src,))
continue
if not recursive and self.fs.is_dir(resolv(src)):
self.writeln("cp: omitting directory `%s'" % (src,))
continue
s = deepcopy(self.fs.getfile(resolv(src)))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest.rstrip('/'))
if outfile in [x[A_NAME] for x in dir]:
dir.remove([x for x in dir if x[A_NAME] == outfile][0])
s[A_NAME] = outfile
dir.append(s)
commands['/bin/cp'] = command_cp
class command_mv(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln("mv: missing file operand")
self.writeln("Try `mv --help' for more information.")
return
try:
optlist, args = getopt.gnu_getopt(self.args, '-bfiStTuv')
except getopt.GetoptError, err:
self.writeln('Unrecognized option')
self.exit()
def resolv(path):
return self.fs.resolve_path(path, self.honeypot.cwd)
if len(args) < 2:
self.writeln("mv: missing destination file operand after `%s'" % \
(self.args[0],))
self.writeln("Try `mv --help' for more information.")
return
sources, dest = args[:-1], args[-1]
if len(sources) > 1 and not self.fs.is_dir(resolv(dest)):
self.writeln("mv: target `%s' is not a directory" % (dest,))
return
if dest[-1] == '/' and not self.fs.exists(resolv(dest)) and \
len(sources) != 1:
self.writeln(
"mv: cannot create regular file `%s': Is a directory" % \
(dest,))
return
if self.fs.is_dir(resolv(dest)):
is_dir = True
else:
is_dir = False
parent = os.path.dirname(resolv(dest))
if not self.fs.exists(parent):
self.writeln("mv: cannot create regular file " + \
"`%s': No such file or directory" % \
(dest,))
return
for src in sources:
if not self.fs.exists(resolv(src)):
self.writeln(
"mv: cannot stat `%s': No such file or directory" % \
(src,))
continue
s = self.fs.getfile(resolv(src))
if is_dir:
dir = self.fs.get_path(resolv(dest))
outfile = os.path.basename(src)
else:
dir = self.fs.get_path(os.path.dirname(resolv(dest)))
outfile = os.path.basename(dest)
if dir != os.path.dirname(resolv(src)):
s[A_NAME] = outfile
dir.append(s)
sdir = self.fs.get_path(os.path.dirname(resolv(src)))
sdir.remove(s)
else:
s[A_NAME] = outfile
commands['/bin/mv'] = command_mv
class command_mkdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if self.fs.exists(path):
self.writeln(
'mkdir: cannot create directory `%s\': File exists' % f)
return
ok = self.fs.mkdir(path, 0, 0, 4096, 16877)
if not ok:
self.writeln(
'mkdir: cannot create directory `%s\': ' % f + \
'No such file or directory')
return
commands['/bin/mkdir'] = command_mkdir
class command_rmdir(HoneyPotCommand):
def call(self):
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if len(self.fs.get_path(path)):
self.writeln(
'rmdir: failed to remove `%s\': Directory not empty' % f)
continue
try:
dir = self.fs.get_path('/'.join(path.split('/')[:-1]))
except IndexError:
dir = None
if not dir or f not in [x[A_NAME] for x in dir]:
self.writeln(
'rmdir: failed to remove `%s\': ' % f + \
'No such file or directory')
continue
for i in dir[:]:
if i[A_NAME] == f:
dir.remove(i)
commands['/bin/rmdir'] = command_rmdir
class command_pwd(HoneyPotCommand):
def call(self):
self.writeln(self.honeypot.cwd)
commands['/bin/pwd'] = command_pwd
class command_touch(HoneyPotCommand):
def call(self):
if not len(self.args):
self.writeln('touch: missing file operand')
self.writeln('Try `touch --help\' for more information.')
return
for f in self.args:
path = self.fs.resolve_path(f, self.honeypot.cwd)
if not self.fs.exists(os.path.dirname(path)):
self.writeln(
'touch: cannot touch `%s`: no such file or directory' % \
(path))
return
if self.fs.exists(path):
# FIXME: modify the timestamp here
continue
self.fs.mkfile(path, 0, 0, 0, 33188)
commands['/bin/touch'] = command_touch
# vim: set sw=4 et: