Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Add rhost to the history item to record IP address of the client
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Lux committed Aug 11, 2020
1 parent 752fa3d commit c8af269
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions privacyidea_pam.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class Authenticator(object):
def __init__(self, pamh, config):
self.pamh = pamh
self.user = pamh.get_user(None)
self.rhost = pamh.rhost
self.URL = config.get("url", "https://localhost")
self.sslverify = not config.get("nosslverify", False)
cacerts = config.get("cacerts")
Expand Down Expand Up @@ -208,7 +209,7 @@ def authenticate(self, password):
self.pamh.conversation(pam_message)

# Save history
save_history_item(self.sqlfile, self.user, serial, (True if rval == self.pamh.PAM_SUCCESS else False))
save_history_item(self.sqlfile, self.user, self.rhost, serial, (True if rval == self.pamh.PAM_SUCCESS else False))
return rval

def challenge_response(self, transaction_id, message, attributes):
Expand Down Expand Up @@ -318,7 +319,7 @@ def pam_sm_authenticate(pamh, flags, argv):
config = _get_config(argv)
debug = config.get("debug")
try_first_pass = config.get("try_first_pass")
prompt = config.get("prompt", "Your OTP")
prompt = config.get("prompt", "Your OTP").replace("_", " ")
grace_time = config.get("grace")
if prompt[-1] != ":":
prompt += ":"
Expand Down Expand Up @@ -434,7 +435,7 @@ def check_offline_otp(user, otp, sqlfile, window=10, refill=True):
return res, matching_serial


def save_auth_item(sqlfile, user, serial, tokentype, authitem):
def save_auth_item(sqlfile, user, rhost, serial, tokentype, authitem):
"""
Save the given authitem to the sqlite file to be used later for offline
authentication.
Expand All @@ -446,6 +447,7 @@ def save_auth_item(sqlfile, user, serial, tokentype, authitem):
:param sqlfile: An SQLite file. If it does not exist, it will be generated.
:type sqlfile: basestring
:param user: The PAM user
:param rhost: The PAM user rhost value
:param serial: The serial number of the token
:param tokentype: The type of the token
:param authitem: A dictionary with all authitem information being:
Expand Down Expand Up @@ -485,7 +487,7 @@ def save_auth_item(sqlfile, user, serial, tokentype, authitem):
# Just be sure any changes have been committed or they will be lost.
conn.close()

def check_last_history(sqlfile, user, grace_time, window=10):
def check_last_history(sqlfile, user, rhost, grace_time, window=10):
"""
Get the last event for this user.
Expand All @@ -495,6 +497,7 @@ def check_last_history(sqlfile, user, grace_time, window=10):
:param sqlfile: An SQLite file. If it does not exist, it will be generated.
:type sqlfile: basestring
:param user: The PAM user
:param rhost: The PAM user rhost value
:param serial: The serial number of the token
:param success: Boolean
Expand All @@ -508,15 +511,15 @@ def check_last_history(sqlfile, user, grace_time, window=10):
res = False
events = []

for row in c.execute("SELECT user, serial, last_success, last_error FROM history "
"WHERE user=? ORDER by last_success "
for row in c.execute("SELECT user, rhost, serial, last_success, last_error FROM history "
"WHERE user=? AND rhost=? ORDER by last_success "
"LIMIT ?",
(user, window)):
(user, rhost, window)):
events.append(row)

if len(events)>0:
for event in events:
last_success = event[2]
last_success = event[3]
if last_success is not None:
# Get the elapsed time in minutes since last success
last_success_delta = datetime.datetime.now() - last_success
Expand All @@ -540,7 +543,7 @@ def check_last_history(sqlfile, user, grace_time, window=10):
return res


def save_history_item(sqlfile, user, serial, success):
def save_history_item(sqlfile, user, rhost, serial, success):
"""
Save the given success/error event.
Expand All @@ -550,6 +553,7 @@ def save_history_item(sqlfile, user, serial, success):
:param sqlfile: An SQLite file. If it does not exist, it will be generated.
:type sqlfile: basestring
:param user: The PAM user
:param rhost: The PAM user rhost value
:param serial: The serial number of the token
:param success: Boolean
Expand All @@ -564,21 +568,21 @@ def save_history_item(sqlfile, user, serial, success):
__name__, ("success" if success else "error")))
if success:
# Insert the Event
c.execute("INSERT OR REPLACE INTO history (user, serial,"
"error_counter, last_success) VALUES (?,?,?,?)",
(user, serial, 0, datetime.datetime.now()))
c.execute("INSERT OR REPLACE INTO history (user, rhost, serial,"
"error_counter, last_success) VALUES (?,?,?,?,?)",
(user, rhost, serial, 0, datetime.datetime.now()))
else:
# Insert the Event
c.execute("UPDATE history SET error_counter = error_counter + 1, "
" serial = ? , last_error = ? "
" WHERE user = ? ",
(serial, datetime.datetime.now(), user))
" WHERE user = ? AND rhost = ? ",
(serial, datetime.datetime.now(), user, rhost))

syslog.syslog(syslog.LOG_DEBUG,"Rows affected : %d " % c.rowcount)
if c.rowcount == 0:
c.execute("INSERT INTO history (user, serial,"
"error_counter, last_error) VALUES (?,?,?,?)",
(user, serial, 1, datetime.datetime.now()))
c.execute("INSERT INTO history (user, rhost, serial,"
"error_counter, last_error) VALUES (?,?,?,?,?)",
(user, rhost, serial, 1, datetime.datetime.now()))


# Save (commit) the changes
Expand Down Expand Up @@ -610,7 +614,7 @@ def _create_table(c):
try:
# create history table
c.execute("CREATE TABLE IF NOT EXISTS history "
"(user text, serial text, error_counter int, "
"(user text, rhost text, serial text, error_counter int, "
"last_success timestamp, last_error timestamp)")
c.execute("CREATE UNIQUE INDEX idx_user "
"ON history (user);")
Expand Down

0 comments on commit c8af269

Please sign in to comment.