Using 2FA authentication with classic ASP always returns an invalid response - authentication

I'm using this code from GitHub
https://github.com/as08/ClassicASP.TwoFactorAuthentication
I downloaded the demo site, installed what I needed on the server and everything works perfectly. The demo site has a lot of code so I broke it down into the two components that are shown on the Github page 1)Generating a secret key and QR code 2) Validating a verification code.
I made 2 very barebones basic asp pages
index.asp
<%
Dim TwoFA : Set TwoFA = Server.CreateObject("ClassicASP.TwoFactorAuthentication")
TwoFA.SecretKeyLength(20)
TwoFA.HashMode("SHA1")
TwoFA.totpSize(6)
RecoveryPasswordLength = 18
Dim SecretKey, RecoveryPassword, GenerateQR
SecretKey = TwoFA.GenerateSecretKey()
RecoveryPassword = TwoFA.RecoveryPassword(RecoveryPasswordLength)
response.write("Secret Key: " & secretKey & "<br>")
response.write("Recovery Password: " & RecoveryPassword & "<br />")
' Generate the QR code
GenerateQR = "<img src=""https://chart.googleapis.com/chart" &_
"?chs=320x320" &_
"&chld=H|0" &_
"&cht=qr" &_
"&chl=" & Server.URLencode("otpauth://totp/test#test.com" &_
"?secret=" & SecretKey &_
"&issuer=examplesite.com" &_
"&algorithm=SHA1" &_
"&digits=6" &_
"&period=30") & "&choe=UTF-8"" " &_
"class=""img-fluid border-info border mt-4 QRframe"" " &_
"width=""320px"" height=""320px"">"
Set TwoFA = Nothing
%>
<%=GenerateQR%>
Validate.asp
<%
Dim TwoFA : Set TwoFA = Server.CreateObject("ClassicASP.TwoFactorAuthentication")
TwoFA.SecretKeyLength(20)
TwoFA.HashMode("SHA1")
TwoFA.totpSize(6)
TOTP = request("totp")
response.write(totp & "<br />")
If TwoFA.Verify("EDSLKFQENTEFPATYN5LAZ5BCGD2UOR4R",cStr(TOTP)) Then
' Valid Time-based One-time Password (TOTP)
response.write("valid")
Else
' Invalid TOTP
response.write("invalid")
End If
Set TwoFA = Nothing
%>
To test, I went to my index.asp page and generated a QRcode and set that up in Microsoft Authenticator. I then took the secret key and hardcoded it into the validate page's verify call. Then I went into Authenticator and got the code and tested it by going to validate.asp?totp=123456. No matter what I do, I can't get this to work. I always get the response.write("invalid") result.
Why is this not returning a valid response even though I'm typing in the right 6 digit code using the right secret key?

I figured this out. I hope this can be helpful to someone in the future. Unfortunately, in the documentation it has the TOTP in a cStr(TOTP), thereby converting it to a string... but I removed the cStr() and in the request i forced it to be an integer by doing:
TOTP = request("totp")+0
Now it works!

This isn't an answer as such, but it's too long and detailed to leave as a comment.
I've downloaded and run the demo from my GitHub repository, and used Microsoft authenticator, Google Authenticator and Authy. And they all work fine, including the 30 second tolerance. I even changed my time zone to various different ones (although that wouldn't account for the 4 second expiration you described, and they didn't. I was just covering all my bases).
All I can think to recommend is this, download and run this UTC.asp page:
<%=UTC_DateTime()%>
<script language="JScript" runat="server">
// Return the current UTC date and time regardless of what timezone the server is set to
function UTC_DateTime() {
var date = new Date();
// date.getUTCMonth() returns a value from 0 - 11 (?) so we need to + 1
var result = date.getUTCFullYear() + "-" + (date.getUTCMonth() + 1) + "-" + date.getUTCDate() + " " + date.getUTCHours() + ":" + date.getUTCMinutes() + ":" + date.getUTCSeconds();
// Pad month/day/hour/minute/second values with a 0 if necessary
return result.replace(/(\D)(\d)(?!\d)/g, "$10$2");
}
</script>
Then compare it to a site like timeanddate.com, if the times aren't the same (give or take a few a few seconds), then there has to be something wrong with you servers time settings, it must be generating a UTC time that is out of sync. Some sort of NTP glitch?
If that's the case, I don't have an answer, hopefully someone does, but that has to be the problem given it's working fine for me. (I ran all apps on iOS and the demo on Windows 10 and Windows Server 2016 just to clarify)

Related

Karate set token in local storage

I can set some value in local storage with following script
script("sessionStorage.setItem('foo', 'bar')")
But I need to set item passing a parameter.
For example,
save response token from a api call
def token = response.token
Now I would like save this token to session storage. How this can be done?
Totally up to you to create some valid JS by string concatenation.
For example:
* def temp = "sessionStorage.setItem('foo', '" + response.token + "')"
* script(temp)
Also please read this section of the docs: https://github.com/intuit/karate/tree/master/karate-core#karate-vs-the-browser

jira api - how to update fields on a jira issue that is closed/published

the following code works fine on a jira issue that is in open. but when this is tried on a closed/published issue i get error. wanted to see if this is even possible to be done? manually on closed/published jira issue, we can update those fields
Client client = Client.create();
WebResource webResource = client.resource("https://jira.com/rest/api/latest/issue/JIRA_KEY1");
String data1 = "{\r\n" +
" \"fields\" : {\r\n" +
" \"customfield_10201\" : \"Value 1\"\r\n" +
" }\r\n" +
"}";
String auth = new String(Base64.encode("user" + ":" + "pass"));
ClientResponse response = webResource.header("Authorization", "Basic " + auth).type("application/json").accept("application/json").put(ClientResponse.class, data1);
Error received
Http Error : 400{"errorMessages":[],"errors":{"customfield_10201":"Field 'customfield_10201' cannot be set. It is not on the appropriate screen, or unknown."}}
There is probably a restriction that doesn't allow the value of that field to be changed once the issue is marked as complete.
Try opening that completed issue via the web interface and changing the field's value; if you can't do it via the web interface, then you can't do it the REST API.

