C# Checking if Password is correct with SmtpException - c#

So I have an application which basically sends an email out, but I want to be able to have multiple users using it, and I need it to check if their login details are correct, which ideally need to be done when entered, but that's not essential, as it sends the email would be fine as well.
I've looked up how to do it, and I read about using an SmtpException, my issue is that I don't actually know how to use it to check if the password is the thing causing the issue.
The other way I found was to use sockets and to check with a tcp/ip layer, however as the program is bespoke for a company, I don't know exactly how their server works, and therefore don't really want to use this method.
Thanks for all your help

The SmtpException thrown will include a status code. See SmptException.StatusCode
It will return an enumeration value of type SmtpStatusCode.
I believe the one you're looking for (to indicate a bad login) is ClientNotPermitted.
To confirm, you can try a test program and provide invalid credentials . . .
Hope that help!

Related

C# OAuth2 SMTPclient.Authenticate() exceptions

I added Service Account to my email#gmail.com, activated OAuth2 for it and downloaded the key. Then I followed the steps described in this (life saving) post with the only difference that I instantiated "credential" from Json file (loading p12 would always give me "Invalid network password"). With this I can successfully get Access Token, here is the line which does it:
Task<bool> result = credential.RequestAccessTokenAsync(CancellationToken.None);
Then I instantiate SmtpClient from MailKit and try to connect and authenticate:
client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
var oauth2 = new SaslMechanismOAuth2("email#gmail.com", credential.Token.AccessToken);
client.Authenticate(oauth2);
The last line generates exception that reads 555: 5.5.2 Syntax error, goodbye. l13sm3080685qtv.82 - gsmtp. The part that ends with .82 changes with each subsequent call. As per this post, I tried different variants for "email#gmail.com" (i.e. <email#gmail.com>). I also tried to use the Service Account email instead (the one similar to this: appName#serviceName.iam.gserviceaccount.com) but to no avail. I mad sure I am using latest versions of MailKit, MimeKit and Google.Api* and searched extensively but found nothing that could provide a solution.
Interestingly, without any change to the code I started experiencing different exception. It now comes partially base64 ecoded and reads this (after decoding):
334: {"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
In the meantime I tried 2 other implementations that claim they got it right. None works - they all succeed with getting access token but break on "authenticate". All of that blows once's mind and makes the effort even more hopeless. One wonders if there is any C# code that is truly successful in sending gmail message using OAuth2... Any hint or other form of help would be greatly appreciated.
The method pointed by jstedfast below works well but I'd like to follow up with few issues. Too much for standard comment, so I added it here:
When the flow is executed for the first time, it opens popup browser window and user must login/approve the application/service to access gmail account. It loooks like access key must be stored on the hard drive. If I removed "DataStore" from GoogleAuthorizationCodeFlow constructor, the browser seems to popup each time when executing the code. The app I have to fix normally runs without any user interaction. Is there a way to avoid browser popup by enabling/disabling something in gmail account or service/app defined in developer's console? If standard gmail account cannot be used this way, perhaps email that is a part of GSuite domain can? The customer who owns the application uses Google GSuite and they have their domain with emails and documents. I think that now I understand jstedfast's remark on client-to-server vs server-to-server.
Follow these directions to get this working: https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md
If you are loading a .p12, then you are doing it wrong. That method is for service-to-service, not client-to-service. The instructions I provided above is for client-to-service.

ASP.Net Website different error page for external and internal users

Scenario: We have a website that is viewed both internally and externally. When an error occurs the users are displayed with a detailed error page(Stack trace etc).
Problem: The external customers do not need that much information about the error. We are looking to have the external customers see a messsage instead. Ex. Please contact Administrator. Also if possible we would like to log this message in our SQL database.
Note: I'm assuming I make a custom error page like - Implementing a Custom Error page on an ASP.Net website but how do I determine whether or not the user is internal/external? Also is this the best way to approach the problem? Additionally if anyone has suggestions on the best way to store these errors in the database that is also appreciated.
Thanks in advance.
YOu can try settings your mode to RemoteOnly in the web.config
<customErrors mode="RemoteOnly">
This way local users will see the error, and external users will see the other error pages which you have set up.
There is an article here about such things http://aspnetresources.com/articles/CustomErrorPages
The way I would do this is to have different entry points for external and internal users. I would do this through the hostname. By varying the hostname I could then create a custom error experiance for each type of user.
If by 'internal' you mean logged in, and 'external' you mean anonymous, you could use the same custom error page but check the user's logged in state using Request.IsAuthenticated
You could then simply display the message based on the user's status.
For storage of errors you could use log4net and/or ELMAH. ELMHA is specifically for catching unhandled exceptions. Log4net is predominantly for logging from within your code, i.e. from within a try/catch statement.
It is good practice to use both.
That article is on the right track of what you need to do. Also, see:
http://aspnetresources.com/articles/CustomErrorPages
http://www.asp.net/hosting/tutorials/displaying-a-custom-error-page-cs
http://weblogs.asp.net/erobillard/archive/2003/04/23/5992.aspx
The determination about whether a user is internal or external will be handled by the web server.
customErrors for RemoteOnly will probably not help you because RemoteOnly only refers to users not accessing the page from the same physical box. Users on the LAN will be treated as remote just like users from the WAN will.
If I had to solve your problem, I would start in Application_Error and examine Request.UserHostAddress and Request.UserHostName but even those are not going to be completely reliable because on my corporate intranet, my address of 10.4.42.219 might very well match your companies internal addresses, and UserHostName is supposed to be a human readable name but it isn't always - case in point, look at it running in debug mode and both UserHostAddress and UserHostName will be "127.0.0.1" when you'd expect the latter to be "localhost".
See the problem here is that by the time they hit your webserver, they're inside the firewall, and the server is a listener - so it doesn't matter what IP the incoming connection CLAIMS to be from (spoofing being a very real problem), your webserver isn't gonna initiate a response, it's going to send a response down the very pipeline that the client opened.
Now if your firewall can be configured to leverage spoofing and force the IP coming in to be a specific value, that would be one possible way to reliably identify external connections, and by process of elimination, the internal ones but I can't speak to the viability of that approach with any certainty.
Edit to add: I suspect your initial question may itself be flawed. The question I'm asking myself is, who on your internal side really cares about the error message? Is your corporate secretary going to want to see stack trace info? Probably not.
I suspect that what you REALLY need here is active authentication and role based security, such that only specifically identified users - members of the "Error Investigator" role perhaps - should see those detailed exceptions, and everyone else, including internal users, gets the pretty custom page.

Is Java/1.6.0_24 a Bot and How to force them to refresh their link

We've now got plenty of sites which all use a log4net base error loging framework and we receive error from site from anywhere it append. We've notice that some of them catch error because of "Bot" like google, bing, yahoo, etc. But there's a things we've not sure about how to resolve. I've two questions about it :
Is "Java/1.6.0_24" a Bot? Because the user-agent of my question #2 is about this.
The "Java/1.6.0_24" still calling subfolder on our site that just do not exists! Like, if we have a page called "Page1.aspx", instead of calling "~/Page1.aspx", he calls it "~/minisite/Page1.aspx". How can I tell him he's wrong? Is there a way to do it?
Thanks you
It's most likely a bot but it could as well be some kind of browser based on Java that sends that user-agent string - you can't trust it 100% but it can give you an estimate idea of what the connecting entity is. Depending on the kind of bot it might as well just ignore your robots.txt so I'd just impement some handling stuff somewhere.
Did those folders ever exist? If so, you could use HTTP's permanent redirect (code 301) to tell him to no longer look there - however that doesn't guarantee it will do so.

DotNetOpenAuth I need some help please

I know this has been posted before, but never really answered, I'm using the DotNetOpenAuth to try and do GoogleID login, and every time I do details = OResponse.GetExtension<ClaimsResponse>(); I always, always, always get back null, I don't get whats the point of the GoogleID if I can't get back any information, I would think at the very least I would get an email address, so I could associate it other login information in my databse. I just don't understand could really use some help, Im probably just looking at openID in the wrong way.
I'm using ASP.NET and looking to use openID/Facebook as my sole means of logging in users, I really don't want to mess with membership roles, or extra junk that ASP.NET likes to add.
Yes, this has been asked and answered many times. Google does support AX. But it ignores any attributes marked as "optional". So if you want the email address, you have to say that email address is a required attribute.
The ClaimsResponse extension you're checking for isn't AX -- it's Simple Registration. But if you have AXFetchAsSregTransform behavior turned on (highly recommended) then it allows you to just use ClaimsRequest and ClaimsResponse exclusively, and DotNetOpenAuth will automatically translate to and from AX behind-the-scenes for you.
Alternatively, you can use FetchReqest and FetchResponse to speak AX directly to Google.
But (and I can't hammer this hard enough), do not use the email address as the user's unique identifier!!! Instead, use the IAuthenticationResponse.ClaimedIdentifier string as the unique identifier. Email address should generally be considered just a helpful hint that can be used to prefill a registration form. You shouldn't even trust that the email address you get is really under the user's control (that's one reason why it shouldn't be considered their unique id) since the Provider can lie to you. Google and Yahoo are two providers that promise (if you choose to trust them) that the email addresses have been verified, so you can skip the email validation step for users from them if you wish.
It doesn't appear that Google's OpenID server supports AX or sreg.

E-Mail Existence Check in C#

I want to verify whether an e-mail is real or not. Some body told me I could do it with DNS check but I don't know how to do this.
Could somebody help me through this problem and I am developing with C#.
Thanks in advance.
I guess this code-project article gives you the information you want: Effective Email Address Validation
But even if you confirm that a domain is valid, it is still not guaranteed that the email address/recipient is valid. E.g. "xyz#stackoverflow.com" -> the domain is valid, but "xyz" might not be a valid email address.
You can use DNS to determine if a domain is valid/resolving. That wouldn't necessarily mean that a given email address at that domain is valid. The only way to know that is to open an SMTP connection and try to send mail to that user.
Never done this myself, but there appears to be a pretty good C# walkthrough here.
DNS check would imply parsing out the domain attached to the email address in question and making sure it resolves/exists.
Be aware that checking that the domain resolves/exists could take time since your application would need to wait for a response from whatever service you use to check if it exists.

Categories

Resources