Community discussions

MikroTik App
 
Lelik200
just joined
Topic Author
Posts: 22
Joined: Fri Jul 24, 2020 1:48 pm

One line password generation without fetch tool

Fri Jul 24, 2020 3:55 pm

:put ([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: One line password generation without fetch tool

Fri Jul 24, 2020 5:46 pm

wow, this was interesting. Seems to generate a random hex string on 20 character each time its run.
Should be fine as a password.

It seems to store each run in this view for some time:
/certificate scep-server otp print
# PASSWORD                                                                                                                EXPIRES              USED
 0 677d57c658119f4f8804                                                                                                    0s                   no  
 1 bd4a331ef703af86d1ac                                                                                                    0s                   no  
 2 7bcc23c0b21d3628154b                                                                                                    0s                   no  
 3 9004db9d316482e341a4                                                                                                    0s                   no  
 4 3347c7c2465cd6696fc4                                                                                                    0s                   no  
 5 cfeb7c719712b1fda4cd                                                                                                    0s                   no  
If you like a shorter password: (8 characters)
:put [pick ([/certificate scep-server otp generate minutes-valid=1 as-value]->"password") 0 8]
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Wed Oct 21, 2020 2:16 pm

And removes the full password directly after generating it.
{
:local hash ([/certificate scep-server otp generate minutes-valid=0 as-value]->"password");
/certificate scep-server otp remove [:find $hash];
:local pwd [:pick $hash 0 8];
:put $pwd;
}
 
Lelik200
just joined
Topic Author
Posts: 22
Joined: Fri Jul 24, 2020 1:48 pm

Re: One line password generation without fetch tool

Wed Oct 21, 2020 3:25 pm

Alternatively, but they are removed automatically after a few seconds if you use "minutes-valid=0"
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Wed Oct 21, 2020 4:45 pm

That did not work for me and the generated passwords stay in the list despite it has counted down to zero.
OTP.jpg
It is not that easy to remove those passwords and the problem is that sometimes the generated password is not yet displayed in the list. Then I get the error that the item does not exist. I am still trying to find a good way like using on-orror so that the script keeps running.

Update: it comes even stranger when I add in Winbox with a 0..4294967295 (unsigned long integer) minutes timeout. It is starting to increase the counter. Terminal is still showing zero.

I am on 6.48beta48 so that could be different than other versions.

Update 2:

Mailed Mikrotik support on this.
You do not have the required permissions to view the files attached to this post.
 
Lelik200
just joined
Topic Author
Posts: 22
Joined: Fri Jul 24, 2020 1:48 pm

Re: One line password generation without fetch tool

Thu Oct 22, 2020 12:35 am

Yes, it's strange. Last time I tested on 6.47.4 and everything was fine. We are waiting for a response from support.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Thu Oct 22, 2020 12:41 am

Simple password generator based on Mikrotik OTP.
# generate password:
{
:set $pwdLength 10;
# From this string the password is formed.
:set $pwdComposedOff "!&()*+/0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz{}";
:set $pwdLoops ((255 + [:len $pwdComposedOff]) / [:len $pwdComposedOff]);
:for i from=1 to=$pwdLoops do={:set $multipliedString "$multipliedString$pwdComposedOff";};

/certificate scep-server otp
# Generate enoug times hash to have enough characters for the password (x2).
:for i from=1 to=((10 + ($pwdLength-1)) / 10) do={:set $hash "$hash$([generate minutes-valid=0 as-value]->"password")";};

# Group them each time in pairs. Substracting 1 because i starts a zero.
:for i from=0 to=(($pwdLength * 2)-1) step=2 do={ \ 
 :set $hex "0x$[:pick $hash $i ($i+2)]";
 :set $pwdString "$pwdString$[:pick $multipliedString ($hex-1) ($hex)]";
};

:put "Generated password: $pwdString; with a length of $pwdLength";
/}
Update: made the script simpler and flexible by set the password length and now only as many needed OTP hashes are generated to fit the length of the password. The characters of the password are now multiplied several times to be more than 255 in total. It adapts to the number of characters you put in that.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: One line password generation without fetch tool

Thu Oct 22, 2020 12:14 pm

Thanks for the script. Tested and also work on beta 7.
Just for my way to use script, I have removed all ; and the not needed \ after "do=" and used tab to get better indent.
# generate password:
{
:set $pwdLength 5
# From this string the password is formed.
:set $pwdComposedOff "!&()*+/0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz{}"
:set $pwdLoops ((255 + [:len $pwdComposedOff]) / [:len $pwdComposedOff])
:for i from=1 to=$pwdLoops do={
	:set $multipliedString "$multipliedString$pwdComposedOff"
}

/certificate scep-server otp
# Generate enoug times hash to have enough characters for the password (x2).
:for i from=1 to=((10 + ($pwdLength-1)) / 10) do={
	:set $hash "$hash$([generate minutes-valid=0 as-value]->"password")"
}

# Group them each time in pairs. Substracting 1 because i starts a zero.
:for i from=0 to=(($pwdLength * 2)-1) step=2 do={
	:set $hex "0x$[:pick $hash $i ($i+2)]"
	:set $pwdString "$pwdString$[:pick $multipliedString ($hex-1) ($hex)]"
}

:put "Generated password: \"$pwdString\" with a length of $pwdLength"
}
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Thu Oct 22, 2020 2:32 pm

Your're welcome and many thanks Jotne for the clean up. All those ; in just to be sure that it would not complain about those missing in other settings. The / was there to go to the root of the menu.

It could be adapted to meet minimal password requerements by having several compose of strings and nest the loops. The value of the hex then determines which loop get which one of the compose of string. When selecting the loop also the number of minimal how much has to match.

A different way of selection the character in the compose of string is needed because the are not multiplied anymore. (255 / (([:len pwdComposedOf])-1)

Example: one special, one capital and one number and the rest is random.

Update: I have added mixed versions of the string and added only letters, only numbers and only special characters. The main change is not to have to multiply the string from which the password is formed.
Code has become outdated and is removed
Last edited by msatter on Sun Oct 25, 2020 7:52 pm, edited 2 times in total.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Fri Oct 23, 2020 1:16 am

An other step and the strings are stored in a array so that selection is easier and is now also a function that can be called with extra parameters:

$genpassword {length} {string} {string} {string} -- length is size of the password, string can be normal, mixed, letters, mixletters, numbers, mixnumbers, special, mixspecial. If no string is provided then the normal string is used to generate the password. Normal contains letters (Case and lower case), numbers and special characters. Mix means that the content is in randomized order.
Code has become outdated and is removed.
Update 1 + 2: if the password length is omitted and there is an other parameter selecting the string. If one or all string parameters are incorrect, then an error message is displayed and no password is generated.
Also the names of the string are only hard-coded at one place so changing any of those, leads not to go through the script to change them also.
Last edited by msatter on Sun Oct 25, 2020 7:51 pm, edited 1 time in total.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Sat Oct 24, 2020 5:17 pm

An other further development. Made it so that only the names and strings are hard-coded and all depending on those are dynamic. The default string should be named "default" and that is the only variable/key that is hard-coded.

It was a lot of work for someone who inexperienced in programming. I did not go further with minimal password requirements and looking for a hashing and salting example so that the does not to be password and instead the hash and salt. Added pin to the parameter to choose from.
# generate password and it locally stored (function and variables)
{
:local genpassword do={ \ 
:local arrayString [:toarray ""];
# Sets the length of the password
:if ([:typeof [:tonum $1]]="nil") do={:set $pwdLength 10} else={:set $pwdLength $1}
# When no length is stated shift the parameters to their expected place when stated
:if ([:typeof [:tonum $1]]="nil") do={:set $4 $3; :set $3 $2; :set $2 $1; :set $1}

# From these strings the password is formed. They are stored in a array.
:set ($arrayString->"default")      "!&()*+/0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz{}"
:set ($arrayString->"letters")      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
:set ($arrayString->"pin")          "0123456789"          ; :set ($arrayString->"numbers")      "0123456789"
:set ($arrayString->"special")      "!&()*+/:;<=>@[]{}"
:set ($arrayString->"mixed")        "67KODNoI10H>4c:b29RdG{kreA<yBtJWwfvzZUFPs;@gjEV&8n}C5hMSx(TQ3!mi/]aLul*+pX[=Yq)" 
:set ($arrayString->"mixedletters") "ogcxNhEwfMDeJAbUuQYZmITCBXLjVWdlFrtsPzqOKGHvySRikpna";
:set ($arrayString->"mixednumbers") "8923176504"          ; :set ($arrayString->"mixednumbers") "8923176504"
:set ($arrayString->"mixedspecial") "[]*/{+};!>:=<(@)&"

# Select the string(s) used to generate the password from. If no string provided select the first in array.
:if ([:typeof $2] ~ "(nothing|nil)") do={ \
    :set $pwdComposedOf (get [$arrayString as-value]->"default"); } \
  else={ \ 
    :foreach labelName in={$2;$3;$4} do={:set $pwdComposedOf "$pwdComposedOf$(get [$arrayString as-value]->$labelName)"}
    
    # Check if the parameters are matching the key(s) of the array. $compareLabel is adaptive to the number of strings.	
    :foreach label,dummy in=$arrayString do={:if ($label ~ "(mixed)") do={} else={:set $compareLabel "$compareLabel$label|"}}
    :set $compareLabel "$[:pick $compareLabel 0 ([:len $compareLabel]-1)]"; :set $compareLabel "($compareLabel)"
    :foreach varname in={"$2"; "$3"; "$4"} do={:if ($varname ~ $compareLabel || [:typeof $varname]~"(nothing|nil)") do={} else={:set $pwdComposedOf ""}}
}; # if ([typeof $2]....

# Only generate a password when there is a string present in $pwdComposedOf. Else throw an on-error. It not a perfect check.
:if ([:len $pwdComposedOf] > 0) do={ \
   # Change to the OTP generator page.
   /certificate scep-server otp
   # Generate enough times hash to have enough characters to fit the password (x2).
   :for i from=1 to=(($pwdLength + 9) / 10) do={:set $hash "$hash$([generate minutes-valid=0 as-value]->"password")"}
      # Group them each time in pairs. Substracting 1 because it starts a zero.
   :for i from=0 to=(($pwdLength * 2)-1) step=2 do={ \ 
	:set $hex "0x$[:pick $hash $i ($i+2)]"
	:set $hex (($hex * 1000000000) / (255000000000 / ([:len $pwdComposedOf]))); # Times 1000000000 to increase calculating accuracy. @no-decimals
	:set $pwdString "$pwdString$[:pick $pwdComposedOf ($hex) ($hex+1)]"
   }; # for i
   :put "Generated password: $pwdString with a length of $pwdLength"
   :set $pwdString; # clears generated password from memory. 
   :do {:for i from=0 to=60 do={remove numbers=$i}} on-error={}
} \

else={ \
:foreach label,dummy in=$arrayString do={:set $parameters "$parameters$label, "} 
 :set $parameters [:pick $parameters 0 ([:len $parameters]-2)]
 :error "\r\nInvalid parameter(s) used. No password generated. Valid parameters are:\r\n$parameters" }
}; # :local genpassword (function)
$genpassword 10 default
}
Update: corrected calculation with a divider by multiplying by x1000 because RouterOS does not use decimals. Some more to tackle.....
Update2: Corrected the check on $2 = "nothing" to ~ "(nothing|nil)". Plus other optimizations in the code.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: One line password generation without fetch tool

Tue Oct 27, 2020 9:54 am

Thanks for the work with the password script. MT should add some like this as an built inn function :)

PS You do not need the \ after do and else or at end of line if its a new command.
do={ \ -> do={
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Tue Oct 27, 2020 1:12 pm

That would be great and Mikrotik could also use the encryption engine to hash the password generated, with a salt added to it. Then the admin only has to store the hash and the salt.

I have busy on a scripts and when syntax and error checking it is wise to not be in the root but off-root (like: /ip). In the root a lot is allowed to be omitted that is not allowed when you are off root.

A chicken and egg problem is when there is a syntax error (using { }) you get the line and position. However it does not help in the Terminal screen because those lines are only displayed when there is no error. Those line can be made visible by pressing the F5 key.
Last edited by msatter on Tue Oct 27, 2020 6:39 pm, edited 1 time in total.
 
Lelik200
just joined
Topic Author
Posts: 22
Joined: Fri Jul 24, 2020 1:48 pm

Re: One line password generation without fetch tool

Tue Oct 27, 2020 2:51 pm

Should line 17 be like this?
:set ($arrayString->"mixedpin") "8923176504"          ; :set ($arrayString->"mixednumbers") "8923176504"
("mixednumbers" -> "mixedpin")
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Tue Oct 27, 2020 6:40 pm

Should line 17 be like this?
:set ($arrayString->"mixedpin") "8923176504"          ; :set ($arrayString->"mixednumbers") "8923176504"
("mixednumbers" -> "mixedpin")
Thanks, I think I will do away with static mixed and replace that by dynamic mixing on each call only for the type actually used.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Fri Nov 13, 2020 6:09 pm

Mixing the base strings is complete after bring on the backburner while I wrote a menu script.

Also aound a much faster and absolute way to remove the obsolete OTP hashes.I first had a for next removing the "numbers" one by one. This did not work always and with more that thirdteen thousand hashes I was stuck and to get rid of them would be rebooting the router...no way.

I use now: remove [find where expires < 10m] in the OTP menu. This should be fixed in the next Beta.

So complete is displaying a menu, password/pin and mixing the base strings used for generating those.

Creating hashes of paswords and salting those is something I can't do.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: One line password generation without fetch tool

Tue Nov 24, 2020 12:44 am

Create a way to delete the generate hash while the auto-removal is still broken in my version of RouterOS:
:local createOTPHash [/certificate scep-server otp; ([generate minutes-valid=0 as-value]->"password") [:foreach i in=[find -1] do={:set $lastHash $i}; :do {remove $lastHash} on-error={}]];
It will create the variable "createOTPHash", with the hash stored in it and at the same time it will remove the last added hash.

Update: I had to isolate the :foreach by using extra [ ] on further testing.
Update2: it only works if there is already a hash present so I have put a :do {} on-error={} in. Erasing from the the on-error did not work and I don't know why.
Upfste 3: this is not going to work because the hash is not yet stored so it removes the previous generated hash.

Who is online

Users browsing this forum: drpioneer and 23 guests