noflo 0.5.13 spreadsheet example broken?

I am new to noflo and looking at examples in order to explore it. The spreadsheet example looked interesting but I couldn't make it run. First, it takes some time and manual debugging to identify missing components, not a big deal and I believe will be improved in the future, for now the error message I get is
return process.component.outPorts[port].attach(socket);
^
TypeError: undefined is not a function
Apparently, before this isAddressable() was also undefined. Checked with this SO issue but I don't have any noflo 0.4 as a dependency anywhere. Spent some time to debug it but seemingly stuck at it, decided to post to SO.
The question is, what are the correct steps to run the spreadsheet example?
For reproduction, here is what I have done:
0) install the following components
noflo-adapters
noflo-core
noflo-couchdb
noflo-filesystem
noflo-groups
noflo-objects
noflo-packets
noflo-strings
noflo-tika
noflo-xml
i) edit spreadsheet/parse.fbp, because first error was
throw new Error("No outport '" + port + "' defined in process " + proc
^
Error: No outport 'error' defined in process Read (Read() ERROR -> IN Display())
apparently couchdb ReadDocument component does not provide Error outport. therefore replaced ReadDocument with ReadFile.
18c18
< 'tika-app-0.9.jar' -> TIKA Read(ReadDocument)
---
> 'tika-app-0.9.jar' -> TIKA Read(ReadFile)
ii) at this point, received the following:
if (process.component.outPorts[port].isAddressable()) {
^
TypeError: undefined is not a function
and improvised a stunt by checking if isAddressable is defined at this location of code:
## -259,9 +261,11 ##
throw new Error("No outport '" + port + "' defined in process " + process.id + " (" + (socket.getId()) + ")");
return;
}
- if (process.component.outPorts[port].isAddressable()) {
+ if (process.component.outPorts[port].isAddressable && process.component.outPorts[port].isAddressable()) {
return process.component.outPorts[port].attach(socket, index);
}
return process.component.outPorts[port].attach(socket);
};
and either way fails. Again, the question is What are the correct steps to run the spreadsheet example?
Thanks in advance.

Save Image-Path into SQL, Webmatrix

I want to create a group-function to my Website. In every group there should be a group-image, which people can upload. So I must save the path into my SQL-DB. My Code:
newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName);
imagePath = #"images\" + newFileName;
imageThumbPath = #"images\thumbs\" + newFileName;
var setPath = (#"~\" + imageThumbPath);
var intoGroupImg = ("UPDATE groups SET img= " + #setPath+ " WHERE id= "+#grID);
db.Execute(intoGroupImg);
I always get the error-message: Token line number = 1,Token line offset = 26,Token in error = images. I don't know why.
I've got a solution:
var intoGroupImg = ("UPDATE groups SET img = #0 WHERE id= " +#grID);
db.Execute(intoGroupImg, imageThumbPath);
First off, please, please use parameterized queries. It is your smoking gun versus SQL injection. Even if you're not adding user-input, it is a good habit to get into.
Anyway, I'm not sure what some of your # symbols are in there for, but I am used to using C#.net with WebMatrix, but I think that is what you're using also. Try this:
var newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName);
var imagePath = "images/" + newFileName;
var imageThumbPath = "images/thumbs/" + newFileName;
var setPath = "~/" + imageThumbPath;
var intoGroupImg = "UPDATE groups SET img = #0 WHERE id = #1";
db.Execute(intoGroupImg, setPath, grID);
This is how I would imagine it to look in C# with parameterized queries.
Given the line offset I believe the error is from #setPath but I'm not sure. Try going to the database tab in WebMatrix and manually doing a query with what you expect the value of #setPath to be.
Also, I noticed you used "backslashes" instead of "forward slashes" in the concatenated string in your example. Is this intentional? Is that what the # symbol is doing? Keeping you from having to escape each backslash with \\? Either way, the forward slash / in its place should do fine, no?
Anyway, hope I helped, at least some.

How to email SalesForce users temporary password by using API?

I am using SOAP Partner API and I have a Developer edition. I am creating users by using API. And upon creation of users I want to email these users temporary password which they can use to login to SalesForce.
This is my code:
SaveResult[] results = connection.create(new SObject[] { user });
if (results[0].isSuccess())
{
out.println("Created user: " + results[0].getId());
//connection.setPassword(results[0].getId(), "password");
ResetPasswordResult rpr = connection.resetPassword(results[0].getId());
String result = rpr.getPassword();
System.out.println("The temporary password for user ID " + results[0].getId()
+ " is " + result);
}
else
{
out.println("Error: " + results[0].getErrors()[0].getStatusCode() +
":" + results[0].getErrors()[0].getMessage());
}
This is the output I am getting in console:
The temporary password for user ID 005E0000000MwkZIAS is ucQD2PADs
However, the user is NOT receiving any password. :-(
Thanks,
Wap Rau
If you build & pass an EmailHeader in your soap request you can control what types of emails will get sent from your request.
It looks like you're using WSC, so you can add this call before calling resetPassword, which will enabled emails being sent to users. This should then send the standard reset password email.
connection.setEmailHeader(false, false, true);
use this class to send out an email. include the pwd variable in the string you want to send the user. there's an example that spells everything out
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_email_outbound.htm