Corona Project: Day 1: Two-Factor Authentication

Use this forum if you have problems with a hMailServer script, such as hMailServer WebAdmin or code in an event handler.
Post Reply
palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-17 16:36

I have an idea to create a 2 factor authentication using SMS. I have a working SMS gateway (Gammu). I think I can script whatever I need, but I'm having trouble coming up with a solid sequence of events.

Scenario 1:
1) User fails logon
2) disable account
3) send SMS to user (user's mobile number & email address in VBS array) "Reply UNLOCK to activate account"
4) Gammu script unlocks account based on mobile number/email address combination

That seems kind of strict and doesn't take into account password guessers. I get very, very few password guessers anyway because no auth on port 25 and other submission ports are closed from the internet (mail submission via webmail, ActiveSync on localhost only).

Scenario 2:
1) User fails logon
2) Failed logon goes into database for counting
3) If failed logons exceeds autoban max invalid logon attempts, then lock account & send SMS "Reply UNLOCK to activate account"
4) Gammu script unlocks account based on mobile number/email address combination

Scenario 3:
Same as above except require password change (already have working SMS hmailserver password change script for Gammu)

These seem better but I'm still missing something. Since this is a Corona-chan project, its more proof of concept than anything else. :D

Still, the concept is sound. Looking for a good execution. Any ideas, you great thinkers with time on your hands? :mrgreen:

Basically asking: what is the best strategy for SMS 2 factor authentication...

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-17 20:05

https://github.com/duosecurity/duo_classicasp

On a side note ... I use Google Two-Factor on my WordPress site since a few years back.

One problem though... SMTP only log on when sending BUT IMAP log on ALL-THE-TIME :roll:

So... Perhaps use it to authenticate your IP address combined with Username ?

1: access website, enter username and enter your Google key (from phone) to create a "oClient.IPAddress" & "oClient.UserName" token with a validity of 10 minutes.
2: start client and logon as normal. Token will allow connection
3: every update on IMAP or SMTP protocol will extend Token with 10 minutes
4: if no communication for 10+ minutes ==> destroy Token.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-17 20:26

SorenR wrote:
2020-03-17 20:05
https://github.com/duosecurity/duo_classicasp

So... Perhaps use it to authenticate your IP address combined with Username ?
^^^^ THIS ^^^^

Brilliant! As usual. Thank you again, very much.

This is going to take a little thinking (but not too much, thankfully :mrgreen: )

1) record IP at logon
2) check IP at next logon. If IP changed, lock account, send SMS to unlock

~ or ~

1) record IP at logon
2) if IP changes at next successful logon, take no action
3) If IP changes at failed logon, lock account, send SMS to unlock

~ or ~

same as above except allow for multiple failed logons (corona-quarantined grandma typos) before locking account

What do you think?

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-17 20:35

Also, I was just thinking. Maybe I use one the "limit outgoing messages" scripts floating around here in combination with account deactivation and force password change.

Which is more logical/safe/useful? The one that tries to catch password guessers before they guess or the one that deactivates/forces password change after a comprimise?

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-17 20:38

palinka wrote:
2020-03-17 20:26
SorenR wrote:
2020-03-17 20:05
https://github.com/duosecurity/duo_classicasp

So... Perhaps use it to authenticate your IP address combined with Username ?
^^^^ THIS ^^^^

Brilliant! As usual. Thank you again, very much.
I used to work as Solutions Architect in the ISP Billing/Mediation/Provisioning business for many years...

I still have my
DMg9Pq8XcAAFMom.jpg
DMg9Pq8XcAAFMom.jpg (23.89 KiB) Viewed 9997 times
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-17 20:40

palinka wrote:
2020-03-17 20:35
Also, I was just thinking. Maybe I use one the "limit outgoing messages" scripts floating around here in combination with account deactivation and force password change.

Which is more logical/safe/useful? The one that tries to catch password guessers before they guess or the one that deactivates/forces password change after a comprimise?
No need to mess with password changes - it's going to FU IMAP :!:

Build the Token stuff around "OnClientLogon()" for updating the Token timeout...

Token can live in a table in the database like my IDS code with an external maintenance.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-17 23:15

SorenR wrote:
2020-03-17 20:40
No need to mess with password changes - it's going to FU IMAP :!:
I don't understand this. Why would IMAP be any different than SMTP with regard to password changes? They share logon credentials.

