privacyidea / pam_python

Add two factor authentication to PAM via privacyIDEA
18 stars 18 forks source link

pam_python for python3? #26

Open henkela opened 2 years ago

henkela commented 2 years ago

Hi, are there any plans for migrating pam_python to python3?

plettich commented 2 years ago

Unfortunately the pam_python project still depends on Python 2, which, from a security perspective, isn't very ideal since Python 2 EOL'd in 2020: https://sourceforge.net/p/pam-python/tickets/5/ Since most distributions stopped shipping the pam_python library or are shipping the Python 2 version, we can not really recommend this plugin currently. We'll have to see where the development leads...

gregharvey commented 2 years ago

If you read that ticket, one of the last comments now is that you can compile pam_python to work with Python 3. The developer seems to have disappeared (no activity for 5 months) but the code is there. Still, forking the C module in LinOTP's repo might be a more robust and future-proof solution, as I'm now discovering - having gotten this working finally in Debian Buster - that this isn't going to work at all with Debian Bullseye in any simple way, since they've pulled most Python 2 support.

I'm now torn between compiling my own pam_python or porting the C-based module to privacyIDEA. I'm not sure which would be less painful, and in any case I'd have to compile the latter myself. This really is making implementation challenging. :-/

adamboutcher commented 2 years ago

@gregharvey Did you make any decisions? I'm wondering on deployment plants for CentOS8.

adamboutcher commented 2 years ago

I'm now torn between compiling my own pam_python or porting the C-based module to privacyIDEA. I'm not sure which would be less painful, and in any case I'd have to compile the latter myself. This really is making implementation challenging. :-/

FYI, I wrote a small API wrapper so the LinOTP-PAM module works with PrivacyIDEA.

<?php

$URL="https://PrivacyIDEA_URL/";
$API="validate/check";

if (!empty($_GET['user'])) {
  $USER=$_GET['user'];
} elseif (!empty($_POST['user'])) {
  $USER=$_POST['user'];
}

if (!empty($_GET['pass'])) {
  $PASS=$_GET['pass'];
} elseif (!empty($_POST['pass'])) {
  $PASS=$_POST['pass'];
}

$CH = curl_init();
$GET=$URL.$API."?user=".$USER."&pass=".$PASS;
curl_setopt($CH, CURLOPT_URL, $GET);
curl_setopt($CH, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($CH, CURLOPT_VERBOSE, 0);
$json=curl_exec($CH);
curl_close($CH);

# JSON! Jason! - Tidy the raw json into named array
$jason=json_decode($json, true);

switch (strtoupper($jason["result"]["authentication"])) {
  case "ACCEPT":
    echo ":-)";
    break;
  case "REJECT":
    echo ":-(";
    break;
  default:
    echo ":-/";
    break;
}
?>

Then set the PAM module to point at the wrapper

auth required /scratch/temp/pam_linotp.so url=https://webserver/linotp_compat.php hide_otp_input

I recommend running this wrapper on the same system as your PrivacyIDEA as this is effectively MITM your OTP system, but as they're just a ONE TIME password, it isn't open to replay attacks. You could however fool the PAM module into a successful/OK result. You have been warned.

ksyblast commented 1 year ago

We are also looking for the best solution for ssh, @gregharvey could you please share your plans? @adamboutcher are you satisfied with your solution and linotp-pam? We are trying some scenarios with pam radius but the solution looks a bit complicated.

adamboutcher commented 1 year ago

@ksyblast personally I don't like it but it worked in principle, it just "feels" a bit too simple for auth but I could be over complicating things 😂