Skip to content

Commit

Permalink
Add log entries management
Browse files Browse the repository at this point in the history
  • Loading branch information
elg committed Jan 24, 2018
1 parent 21ca749 commit 6cf4221
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 38 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__
passhportd/config.pyc
*.pyc
6 changes: 3 additions & 3 deletions passhport/connections_utils/password.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ def reset(server, login, sshoptions, port, PWD_FILE_DIR):
user = login

# 3. Propage password (this command HAS to be launched as root)
os.system("ssh root@" + server + ' ' + sshoptions
+ ' -p ' + port + ' -l root \'echo "'
+ user + ':' + pwdstring + '" | chpasswd\'')
os.system("ssh root@" + server + ' ' + sshoptions + \
' -p ' + str(port) + ' -l root \'echo "' + \
user + ':' + pwdstring + '" | chpasswd\'')

# 4. Sore it locally
if not os.path.exists(PWD_FILE_DIR):
Expand Down
72 changes: 55 additions & 17 deletions passhport/passhport
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,26 @@ def get(url):
return 1


def post(url, data):
"""Send the POST request to the server and print a result.
This is used to connect to passhportd, to log access"""
try:
if SSL:
print(data)
r = requests.post(url_passhport + url, data=data,
verify=SSL_CERTIFICAT)
else:
r = requests.post(url_passhport + url, data=data)

except requests.RequestException as e:
print("ERROR: " + str(e.message))
else:
if r.status_code == requests.codes.ok:
return r.text

return 1


def checkandconnect(indexed_target_list, choice, username, originalcmd,
scpcmd = False):
"""Check if the user have entered an accessible target
Expand All @@ -69,25 +89,43 @@ def checkandconnect(indexed_target_list, choice, username, originalcmd,
for possibility in item_list:
if choice == possibility.casefold():
if len(item_list) > 2:
target = item_list[2]
pathlog = SCRIPT_LOGS_PATH + "/" + target + "/"
isodate = datetime.now().isoformat().replace(":",""). \
replace("-","").split('.')[0]
filelog = pathlog + isodate + "-" + str(os.getpid()) + "-" + \
target + "-" + username
login = get(url_passhport + "target" + "/login/" +
item_list[1])
#target login is set at $email => login=username (without @...)
date = datetime.today().strftime('%Y/%m/%d')
targetname = item_list[1]
target = item_list[2]
login = get(url_passhport + "target" + "/login/" + \
targetname)
# If target login is set at $email =>
# we user login=username (without @...)
if login == "$email":
login = re.split("@", username)[0]
port = get(url_passhport + "target" + "/port/" +
item_list[1])
sshoptions = get(url_passhport + "target" + "/sshoptions/" + \
item_list[1])

login = re.split("@", username)[0]
pathlog = SCRIPT_LOGS_PATH + "/" + date + "/"
# Create a log directory for this target
if not os.path.exists(pathlog):
os.mkdir(pathlog)
if not os.path.isdir(pathlog):
os.makedirs(pathlog)
isodate = datetime.now().isoformat().replace(":",""). \
replace("-","").split('.')[0]
filename = isodate + "-PID" + \
str(os.getpid()) + "-" + targetname + "-" + \
login + "@" + target + "-" + username
filelog = pathlog + filename
port = get(url_passhport + "target" + "/port/" +
target)
sshoptions = get(url_passhport + "target" + \
"/sshoptions/" + targetname)

if scpcmd == False:
cmd = "ssh"
else:
cmd = originalcmd

data= {"connexiondate" : isodate,
"connexioncmd" : cmd,
"logfilepath" : pathlog,
"logfilename" : filename,
"user" : username,
"target" : targetname}
# Log the entry on the database
r = post("logentry/create", data)

# It's SCP if scpcmd is set, else ssh.
if scpcmd == True:
Expand Down
31 changes: 30 additions & 1 deletion passhportd/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,37 @@
from __future__ import unicode_literals

from app import db
from .models_mod import user, target, usergroup, targetgroup
from .models_mod import user, target, usergroup, targetgroup, logentry

###############################################################################
# Relations tables
###############################################################################
class Target_Log(db.Model):
"""Link between a connexion and a target"""
__tablename__ = "target_log"
target_id = db.Column(
db.Integer,
db.ForeignKey("target.id"),
primary_key=True)
logentry_id = db.Column(
db.Integer,
db.ForeignKey("logentry.id"),
primary_key=True)


class User_Log(db.Model):
"""Link between a connexion and a user"""
__tablename__ = "user_log"
user_id = db.Column(
db.Integer,
db.ForeignKey("user.id"),
primary_key=True)
logentry_id = db.Column(
db.Integer,
db.ForeignKey("logentry.id"),
primary_key=True)


class Target_User(db.Model):
"""TargetUser authorized access between users and targets
(not including groups).
Expand All @@ -24,6 +50,7 @@ class Target_User(db.Model):
db.ForeignKey("user.id"),
primary_key=True)