The token idea is great but seems a little invasive (expiring the token requires renewed validation constantly), but I think I might settle for the following:

1) Record IP at successful logon
2) If IP changes, lock account and send sms to UNLOCK
3) Draw from past IPs to avoid UNLOCK - meaning, logon ip 1, send sms. Then logon ip 2, send sms. Then logon ip 1 and don't require sms because it's already listed as safe.
4) N failed logons (one more than autoban?) delete safe ip if exists and send sms to UNLOCK. This one will require more thinking.

It could be a pain for really mobile users, but in my environment its almost exclusively localhost, so there won't be many issues. In fact, I'll be the one that mostly gets hit with 2 factor. I'll test it exclusively on my own accounts before implementing it server-wide.

AFTER I get that set up, I'll do the "limit outgoing" thing and force password change if limit exceeded.

I have to say, Gammu is pretty awesome. Very flexible. My setup is a $10 LTE dongle and $10/mo sim card. When I first set it up, I got hit by carrier spam filters, but I was then quickly removed and haven't had an issue since. I use it for lots of different types of notifications. When I get these 2 projects finished, I'll put it up on github.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-17 23:53

palinka wrote:
2020-03-17 23:15
SorenR wrote:
2020-03-17 20:40
No need to mess with password changes - it's going to FU IMAP :!:
I don't understand this. Why would IMAP be any different than SMTP with regard to password changes? They share logon credentials.

The token idea is great but seems a little invasive (expiring the token requires renewed validation constantly), but I think I might settle for the following:

1) Record IP at successful logon
2) If IP changes, lock account and send sms to UNLOCK
3) Draw from past IPs to avoid UNLOCK - meaning, logon ip 1, send sms. Then logon ip 2, send sms. Then logon ip 1 and don't require sms because it's already listed as safe.
4) N failed logons (one more than autoban?) delete safe ip if exists and send sms to UNLOCK. This one will require more thinking.

It could be a pain for really mobile users, but in my environment its almost exclusively localhost, so there won't be many issues. In fact, I'll be the one that mostly gets hit with 2 factor. I'll test it exclusively on my own accounts before implementing it server-wide.

AFTER I get that set up, I'll do the "limit outgoing" thing and force password change if limit exceeded.

I have to say, Gammu is pretty awesome. Very flexible. My setup is a $10 LTE dongle and $10/mo sim card. When I first set it up, I got hit by carrier spam filters, but I was then quickly removed and haven't had an issue since. I use it for lots of different types of notifications. When I get these 2 projects finished, I'll put it up on github.
Do some logging on IMAP and you'll get the idea. How do you plan on changing password in the client software?

The Token authentication is simply authenticating your access to the service without changing your password. It will have the smallest footprint on the server and only put a minimal load on the server itself.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 00:09

palinka wrote:
2020-03-17 23:15
It could be a pain for really mobile users, but in my environment its almost exclusively localhost, so there won't be many issues. In fact, I'll be the one that mostly gets hit with 2 factor. I'll test it exclusively on my own accounts before implementing it server-wide.
Imagine my Token thing idea like the "free" WiFi in airports. You are redirected to a page to buy time on WiFi and must leave the browser open... Only with the Token thing it's the Google Two-Factor app on your phone that provide the code.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 01:09

SorenR wrote:
2020-03-17 23:53
How do you plan on changing password in the client software?
How does anyone change the password? Most people don't have problems with that. Only 2 of my users are seasoned citizens. I can walk them through it over the phone.

Anyway, password change is only going to be enforced on suspicion of compromised account ("limit outgoing" script). I think that would be a pretty rare occurrence.

Otherwise, the IP tracking thing would only require you reply to sms: UNLOCK. No password change - just making sure its you and not Ivan Connivin'.
The Token authentication is simply authenticating your access to the service without changing your password. It will have the smallest footprint on the server and only put a minimal load on the server itself.
I see what you're saying. And I like it. I like it a lot.

Maybe I'll forget the IP thing altogether. This does make a lot of sense.

If last successful login in past N minutes/hours/days, then allow. Else force token renewal.

But how do you deal with failed logons? Ignore them and let autoban do its thing?

