I have written a C# .net executable that sends an email through an outlook exchange server. Everything works fine when I run it manually, but when I use a scheduled task to call the executable it doesn't send the email. Everything else works fine, but the email doesn't get sent. I set the scheduled task to run as my user account. When the task is running I can see in Task Manager that the executable is running under my username. This rules out any obvious permissions issues.
While debugging I made the program output some text to a file on a network share on the same machine on which Exchange is running. This file outputs fine, so I know that the program can connect to that machine.
Can anyone help?
Ok, as you can see above I was trying to send mail through a running instance of Outlook. Although I wasn't able to post code without in a comment box without pulling my hair out #amitapollo gave me the clue to use the System.Net.Mail namespace. At the end of the day I got it to work. Here's my code:
System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient("myExchangeServerIPAddress");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new System.Net.NetworkCredential("myDomain\\myUsername", "myPassword");
smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
smtpClient.EnableSsl = true;
System.Security.Cryptography.X509Certificates.X509Store xStore = new System.Security.Cryptography.X509Certificates.X509Store();
System.Security.Cryptography.X509Certificates.OpenFlags xFlag = System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly;
xStore.Open(xFlag);
System.Security.Cryptography.X509Certificates.X509Certificate2Collection xCertCollection = xStore.Certificates;
System.Security.Cryptography.X509Certificates.X509Certificate xCert = new System.Security.Cryptography.X509Certificates.X509Certificate();
foreach (System.Security.Cryptography.X509Certificates.X509Certificate _Cert in xCertCollection)
{
if (_Cert.Subject.Contains("myUsername#myDomain.com"))
{
xCert = _Cert;
}
}
smtpClient.ClientCertificates.Add(xCert);
//I was having problems with the remote certificate no being validated so I had to override all security settings with this line of code...
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object s, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; };
smtpClient.Send("myUsername#myDomain.com", "myUsername#myDomain.com", "mySubject", "myBody");
Related
I've got the following code...
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
{
ClientId = "<< MY CLIENT ID>>",
ClientSecret = "<<MY CLIENT SECRET>>"
},
new[] { "https://www.googleapis.com/auth/gmail.readonly" },
"<<EMAIL ADDRESS>>",
CancellationToken.None,
new FileDataStore("Mail2.Auth.Store")).Result;
using (var client = new ImapClient())
{
// THE CODE FAILS ON THIS NEXT LINE
client.Connect("imap.gmail.com", 993, SecureSocketOptions.SslOnConnect);
client.Authenticate("<<EMAIL ADDRESS>>", credential.Token.AccessToken);
}
When run, the code fails on the indicated like with AuthenticationException: The remote certificate is invalid according to the validation procedure.
I initially thought that is was 'cos the account had 2-step authentication on. So, I set up another account ensuring it just used the regular authentication settings and I got the same error.
I have found a number of posts, here and elsewhere, that deal with this exception but they seem to deal with the issue of working with the SmtpClient() and here, as you can see from the code, I'm getting the error with the ImapClient().
Can anyone suggest what it is that may be the cause of the error? Is it GMail? MailKit? .NET? All of the above?
The problem is that your system does not accept the GMail's SSL certificate.
You can override client.ServerCertificateValidationCallback.
A very simple example of a solution might look like this:
client.ServerCertificateValidationCallback = () => true;
Obviously that means that if anyone ever spoofed imap.gmail.com, your software would get caught in a MITM attack, so that's not ideal.
You'll likely want to match the certificate's thumbprint against a known thumbprint or else add the certificate to your local certificate store and assign a trust level to it.
I am writing an MVC application which needs to request owner names for ip addresses from ARIN.net. Here is the snippet of program code that I have written to do this:
.
.
.
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
.
.
.
This snippet of code is successfully able to send a request to http://whois.arin.net/rest/ip/17.151.229.4 and receive the appropriate response when it is run from a console application on my machine. However, when I attempt to put this snippet of code in my MVC application, I get an exception stating
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond .
My local machine, where these applications run, is inside the network of a very large corporation and therefore this snippet must send its request to ARIN through a proxy server when it is run by the previously mentioned applications. I believe that I'm probably receiving this discrepancy in results due to the console application running under a different user than the MVC application. I'm running both applications in debug mode in Visual Studio 2013. The MVC application is hosted by IIS Express when it is run in debug mode.
My questions are:
How can I find out what user the console application and the MVC application are run under?
How can I configure IIS Express to run the MVC application under a different user?
I have been unable to find answers to the questions in my research, any help is appreciated.
I discovered the cause of the problem. The MVC application didn't have a proxy server assigned to the proxy object member of the WebRequest instance by default, while the one in the console application did.
I therefore had to assign the proxy server to the proxy object instance of the WebRequest instance in my code before attempting to retrieve a response:
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
Uri newUri = new Uri("http://proxy.bigcorp.com:8080");
WebProxy myProxy = new WebProxy(newUri);
request.Proxy = myProxy;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
Thank you Brendan Green for your help!
I have a web service that expects (unicode UTF-8 encoded) text data as an HTTP POST message.
I'd like to use it from a Windows Phone 8.1 runtime client.
I created the client, but it does not invoke the web URI.
Here's the code I use on the client:
Can anyone tell what am I missing?
Thanks,
B
{
...
SendText("http://192.168.1.107:58709/UploadText.aspx"); // The IP belongs to the web server, port is correct. I can invoke it from a browser.
...
}
string StringToSend = "This is a test string uploaded via HTTP POST from WP8";
private void SendText(string Url)
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)WebRequest.Create(Url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(UploadText_GetRequestStreamCallback), request);
}
public void UploadText_GetRequestStreamCallback(IAsyncResult asyncResult)
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)asyncResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asyncResult);
byte[] postDataAsBytes = System.Text.Encoding.UTF8.GetBytes(StringToSend);
postStream.Write(postDataAsBytes, 0, postDataAsBytes.Length);
postStream.Flush();
// postStream.Close(); // Close is not available in Windows Phone 8.1 runtime project.
// request.ContentLength = postDataAsBytes.ToString(); // request.ContentLength is not available in Windows Phone 8.1 runtime project.
request.Headers["Content-length"] = postDataAsBytes.ToString();
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
OK, it seems the code was correct...
Problem was, that the phone emulator could not connect to the development server (IIS Express). I searched the web over, tried a number of solutions, but I could not make it happen. In the meantime I trashed my wifi connection, had to remove and reinstall Hyper-V to make it work again.
The workaround was to publish the test web app to the local IIS (make sure it is the Debug version that is published) then attach to it from the debugger, call from WP8.1 emulator - and it works.
I am currently working on a client-server application using netty, some of the clients are not going to be doing anything until they recieve a message. I have read the api and can´t find a way to do so. I mean I could try to have "in.readline()" on the main so it won´t end but it Doesn´t feel right. Also could have endless loops but I don´t think its the right way either.
The question here is: is there a way to bind the socket for incoming messages just like the server having the main method ending?
public void run(){
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChatClientInitializer());
Channel channel = bootstrap.connect(host,port).sync().channel();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Inserte su nombre");
String nombre = in.readLine();
MyClientChannel canal = new MyClientChannel(channel,nombre);
canal.write("SM",nombre);
in.readLine();
See that at the end I had to write "in.readline()" so the program wouldn´t end and the handler would be still up for incomming messages
The easiest thing to do would be to replace:
in.readLine();
With:
channel.closeFuture().await();
When the connection to the server is disconnected, the client will terminate.
You will also want to spend some time defining your client's life-cycle, so that the channel's state doesn't affect when your application is running and when it's not.
I am trying to create and iOS app that takes a users credentials and verifies it with the AD server. Is there some built in library in xCode to do that, or is it third party?
Any advice on direction to look would be greatly appreciated.
Thanks
Zach
Ok, so this was the PHP i used to make the connection to the ldap server. i am not 100% sure what is happening here, i got this code from IT Coordinator at my company. I understand all the binding and searching parts, but i dont get the the ldap_set_option part of this whole thing. Anyway after setting it up this way, you can then call the URL of the php script and pass it parameters. take a look at the PHP, and the url example with be below.
<?php
//Connection parameters
$dn = "DC=network,DC=net";
$host = "ldap://ldap.network.com";
$port = 1111
$user = $_GET['user'];
$pass = $_GET['pass'];
//$user = "user#network.net";
//$pass = "pass";
$filter = "memberof";
$keyword = "CN=USSC_ALL,CN=Users,DC=network,DC=net";
$filter = "objectclass";
$keyword = "user";
$filter = "objectcategory";
$keyword = "CN=Person,CN=Schema,CN=Configuration,DC=network,DC=net";
//The real thing with PHP
if (!empty($keyword) and !empty($dn)) {
//Connect to the AD
$adConn = ldap_connect($host, $port) or die("Could not connect!");
//Set protocol verison
ldap_set_option($adConn, LDAP_OPT_PROTOCOL_VERSION, 3) or die ("Could not set ldap protocol1");
//Set referrals... Won't work without this...
ldap_set_option($adConn, LDAP_OPT_REFERRALS, 0) or die ("Could not set ldap protocol2");
//Bind the user
$bd = ldap_bind($adConn, $user, $pass) or die ("Could not bind");
echo $bd;
//End binding
ldap_unbind($adConn);
} else {
echo "<p>No results found!</p>";
}
?>
</body>
</html>
Ok so now all you have to do is pass a username and password to the script and it will return the bind. that will give you either true or false. meaning if it bound successfully it is a correct combination of username and password.
this is how i am calling it:
http://192.268.192.1/ldap.php?user=(username here)&pass=(password here)
This is the approach that i took, and i think it is a very simple answer.
So what I have been able to find out is that i need to use PHP to do this. By creating a php file on the server, i can use built in ldap protocol to take a user name and password to the ldap server for verification. The query should then return true or false. As soon as i get this working ill post my code