leonardomarino / duo_auth

Roundcube webmail plugin that enables Duo Security Two Factor Authentication
3 stars 4 forks source link

Get compatible with Duo Web v4 SDK #4

Closed paderijk closed 1 year ago

paderijk commented 2 years ago

Looks like as of Feb 28th a new Web SDK became available. Probably the app needs to be modified to be compatible.

https://duo.com/docs/duoweb and https://duo.com/docs/universal-prompt-update-guide

danmarinoj commented 1 year ago

@paderijk here is an attempt at this: https://github.com/leonardomarino/duo_auth/pull/5 I'm new to php and this doesn't work yet

Abhijit-81 commented 1 year ago

@leonardomarino I am trying to test this 2FA plugin with Roundcube 1.4.13, I have configured Client ID, Client secret, API hostname in duo admin panel, and modified config.inc.php as per readme, but unable to get duo login screen after entering the password, in roundcube logs following warning is showing

PHP Warning: Invalid argument supplied for foreach() in /../../plugins/duo_auth/duo_auth.php on line 64

PHP Warning: in_array() expects parameter 2 to be array, null given in /../../plugins/duo_auth/duo_auth.php on line 57

My php version is PHP 7.4.3

Can you please suggest some solution regarding this.

leonardomarino commented 1 year ago

Hi @Abhijit-81 did you install the plugin using composer? if not, I highly recommend that you do so because there are dependencies that will be installed using composer.

Please run the commands as follows in your Roundcube installation directory:

Run $ composer require duosecurity/duo_api_php dev-master

Run $ composer require "lmr/duo_auth:>=1.0.7"

Run $ composer dumpautoload -o

Run cd plugins/duo_auth/