Lastly, I'm using SMS, not google. Why? Mainly because I want to - I set it up, I pay for it, I want it that way. But there are really other BIG benefits. Using your method is complicated for both me and the userbase. I have to set up a website, learn how to deal with google, etc; users have to open the webpage and an app to make it work. Using my way, all they need to do is reply to a SMS message sent to them. That's easy enough. Their mobile number is their authentication. If they can receive and reply to a message, it has to be them. And yes, I know about SMS number spoofing, but an attacker would have to know the number in order to spoof it. A lot of roadblocks along that path.

I could also make them reply with a random string. I'm not sure if that would be helpful because if a number was spoofed, they would also receive the random string. I think the mobile number is probably good enough.

One last thing - I was testing code to disable the account with SMS message like this: "For security reasons, your account (test@domain.com) has been disabled due to too many failed logons. Reply UNLOCK to enable your account." Anyway, the SMS app on my phone saw "Reply UNLOCK" and placed an auto-response "UNLOCK" below the message. I didn't even have to type the word "UNLOCK". I just pushed the auto-response and away it went. Even more convenient! :mrgreen:

I'm going to get working on this tonight. :D

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 01:17

https://medium.com/@richb_/easy-two-fac ... 8388a1ea23

How about adding it to the PHPWebAdmin website?

When Token expire simply deny login, perhaps AutoBan for 30 minutes.

Google TFA is free, it only uses data so it will work on WiFi if no service is available.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 02:03

SorenR wrote:
2020-03-18 01:17
Google TFA is free, it only uses data so it will work on WiFi if no service is available.
Use going outside for service as an excuse to go smoke. :mrgreen:

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 03:16

palinka wrote:
2020-03-18 02:03
SorenR wrote:
2020-03-18 01:17
Google TFA is free, it only uses data so it will work on WiFi if no service is available.
Use going outside for service as an excuse to go smoke. :mrgreen:
Stopped smoking 5 years ago after having smoked 20-30 cigarettes a day for 40 years. Went cold turkey and never looked back.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 03:31

SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 13:41

Eh... I'm still doing it with SMS.

I think the benefits are clear. Plus I'm already paying for it. Plus I know I can do it. :mrgreen:

Oauth is really uncharted territory for me.

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 14:18

By the way, have you found the hMailServer documentation for SASL yet? :lol:

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 15:35

palinka wrote:
2020-03-18 14:18
By the way, have you found the hMailServer documentation for SASL yet? :lol:
Not looked for it yet ... :oops:
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 16:04

SorenR wrote:
2020-03-18 15:35
Not looked for it yet ... :oops:
Here you go. Everything ever written about hMailServer SASL: https://www.google.com/search?q=sasl&sa ... umentation

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 16:32

palinka wrote:
2020-03-18 16:04
SorenR wrote:
2020-03-18 15:35
Not looked for it yet ... :oops:
Here you go. Everything ever written about hMailServer SASL: https://www.google.com/search?q=sasl&sa ... umentation
https://github.com/hmailserver/hmailser ... &type=Code :mrgreen: :roll:
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 16:36

That's very helpful. :roll:



:lol:

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 17:32

hm_accounts already has column accountlastlogontime. Good! I don't need to set up any new tables.

What do you think is an appropriate amount of time since last logon before locking the account and forcing 2 factor renewal? A week? A month?

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 17:35

palinka wrote:
2020-03-18 17:32
hm_accounts already has column accountlastlogontime. Good! I don't need to set up any new tables.

What do you think is an appropriate amount of time since last logon before locking the account and forcing 2 factor renewal? A week? A month?
How often do your client check for new mail and do you have IMAP Idle active?

oAccount.LastLogonTime ...
Last edited by SorenR on 2020-03-18 17:40, edited 1 time in total.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 17:38

Also, should any action be taken on failed logon? I'm not really sure how to handle that. There could be many via password guessers.

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 17:41

SorenR wrote:
2020-03-18 17:35
palinka wrote:
2020-03-18 17:32
hm_accounts already has column accountlastlogontime. Good! I don't need to set up any new tables.

What do you think is an appropriate amount of time since last logon before locking the account and forcing 2 factor renewal? A week? A month?
How often do your client check for new mail and do you have IMAP Idle active?
IMAP idle is active.

Via ActiveSync (IMAP via :443), logon is very frequent.