class Tg_admins(db.Model):
"""Users authorized to admin targetgroups"""
__tablename__ = "tg_admins"
Expand All @@ -36,6 +63,7 @@ class Tg_admins(db.Model):
db.ForeignKey("user.id"),
primary_key=True)


class Ug_admins(db.Model):
"""Users authorized to admin usergroups"""
__tablename__ = "ug_admins"
Expand All @@ -48,6 +76,7 @@ class Ug_admins(db.Model):
db.ForeignKey("user.id"),
primary_key=True)


class Group_User(db.Model):
"""Groupuser users in groups"""
__tablename__ = "group_user"
Expand Down
49 changes: 49 additions & 0 deletions passhportd/app/models_mod/logentry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# -*-coding:Utf-8 -*-

# Compatibility 2.7-3.4
from __future__ import absolute_import
from __future__ import unicode_literals

from app import app, db
from app.models_mod import target,usergroup,targetgroup,user

class Logentry(db.Model):
"""Logentry store connexion history for furture reference"""
__tablename__ = "logentry"
id = db.Column(db.Integer, primary_key=True)
connexiondate = db.Column(db.String(20), index=True, nullable=False)
connexioncmd = db.Column(db.String(200), index=True, nullable=False)
logfilepath = db.Column(db.String(200)) # Empty if archived or logrotated
logfilename = db.Column(db.String(200), nullable=False)

# Relations
target = db.relationship("Target", secondary="target_log")
user = db.relationship("User", secondary="user_log")

def __repr__(self):
"""Return main data of the Log entry as a string"""
output = []

output.append("Date : {}".format(self.connexiondate))
output.append("Command: {}".format(self.connexioncmd))
output.append("Logfile:" + self.logfilepath + self.logfilename)
output.append("User : {}".format(self.user[0].show_name()))
output.append("Target : {}".format(self.target[0].show_name()))
return "\n".join(output)


def simplejson(self):
"""Return a json of logentry infos"""
output = "{"
output = output + "\"Date\": \"" + format(self.connexiondate) + "\",\n"
output = output + "\"Command\": \"" + \
format(self.connexioncmd) + "\",\n"
output = output + "\"Logfile\": \"" + self.logfilepath + \
self.logfilename + "\",\n"
output = output + "\"User\": \"" + format(self.user[0].show_name()) + "\",\n"
output = output + "\"Target\": \"" + format(self.target[0].show_name()) + "\""
output = output + "}"

return output


38 changes: 31 additions & 7 deletions passhportd/app/models_mod/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from app import app, db
from app.models_mod import targetgroup
from flask import jsonify