Run ln -s ../../vendor/duosecurity/duo_api_php/src/* .

And finally edit the config.inc.php file to reflect your DUO values. If you are having issues please send the output of each command so I can diagnose issues better. Another question, you are running older versions of Roundcube and PHP, any particular reason?

Abhijit-81 commented 1 year ago

Hello Sir,

         I have used composer only to install the plugin, there was no such error at the time of installation, and I have followed all the steps as mentioned, but still getting no authentication page of duo , is there any other steps need to be done from duo end for authentication apart from client id, secret key etc.., and is there is any specific protection type need to be used from duo site for authentication of this plugin, kindly advice.

Regarding version of php and roundcube there is no specific reason or dependency, I am also in process for up gradation.

Abhijit-81 commented 1 year ago

Hello Sir,

      I have used composer only to install the plugin, there was no 

such error at the time of installation, and I have followed all the steps as mentioned, but still getting no authentication page of duo , is there any other steps need to be done from duo end for authentication apart from client id, secret key etc.., and is there is any specific protection type need to be used from duo site for authentication of this plugin, kindly advice.

Regarding version of php and roundcube there is no specific reason or dependency, I am also in process for up gradation.

On 2022-12-09 20:05, Leonardo Marino-Ramirez wrote:

Hi @Abhijit-81 [1] did you install the plugin using composer? if not, I highly recommend that you do so because there are dependencies that will be installed using composer.

Please run the commands as follows in your Roundcube installation directory:

Run $ composer require duosecurity/duo_api_php dev-master

Run $ composer require "lmr/duo_auth:>=1.0.7"

Run $ composer dumpautoload -o

Run cd plugins/duo_auth/

Run ln -s ../../vendor/duosecurity/duo_api_php/src/* .

And finally edit the config.inc.php file to reflect your DUO values. If you are having issues please send the output of each command so I can diagnose issues better. Another question, you are running older versions of Roundcube and PHP, any particular reason?

-- Reply to this email directly, view it on GitHub [2], or unsubscribe [3]. You are receiving this because you were mentioned.Message ID: @.***>

Links:

[1] https://github.com/Abhijit-81 [2] https://github.com/leonardomarino/duo_auth/issues/4#issuecomment-1344383051 [3] https://github.com/notifications/unsubscribe-auth/APKRNTOXAGC2KBVQFF4NAQDWMM7RLANCNFSM5SCCYZ6Q

Abhijit-81 commented 1 year ago

Any update on this?

leonardomarino commented 1 year ago

@Abhijit-81 I just tested the plugin with a fresh Roundcube install (https://github.com/roundcube/roundcubemail/releases/download/1.6.0/roundcubemail-1.6.0-complete.tar.gz). Briefly, after installing on the Web root directory I did:

sudo -u www-data php7.4 /usr/local/bin/composer --ignore-platform-req=ext-ldap update

sudo -u www-data php7.4 /usr/local/bin/composer --ignore-platform-req=ext-ldap require duosecurity/duo_api_php dev-master

sudo -u www-data php7.4 /usr/local/bin/composer --ignore-platform-req=ext-ldap require "lmr/duo_auth:>=1.0.7"

cd plugins/duo_auth/

ln -s ../../vendor/duosecurity/duo_api_php/src/* .

Edit your config.inc.php file

And make sure your Roundcube config/config.inc.php file has the proper configuration. You should be good to go.

Pavlo-Lyha commented 1 year ago

Hello everyone. Currently I have already finished write and tested for me PHP plugin for new library Duo WEB v4 SDK for RoundCube v1.6.1 and PHP 8.0-8.2. I am have deployment RoundCube for Windows installation and plugin fully tested for my environment. If more interested everyone I can share code. This is first version code and some moments not fully optimisation, but fully still work )) Any idea for better solution code would be glad see.

leonardomarino commented 1 year ago

Great news Pavlo!!! Please do share the code so I can test it in my environment.

Best, Leonardo

On June 1, 2023 8:05:31 AM EDT, Pavlo-Lyha @.***> wrote:

Hello everyone. Currently I have already finished write and tested for me PHP plugin for new library Duo WEB v4 SDK for RoundCube v1.6.1 and PHP 8.0-8.2. I am have deployment RoundCube for Windows installation and plugin fully tested for my environment. If more interested everyone I can share code. This is first version code and some moments not fully optimisation, but fully still work )) Any idea for better solution code would be glad see.

-- Reply to this email directly or view it on GitHub: https://github.com/leonardomarino/duo_auth/issues/4#issuecomment-1571928312 You are receiving this because you were mentioned.

Message ID: @.***>

Pavlo-Lyha commented 1 year ago

Hello, Leonardo.

duo_sdk.zip

  1. Install DUO WEB v4 SDK from composer inside your Roundcube instance: https://github.com/duosecurity/duo_universal_php. It's official PHP library from DUO for OIDC.
  2. In DUO Admin Panel create new WEB SDK application and activate inside this application universe prompt;
  3. Create new named folder "duo_sdk" inside Roundcube "plugins" folder;
  4. Copy next file's from archive to "duo_sdk" folder: composer.json, duo_sdk.php and duo.conf;
  5. Other 3 file's from archive copy to root folder Roundcube installation (there Roundcube index.php file placed);
  6. Open "duo.conf" file and insert your DUO SDK APP value to corresponding key's, generate any your own redirect page name and write value to redirect_uri key, example: https://test.com/redirect. REQUIRE: only https.
  7. Rename file "your_page_name_redirect" to your name from previously step.
  8. Inside your redirect page indicate your session name in session_name("your_session_name"); by default Roundcube it's "roundcube_sessid";
Pavlo-Lyha commented 1 year ago
  1. Of course, you must activate plug-in “duo_sdk” in Roundcube conf file in plugin section ))
leonardomarino commented 1 year ago

Thanks so much for all your work @Pavlo-Lyha !!! I am testing under linux and the authentication part works fine, but after referring to "your_page_name_redirect" and making a change for session_name("roundcube_sessid"), I am getting back the php code instead of the login.

Pavlo-Lyha commented 1 year ago

Hello, Leonardo.

After DUO authentication you saw php code from redirect page? If yes, then it's your CGI web-server don't handler PHP code because redirect page not have extension .php. Your web-server have configuration for CGI only for .php extension. In this situation web-server handler this code as simple text block and encapsulate to html container.

Therefor:

  1. You must rename redirect page with .php extension, for example https://example.com/redirect.php and don't forget change key redirect_uri in duo.conf file;
  2. You must in web-server "CGI handler" your redirect page file name without .php extension exactly handler by your php cgi instance.
Pavlo-Lyha commented 1 year ago

Also this script have some advantage for flexible or enterprise control access but this function's implicitly:

  1. In "duo.conf" file key "failmode" control handler behavior if Duo Service is unavailable (function check_service inside main script "duo_sdk.php"). If DUO Service is unavailable and failmode is equal value "closed" - script redirect to main login page Roundcube service and generate PHP instance error log (not Roundcube instance error log) for Duo service unavailable. If Duo Service is unavailable and failmode equal value "open" - Roundcube service redirect to user mailbox page, if Roundcube authentication was success and bypass Duo service authentication. Don't forget - add corresponding value key in "duo.conf" file and corresponding value variable in "duo_sdk.php" file in section check_service handler.
  2. If Duo service still online and available - always work 2FA mechanism.
  3. Also you can still control bypass mechanism from Duo service by add user config bypass for you Duo APP in your Duo Admin Panel Application.
  4. Script support http proxy mode for enterprise internet access solution’s.

Therefor I don't add some advantage in script - local user bypass (see above how release this function on currently script and Duo service) and IP Address/IP Subnet bypass mechanism. For my Roundcube service this function's don't needed. But it's not problem add this function to script for universal state. If It's needed I take do it this.

Also In current version script generate only PHP instance error log, not Roundcube instance error log and not generate any message error for user interface. But it's not problem add this function to script for universal state. If It's needed I take do it this.

Me need also your any ideas for user experience for script still was better and have universal state for any deployment scenario's.

On currently this script execute only main function - 2FA authentication, block access while second factor not take, generate error for PHP admin.

Therefore I say this plugin not ideal, but work. For ideal state - me need some time and your idea's for release ))

leonardomarino commented 1 year ago

Hi @Pavlo-Lyha I forgot to add the .php extension. Now after accepting the DUO prompt and authenticating I am getting to the root directory of the Website. I think the issue is in the header function: header("Location: /"); of the redirect script.

I have the mail application in a subdirectory and for some reason I am redirected to the Web root instead of the roundcube root directory.

I think that it is important to add a section where admin users can perform a local user bypass directly on the duo.conf file as it is currently implemented. See: https://github.com/leonardomarino/duo_auth/blob/master/duo_auth.php and https://github.com/leonardomarino/duo_auth/blob/master/config.inc.php.dist That particular functionality was done using: duosecurity/duo_api_php (https://github.com/duosecurity/duo_api_php) Thanks so much for putting your time and effort to upgrade this plugin.

Pavlo-Lyha commented 1 year ago

Hi @Pavlo-Lyha I forgot to add the .php extension. Now after accepting the DUO prompt and authenticating I am getting to the root directory of the Website. I think the issue is in the header function: header("Location: /"); of the redirect script.

I have the mail application in a subdirectory and for some reason I am redirected to the Web root instead of the roundcube root directory.

Hello, Leonardo.

Yes, sure, but:

If your web application have subdirectory location instead root location you must indicate your absolutely fully path to you web application in http header inside function after /, for example header ("Location: /webmail/?_task=mail") if your web application location in subdirectory "webmail" inside root web-server directory or you can indicate fully FQDN URI path to you application inside header: header ("Location: https://example.com/webmail/?_task=mail"). I have my web application in root directory web-server, therefor I am indicate simple "/?_task=mail" - what meaning redirect to $_server_host URI with root directory and have valid user session and user cookies )) Configuration this parameter depends only from your own web application deployment scenario ))

In your case header function: header("Location: /") - it's function for case if DUO authentication token for any reason not success and user session in this case are destroyed and redirect to login page. In my case it's root directory. In case with subdirectory - it's must be absolutely fully path to you web application where index.php file location if handled by default, for example /webmail or indicate fully FQDN URI path - /webmail/index.php or https://example.com/webmail/index.php

If you repair this parameter for your web app deployment - you must get working application )) Sure, it's possible released through php variable, but I think would be change path manual simpler.

Also in redirect page code verify path to lib file's in "require" section - maybe you have not valid path.

Also check you have inserted cookies parameter "_duoauth" in your valid session. If you not have this array your session also destroyed and redirect to login page - "/". I think your issue same take this case.

Check in your Roundcube config file have next section:

// Session name. Default: 'roundcube_sessid' $config['session_name'] = 'your_session_name';

If yes, name must be identical in redirect page code in session_name("your_session_name"); If no, by default value must be 'roundcube_sessid'

I think that it is important to add a section where admin users can perform a local user bypass directly on the duo.conf file as it is currently implemented. See: https://github.com/leonardomarino/duo_auth/blob/master/duo_auth.php and https://github.com/leonardomarino/duo_auth/blob/master/config.inc.php.dist That particular functionality was done using: duosecurity/duo_api_php (https://github.com/duosecurity/duo_api_php) Thanks so much for putting your time and effort to upgrade this plugin.

Ok. I am do it this later.

Thanks.

leonardomarino commented 1 year ago

@Pavlo-Lyha could we do a quick video call so I can show you what is happening in my test environment? I am running debian, php7.4 and apache. Please let me now a convenient time. Leonardo

Pavlo-Lyha commented 1 year ago

Hello Leonardo,

Oh... Sorry, sorry mate, but I forgot one important item: by default Roundcube storage user session in database. You must change this config parameter in Roundcube config file and switch storage session from db to php local file. Current version release script don't use DB connection. And additional in php config file you need indicate path to storage local file session - only path; php by default generate session id and this session id will be named local file session.

Therefore script don't write additional information to user session and you have not correct redirect.

Sorry again... ((

Roundcube config file (config.inc.php):

// Backend to use for session storage. Can either be 'db' (default), 'redis', 'memcache', or 'php' // // If set to 'memcache' or 'memcached', a list of servers need to be specified in 'memcache_hosts' // Make sure the Memcache extension (https://pecl.php.net/package/memcache) version >= 2.0.0 // or the Memcached extension (https://pecl.php.net/package/memcached) version >= 2.0.0 is installed. // // If set to 'redis', a server needs to be specified in 'redis_hosts' // Make sure the Redis extension (https://pecl.php.net/package/redis) version >= 2.0.0 is installed. // // Setting this value to 'php' will use the default session save handler configured in PHP $config['session_storage'] = 'php';

PHP config file (php.ini): session.save_handler = files session.save_path = "path_folder"

Yes, sure. If needed we can organise call.

leonardomarino commented 1 year ago

Hi @Pavlo-Lyha, that did the trick and now I am able to have a functional plugin in my environment and I can confirm that this is compatible with php 7.4. We can document the php changes later but I think that the local user bypass is important here. Thanks again, great work!!!

Pavlo-Lyha commented 1 year ago

I glad hear that ))

Also for reminder: script fully compatible for all latest PHP and Roundcube versions.

Ok. I am trying to modify script under weekends finish. I am update post after.

Pavlo-Lyha commented 1 year ago

duo_sdk.zip

In a new attachment I am update plugin and add local username and ip address/subnet bypass - updated next file's: duo.conf and duo_sdk.php. This file's need replace from new archive for update version plugin. In duo.conf file need add value to corresponding section's for activate corresponding local bypass mechanism's.

leonardomarino commented 1 year ago

Thanks again @Pavlo-Lyha!!! things are working fine and the local bypass mechanism is a great addition. The next step is to do a public release so others can test the plugin in their environment. Roundcube plugins are managed by composer https://plugins.roundcube.net/ Could we work together to make the new duo_sdk plugin installable by composer? I can also confirm that the plugin is compatible with php 7.4

Pavlo-Lyha commented 1 year ago

Yes, sure. It's not problem: need simple describe dependency meta-data in composer file in json, publish project to repository, and add README file with instruction, describe project on git. In fact I am update composer.json and hes already have all necessary information for dependency install and install plugin. Only need publish plugin to repository and describe project and make README file with deployment instruction. I can make new packet and new publish project as separate project from this? Or we can make continue next version this project plugin? If continue, in composer.json need change some key's. Logical, needed continue this project as new next version and update information about new version. You owner this git repository container, therefore only you can update this project. I can help with update all necessary information about new version.

leonardomarino commented 1 year ago

Thanks for the message @Pavlo-Lyha, I did not wanted to proceed with the publishing step before having this conversation. I just added you as a collaborator to the project.

Pavlo-Lyha commented 1 year ago

Ok. Have't any problem.

Pavlo-Lyha commented 1 year ago

I am update all necessary file's plugin and make new draft release version (not public view). Composer file verified. Please review/verified and make changes if needed. If it's Ok, after you can publish new release version and change README.

leonardomarino commented 1 year ago

Sounds like a good plan @Pavlo-Lyha. I was looking at the prerelease and I think it would be useful to perform some post installation actions via a script, see (https://plugins.roundcube.net/#/about/) since we have to move some files to the roundcube root directory (your_page_name_redirect.php for example).

Plugin install/upgrade/uninstall scripts If the installation or upgrading of a plugin requires some additional things to be done (e.g. creating a temp folder or installing cron jobs), arbitrary shell scripts can be shipped with the plugin package and registered for execution after an install, update or uninstall operation:

"extra": { "roundcube": { "post-install-script": "bin/install.sh", "post-update-script": "bin/update-me.sh", "post-uninstall-script": "bin/uninstall.sh" } } The paths for the post-*-script options are relative to the plugin directory. Scripts can either be shell script or PHP files and will be executed with the privileges of the user who executes the plugin installation (i.e. running composer).

Pavlo-Lyha commented 1 year ago

Hello Leonardo,

I am update draft release. I don't tested, but can would be worked. Maybe uninstall.sh file not need, because target files can be renamed customers.

leonardomarino commented 1 year ago

Hello Leonardo,

I am update draft release. I don't tested, but can would be worked. Maybe uninstall.sh file not need, because target files can be renamed customers.

Okay, sounds good to me.

leonardomarino commented 1 year ago

@Pavlo-Lyha looks like there is a problem with the composer.json file:

Error: Parse error on line 43: ...\": "src/" } } "extra": { "roundc -------------------^ Expecting 'EOF', '}', ',', ']', got 'STRING'

Pavlo-Lyha commented 1 year ago

composer.json.zip

Hello, Leonardo

Repair )) In Attach.

leonardomarino commented 1 year ago

Hi @Pavlo-Lyha a have a new draft release. Could you please test it in your environment and let me know if you run into any problems? Please use composer for the install. I also updated the README, please let me know if you have suggestions.

I am also getting errors using composer but manually running the install script solves some issues.

Please advise, Leonardo

Do you want to activate the plugin duo_auth? [Y|n] Y Install of lmr/duo_auth failed

In ExtensionInstaller.php line 408:

Error executing script: sh: 1: plugins/duo_auth/bin/install.php: not found

Pavlo-Lyha commented 1 year ago

Hello Leonardo,

  1. You have not valid path install in composer.json file in extra section to post-installation script, because: the paths for the post-*-script options are relative to the plugin directory, not "plugins" directory.

Now you have path ./plugins/duo_auth/plugins/duo_auth/bin/install.php which is not exist.

Simple repair composer.json to:

"post-install-script": "bin/install.php" "post-update-script": "bin/update.php" "post-uninstall-script": "bin/uninstall.php"

  1. In script files: install.php, update.php, uninstall.php I recommend also change path and add "./" in each path, because composer run in root RoundCube directory and this script's must path relatively RC directory path.

Simple repair script file's.

For example:

rename ("./plugins/duo_auth/your_page_name_blocking_access_while_2FA_not_approved.htm", "./your_page_name_blocking_access_while_2FA_not_approved.htm");

leonardomarino commented 1 year ago

Thanks @Pavlo-Lyha! all is fine now. I am going to close this issue as it has been resolved.