Via webmail, logon is whenever someone decides to check mail. Usually at least daily.

There are no IMAP clients (:143/:993).

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 18:19

Another question: Where do I put the script?

Here is sequence of events:
1) check last logon time
2) if last logon + n days < now, then account is deemed inactive
3) autoban IP
4) send SMS unlock msg
5) receive SMS unlock response and remove autoban entry

If I put the script in OnClientLogon, hasn't the client already logged on and therefore the accountlastlogontime has been updated to now?

I think I'm going to need a new table after all.

Table hm_twofactor with columns account_name and last_logon.

1) At successful logon at OnClientLogon, check last_logon in hm_twofactor.
2a) If last_logon younger than n days, update last_logon and exit
2b) If last_logon older than n days, autoban IP and send SMS unlock message
3) When unlock message received, remove autoban

hmmm... now I have to figure out how to pass the autoban info to powershell… Maybe I just have a column in hm_twofactor to store the autoban data, then delete that info when autoban removed.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 18:25

Code: Select all

Sub OnClientLogon(oClient)

    '
    '   Find Account
    '
    Dim oApp : Set oApp = CreateObject("hMailServer.Application")
    Call oApp.Authenticate(ADMIN, PASSWORD)
    Dim a, LastLogonTime
    a = Split(oClient.UserName, "@")
    If (UBound(a) > 0) Then
        LastLogonTime = oApp.Domains.ItemByName(a(1)).Accounts.ItemByAddress(oClient.UserName).LastLogonTime
    Else
        LastLogonTime = oApp.Domains.ItemByName(oApp.Settings.DefaultDomain).Accounts.ItemByAddress(oClient.UserName & "@" & oApp.Settings.DefaultDomain).LastLogonTime
    End If
    EventLog.Write( oClient.UserName & " LastLogonTime: " & LastLogonTime )
End Sub
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 19:13

SorenR wrote:
2020-03-18 18:25

Code: Select all

Sub OnClientLogon(oClient)

    '
    '   Find Account
    '
    Dim oApp : Set oApp = CreateObject("hMailServer.Application")
    Call oApp.Authenticate(ADMIN, PASSWORD)
    Dim a, LastLogonTime
    a = Split(oClient.UserName, "@")
    If (UBound(a) > 0) Then
        LastLogonTime = oApp.Domains.ItemByName(a(1)).Accounts.ItemByAddress(oClient.UserName).LastLogonTime
    Else
        LastLogonTime = oApp.Domains.ItemByName(oApp.Settings.DefaultDomain).Accounts.ItemByAddress(oClient.UserName & "@" & oApp.Settings.DefaultDomain).LastLogonTime
    End If
    EventLog.Write( oClient.UserName & " LastLogonTime: " & LastLogonTime )
End Sub
Right. Actually I already created a database call, but this is a few lines shorter. :mrgreen:

However, what exactly does OnClientLogon do? My understanding is that everything you can do within this sub is taking place AFTER login. Therefore calling lastlogon will report the time(NOW) because the last logon took place immediately before you checked last logon.

Is this not the case?

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 19:21

LastLogonTime is updated during logon so an external check script can do the banning when the "window" closes.

If I just leave my Outlook open it will re-login when checking for new mail.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 20:22

SorenR wrote:
2020-03-18 19:21
LastLogonTime is updated during logon so an external check script can do the banning when the "window" closes.

If I just leave my Outlook open it will re-login when checking for new mail.
External script... So: IF lastlogon + n days < now THEN

-> Autoban? Autoban what? You can't predict the IP used next time they attempt logon.
-> disable account? Then it won't receive mail in the interim. :cry:

I think the new table idea works better than external script. Call at OnClientLogon and you have everything you need (IP, username, logon pass/fail, etc). If user does not respond to unlock message and then logs in on a different IP, you can still catch them with autoban. "PROVE YOU'RE YOU, DAMMIT!!!"

Also, the very best time to notify them that they can't log in is immediately after they attempt to log in.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 20:37

palinka wrote:
2020-03-18 20:22
SorenR wrote:
2020-03-18 19:21
LastLogonTime is updated during logon so an external check script can do the banning when the "window" closes.

If I just leave my Outlook open it will re-login when checking for new mail.
External script... So: IF lastlogon + n days < now THEN