class Target(db.Model):
Expand All @@ -14,18 +15,19 @@ class Target(db.Model):
"""
__tablename__ = "target"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(256), index=True, unique=True)
hostname = db.Column(db.String(120), index=True, nullable=False)
name = db.Column(db.String(256), index=True, unique=True)
hostname = db.Column(db.String(120), index=True, nullable=False)
servertype = db.Column(db.String(120), index=True, server_default="ssh")
login = db.Column(db.String(120), index=True)
port = db.Column(db.Integer, index=False)
login = db.Column(db.String(120), index=True)
port = db.Column(db.Integer, index=False)
sshoptions = db.Column(db.String(500), index=True)
comment = db.Column(db.String(500), index=True)
comment = db.Column(db.String(500), index=True)

# Relations
members = db.relationship("User", secondary="target_user")
gmembers = db.relationship("Usergroup", secondary="target_group")
members = db.relationship("User", secondary="target_user")
gmembers = db.relationship("Usergroup", secondary="target_group")
memberoftg = db.relationship("Targetgroup", secondary="tgroup_target")
logentries = db.relationship("Logentry", secondary="target_log")


def __repr__(self):
Expand Down Expand Up @@ -97,6 +99,28 @@ def memberof(self, obj):
ret = ret + m.name + ","
return ret[:-1] + "]"

# Log management
def addlogentry(self, logentry):
"""Add a reference on a connexion made on this target"""
self.logentries.append(logentry)
return self


def get_lastlog(self):
"""Return 500 last log entries as json"""
output = "{\n"
if len(self.logentries) < 1:
return "{}"

for i in range(0, 500):
if i >= len(self.logentries):
i = 500
else:
output = output + '"' + str(i) + '": ' + \
self.logentries[i].simplejson() + ",\n"

return output[:-2] + "\n}"


# User management
def is_member(self, user):
Expand Down
39 changes: 30 additions & 9 deletions passhportd/app/models_mod/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,19 @@ class User(db.Model):
"""User defines information for every adminsys using passhport"""
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True, nullable=False)
sshkey = db.Column(
db.String(500),
index=False,
unique=True,
nullable=False)
comment = db.Column(db.String(500), index=True)
name = db.Column(db.String(120),
index=True, unique=True, nullable=False)
sshkey = db.Column(db.String(500),
index=False, unique=True, nullable=False)
comment = db.Column(db.String(500), index=True)
superadmin = db.Column(db.Boolean, unique=False, default=False)


# Relations (in targetgroups)
targets = db.relationship("Target", secondary="target_user")
usergroups = db.relationship("Usergroup", secondary="group_user")
targets = db.relationship("Target", secondary="target_user")
usergroups = db.relationship("Usergroup", secondary="group_user")
targetgroups = db.relationship("Targetgroup", secondary="tgroup_user")
logentries = db.relationship("Logentry", secondary="user_log")
# Admins - can admin usergroups and targetgroups (add and remove users)
adminoftg = db.relationship("Targetgroup", secondary="tg_admins")
adminofug = db.relationship("Usergroup", secondary="ug_admins")
Expand Down Expand Up @@ -147,3 +146,25 @@ def memberof(self, obj):
def togglesuperadmin(self):
"""Change the superadmin flag"""
self.superadmin = not self.superadmin

# Log management
def addlogentry(self, logentry):
"""Add a reference on a connexion made on this target"""
self.logentries.append(logentry)
return self

def get_lastlog(self):
"""Return 500 last log entries as json"""
output = "{\n"
if len(self.logentries) < 1:
return "{}"

for i in range(0, 500):
if i >= len(self.logentries):
i = 500
else:
output = output + '"' + str(i) + '": ' + \
self.logentries[i].simplejson() + ",\n"

return output[:-2] + "\n}"

2 changes: 1 addition & 1 deletion passhportd/app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from __future__ import unicode_literals

from app import app
from .views_mod import user, target, usergroup, targetgroup
from .views_mod import user, target, usergroup, targetgroup, logentry


@app.route("/")
Expand Down
1 change: 1 addition & 0 deletions passhportd/app/views_mod/logentry/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import logentry
Loading

0 comments on commit 6cf4221

Please sign in to comment.