-> Autoban? Autoban what? You can't predict the IP used next time they attempt logon.
-> disable account? Then it won't receive mail in the interim. :cry:

I think the new table idea works better than external script. Call at OnClientLogon and you have everything you need (IP, username, logon pass/fail, etc). If user does not respond to unlock message and then logs in on a different IP, you can still catch them with autoban. "PROVE YOU'RE YOU, DAMMIT!!!"

Also, the very best time to notify them that they can't log in is immediately after they attempt to log in.
Table with TokenID, oClient.UserName and oClient.IPAddress. If token exists continue, if not => disconnect ... or Return.Value = 1

External script check oAccount. LastLogonTime < TokenTimeoutWindow. If expired then delete record.

Something like that'ish :wink:

There are some limitations in that you can only be logged on 1 IP address.
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 20:55

Now we're on the same page. That's definitely a good sign. :mrgreen:

Why one IP limitation? Logon goes to user.

Also, Return.Value = 1 works for imap? I just assumed it only works for smtp. Will it work within OnClientLogon?

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-18 21:40

palinka wrote:
2020-03-18 20:55
Now we're on the same page. That's definitely a good sign. :mrgreen:

Why one IP limitation? Logon goes to user.

Also, Return.Value = 1 works for imap? I just assumed it only works for smtp. Will it work within OnClientLogon?
No idea... It was just an idea :oops:

Anyways... OnClientConnect is executed before OnClientLogon so you can capture it there... 8)
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-18 23:39

SorenR wrote:
2020-03-18 21:40
Anyways... OnClientConnect is executed before OnClientLogon so you can capture it there... 8)
Nope.

Code: Select all

"DEBUG"	3836	"2020-03-18 17:35:45.652"	"Pre-creating session 7107"
"TCPIP"	3836	"2020-03-18 17:35:45.652"	"TCP - 127.0.0.1 connected to 127.0.0.1:143."
"DEBUG"	3836	"2020-03-18 17:35:45.652"	"Executing event OnClientConnect"
"DEBUG"	3836	"2020-03-18 17:35:45.652"	"Event completed"
"DEBUG"	3836	"2020-03-18 17:35:45.652"	"TCP connection started for session 7106"
"IMAPD"	3836	7106	"2020-03-18 17:35:45.652"	"127.0.0.1"	"SENT: * OK IMAPrev1"
"IMAPD"	6872	7106	"2020-03-18 17:35:45.652"	"127.0.0.1"	"RECEIVED: 1 CAPABILITY"
"IMAPD"	6872	7106	"2020-03-18 17:35:45.667"	"127.0.0.1"	"SENT: * CAPABILITY IMAP4 IMAP4rev1 CHILDREN IDLE QUOTA SORT ACL STARTTLS NAMESPACE RIGHTS=texk[nl]1 OK CAPABILITY completed"
"IMAPD"	436	7106	"2020-03-18 17:35:45.667"	"127.0.0.1"	"RECEIVED: 2 STARTTLS"
"IMAPD"	436	7106	"2020-03-18 17:35:45.667"	"127.0.0.1"	"SENT: 2 OK Begin TLS negotiation now"
"DEBUG"	6872	"2020-03-18 17:35:45.667"	"Performing SSL/TLS handshake for session 7106. Verify certificate: False"
"TCPIP"	3836	"2020-03-18 17:35:45.730"	"TCPConnection - TLS/SSL handshake completed. Session Id: 7106, Remote IP: 127.0.0.1, Version: TLSv1.2, Cipher: ECDHE-RSA-AES128-GCM-SHA256, Bits: 128"
"IMAPD"	6872	7106	"2020-03-18 17:35:45.730"	"127.0.0.1"	"RECEIVED: 3 CAPABILITY"
"IMAPD"	6872	7106	"2020-03-18 17:35:45.730"	"127.0.0.1"	"SENT: * CAPABILITY IMAP4 IMAP4rev1 CHILDREN IDLE QUOTA SORT ACL STARTTLS NAMESPACE RIGHTS=texk[nl]3 OK CAPABILITY completed"
"IMAPD"	3836	7106	"2020-03-18 17:35:45.730"	"127.0.0.1"	"RECEIVED: 4 LOGIN admin@domain.com ***"
"DEBUG"	3836	"2020-03-18 17:35:45.730"	"Executing event OnClientLogon"
"DEBUG"	3836	"2020-03-18 17:35:45.761"	"Event completed"
"IMAPD"	3836	7106	"2020-03-18 17:35:45.761"	"127.0.0.1"	"SENT: 4 OK LOGIN completed"

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-19 19:14

I set up test scripts for both the hmailserver and the gammu side of things. Got everything working. Creating & deleting autobans, no sweat. Then I put it into actual use (limited to test domains). Whooooopsss… big problem on my setup because 99.9% of traffic is on localhost. Therefore autobans don't mean a hoot because localhost IP Range priority overrides everything. Therefore, instead of locking out the user, they can log in, but the script keeps making autobans and sending notices of being locked out. Reply UNLOCK doesn't do anything. :mrgreen:

Oh boy... back to the drawing board.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-19 19:25

palinka wrote:
2020-03-19 19:14
I set up test scripts for both the hmailserver and the gammu side of things. Got everything working. Creating & deleting autobans, no sweat. Then I put it into actual use (limited to test domains). Whooooopsss… big problem on my setup because 99.9% of traffic is on localhost. Therefore autobans don't mean a hoot because localhost IP Range priority overrides everything. Therefore, instead of locking out the user, they can log in, but the script keeps making autobans and sending notices of being locked out. Reply UNLOCK doesn't do anything. :mrgreen:

Oh boy... back to the drawing board.
I'm looking at the code ( 5.6.8 ) and by implementing Result.Value = 1 in OnClientLogon() I could probably make it reauthenticate ... for ever :twisted:
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-19 19:27

SorenR wrote:
2020-03-19 19:25
palinka wrote:
2020-03-19 19:14
I set up test scripts for both the hmailserver and the gammu side of things. Got everything working. Creating & deleting autobans, no sweat. Then I put it into actual use (limited to test domains). Whooooopsss… big problem on my setup because 99.9% of traffic is on localhost. Therefore autobans don't mean a hoot because localhost IP Range priority overrides everything. Therefore, instead of locking out the user, they can log in, but the script keeps making autobans and sending notices of being locked out. Reply UNLOCK doesn't do anything. :mrgreen:

Oh boy... back to the drawing board.
I'm looking at the code ( 5.6.8 ) and by implementing Result.Value = 1 in OnClientLogon() I could probably make it reauthenticate ... for ever :twisted:
I will try it and see what happens.

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-19 22:09

:cry: didn't work..

There must be some other way of intercepting logon.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-19 22:49

palinka wrote:
2020-03-19 19:27
SorenR wrote:
2020-03-19 19:25
palinka wrote:
2020-03-19 19:14
I set up test scripts for both the hmailserver and the gammu side of things. Got everything working. Creating & deleting autobans, no sweat. Then I put it into actual use (limited to test domains). Whooooopsss… big problem on my setup because 99.9% of traffic is on localhost. Therefore autobans don't mean a hoot because localhost IP Range priority overrides everything. Therefore, instead of locking out the user, they can log in, but the script keeps making autobans and sending notices of being locked out. Reply UNLOCK doesn't do anything. :mrgreen:

Oh boy... back to the drawing board.
I'm looking at the code ( 5.6.8 ) and by implementing Result.Value = 1 in OnClientLogon() I could probably make it reauthenticate ... for ever :twisted:
I will try it and see what happens.
What are you doing ???? I have not modified the code yet ... I need to build new 5.6.8 code first :mrgreen:
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-19 22:54

LOL misunderstood.

Don't do this for me. I'm not going back to 32 bit. :(

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-20 00:17

Is there any other way to disable access to the account without actually disabling the account? Disabling the account causes 550 rejections (I think).

What about RvdH's disconnect.exe? I'm going to try it.

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-20 00:32

SUCCESS!! Disconnect.exe works! Now I have to create a switch to turn it on and off.

User avatar
SorenR
Senior user
Senior user
Posts: 3576
Joined: 2006-08-21 15:38
Location: Denmark

Re: Corona Project: Day 1: Two-Factor Authentication

Post by SorenR » 2020-03-20 00:39

palinka wrote:
2020-03-20 00:32
SUCCESS!! Disconnect.exe works! Now I have to create a switch to turn it on and off.
Earlier you mentioned that everyone is using 127.0.0.1... If you disconnect 127.0.0.1 how many users do you interrupt?
SørenR.

“Those who don't know history are doomed to repeat it.”
― Edmund Burke

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-20 02:39

SorenR wrote:
2020-03-20 00:39
palinka wrote:
2020-03-20 00:32
SUCCESS!! Disconnect.exe works! Now I have to create a switch to turn it on and off.
Earlier you mentioned that everyone is using 127.0.0.1... If you disconnect 127.0.0.1 how many users do you interrupt?
I don't know. I only turned it on for all users to see if it would work, then turned it off right away.

However, I don't think it will be that disruptive at all. Of course, this is assuming a small operation like mine. It probably wouldn't scale well at all. Anyway, lets say soren@mydomain.com hasn't logged on in a long time. Then you log in via webmail and immediately get booted via disconnect.exe. Then, I log in with palinka@mydomain.com via webmail or activesync. My connection is a new one which goes through because the disconnect switch doesn't get thrown at the time I logon. Then you log in and get booted again. Then I log in and get through.

This may affect data flow. If I'm in the middle of downloading an attachment when you get booted, it could cut off my attachment. I'll have to experiment to find out what the side effects are. It will probably also kill imap idle. I'll find out soon enough.

I think regular imap/ActiveSync clients won't be affected at all because they constantly logon. They'll never trip the disconnect switch. Its the couple of people that only use webmail that may get hit. The other thing about webmail is that it only logs in when you tell it to, so its not going to keep trying over and over again unsuccessfully and tripping the disconnect on other people.

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-20 04:43

I think its working. The only quirk has to do with fetching the account to be unlocked. I have a table with mobile numbers for each account. At first, I set it up so every account that didn't belong to a real person used my mobile phone. But when the gammu script looks for the account based on the mobile number of the sender, it loops through all accounts with the sender number. So testing with one of those that had my number caused it to run through all of them and I got a flood of "your account has been unlocked" messages. So after that I changed the mobile number for all the machine accounts to 0 and only send a message if the disconnect switch was set to ON. Also, eventhandlers.vbs only triggers on accounts with a real mobile number. So basically, I'm ignoring machine accounts. Nobody ever logs in to them anyway.

I'll throw the whole thing up on GitHub later. You might be interested in how I worked out eventhandlers.

Code: Select all

Sub GetLastLogon(ByVal s_Account, ByRef m_LastLogon)
	Dim oRecord, oConn : Set oConn = CreateObject("ADODB.Connection")
	oConn.Open "Driver={MariaDB ODBC 3.0 Driver}; Server=localhost; Database=hmailserver; User=hmailserver; Password=supersecretpassword;"

	If oConn.State <> 1 Then
		EventLog.Write( "Sub GetLastLogon - ERROR: Could not connect to database" )
		m_LastLogon = "1969-12-31 23:59:59"
		Exit Sub
	End If

	m_LastLogon = "1969-12-31 23:59:59"

	Set oRecord = oConn.Execute("SELECT lastlogon FROM hm_twofactor WHERE account = '" & s_Account & "'")
	Do Until oRecord.EOF
		m_LastLogon = oRecord("lastlogon")
		oRecord.MoveNext
	Loop
	oConn.Close
	Set oRecord = Nothing
End Sub

Function TFDB(sAccount)
    Dim strSQL, oDB : Set oDB = GetDatabaseObject
    strSQL = "INSERT INTO hm_twofactor (account,lastlogon) VALUES ('" & sAccount & "',NOW()) ON DUPLICATE KEY UPDATE lastlogon=NOW();"
    Call oDB.ExecuteSQL(strSQL)
    Set oDB = Nothing
End Function

Function SetSwitchOn(sAccount)
    Dim strSQL, oDB : Set oDB = GetDatabaseObject
    strSQL = "UPDATE hm_accounts_mobile SET switch = 1 WHERE account = '" & sAccount & "';"
    Call oDB.ExecuteSQL(strSQL)
    Set oDB = Nothing
End Function

Sub GetMobileNumber(ByVal s_Account, ByRef m_MobileNumber)
	Dim oRecord, oConn : Set oConn = CreateObject("ADODB.Connection")
	oConn.Open "Driver={MariaDB ODBC 3.0 Driver}; Server=localhost; Database=hmailserver; User=hmailserver; Password=supersecretpassword;"

	If oConn.State <> 1 Then
		EventLog.Write( "Sub GetLastLogon - ERROR: Could not connect to database" )
		m_MobileNumber = "0"
		Exit Sub
	End If

	m_MobileNumber = "0"

	Set oRecord = oConn.Execute("SELECT mobilenumber FROM hm_accounts_mobile WHERE account = '" & s_Account & "'")
	Do Until oRecord.EOF
		m_MobileNumber = oRecord("mobilenumber")
		oRecord.MoveNext
	Loop
	oConn.Close
	Set oRecord = Nothing
End Sub

Sub OnClientLogon(oClient)
	Dim strRegEx, sMSG, SMSNumber, ShURL
	If oClient.Authenticated Then

		strRegEx = "@mydomain\.net|@mydomain\.com"      '<-- EXCLUDE ALL BUT TEST DOMAINS FOR NOW
		If Lookup(strRegEx, oClient.Username) Then

			REM - Two Factor Authentication - get variables
			Dim m_MobileNumber, m_LastLogon
			Call GetMobileNumber(oClient.Username, m_MobileNumber)
			REM - If account is a real person, then begin two factor check
			If m_MobileNumber <> "0" Then
				Dim a : a = Split( oClient.Username, "@" )
				Dim AcctDomain : AcctDomain = Trim( CStr( a(1) ) )
				Dim A_Domain : A_Domain = UCase(Left(AcctDomain, 1)) &  Mid(AcctDomain, 2)
				Dim A_AcctCaps : A_AcctCaps = UCase(oClient.Username)
				Call GetLastLogon(oClient.Username, m_LastLogon)

				REM - If last logon outside of interval, trip 2 factor
				REM - DateAdd can be one of the following: "yyyy" Year, "m" Month, "d" Day, "h" Hour, "n" Minute, "s" Second
				If (DateAdd("d", 7, m_LastLogon)) < Now() Then
					Call Disconnect(oClient.IPAddress)
					SetSwitchOn(oClient.Username)
					sMSG = "Message from " & A_Domain & " Mail Server: For security reasons and your safety, your account (" & oClient.Username & ") has been temporarily disabled. Reply UNLOCK to enable your account."
					Call SendSMS(m_MobileNumber, sMSG)
				Else
					REM - If last logon within interval, update logon time
					Call TFDB(oClient.Username)
				End If
			End If
		End If
	End if
End Sub

One thing I noticed was that when disconnect.exe gets called, ALL connections from localhost get killed - not just the ones connecting on hmailserver mail ports.

I'm going to clean this up, throw it up on GitHub and call it a day. The next corona-quarantine project is outgoing mail limit with force password change via sms. :mrgreen:

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-20 14:56

One last question. Maybe the most important one.

What is an appropriate no-logon interval that trips the 2 factor switch? 2 days? 7 days? 30 days?

Actually, one more question. The way Google works it is by device. If it sees you're on a new device, it asks for pre- authentication. Is there any way other than IP to determine that in hmailserver?

Via activesync, the device is known with a sync key. Probably via webmail, browser ID could be figured out. What about other clients like outlook / Thunderbird via imap?

If we figure this one out it could be applied well towards implementing Google oauth.

User avatar
mattg
Moderator
Moderator
Posts: 20837
Joined: 2007-06-14 05:12
Location: 'The Outback' Australia

Re: Corona Project: Day 1: Two-Factor Authentication

Post by mattg » 2020-03-21 00:35

palinka wrote:
2020-03-20 14:56
The way Google works it is by device.
Actually not quite

If you open two different browsers on one computer you will need to AUTH both of them
It seems to be per program / per device
Just 'cause I link to a page and say little else doesn't mean I am not being nice.
https://www.hmailserver.com/documentation

palinka
Senior user
Senior user
Posts: 1941
Joined: 2017-09-12 17:57

Re: Corona Project: Day 1: Two-Factor Authentication

Post by palinka » 2020-03-21 00:51

mattg wrote:
2020-03-21 00:35
palinka wrote:
2020-03-20 14:56
The way Google works it is by device.
Actually not quite

If you open two different browsers on one computer you will need to AUTH both of them
It seems to be per program / per device
That's what I meant. They look at some kind of browser identification, among other things.

Post Reply