Managed CSOM on Sharepoint 201. Could not create SSL/TLS secure channel - ssl

I have a Windows Server 2016 VM and Visual Studio 2017 Community Edition. I am writing a simple script just to check the connectivity with the Sharepoint 2013. The Sharepoint Server is NOT installed on the VM, it is somewhere within the intranet.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Client;
using System.Security;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string siteUrl = "https://xxx.yyy.org:443";
ClientContext clientContext = new ClientContext(siteUrl);
Web site = clientContext.Web;
List documents = site.Lists.GetByTitle("Documents");
//Prepare the request
clientContext.Load(site);
//Submit the Request
clientContext.ExecuteQuery();
Console.ReadKey();
}
}
}
But I am getting this exception:
System.Net.WebException occurred
HResult=0x80131509
Message=The request was aborted: Could not create SSL/TLS secure channel.
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.SharePoint.Client.SPWebRequestExecutor.Execute()
at Microsoft.SharePoint.Client.ClientContext.GetFormDigestInfoPrivate()
at Microsoft.SharePoint.Client.ClientContext.EnsureFormDigest()
at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
at ConsoleApp1.Program.Main(String[] args) in C:\Users\AdminDD\source\repos\ConsoleApp1\ConsoleApp1\Program.cs:line
I've read this thread and I signed in through IE. The certificate of the browser seems valid and the problem remains. Is there any suggestion on how to solve this ?

I had the exact same issue.
Check your project .Net Version. It worked after upgrading from 4.5 --> 4.6

you should do a request on your url https://yoursite/ absolute url only, nothing more
$response = Invoke-WebRequest -Verbose -URI $anUrl -CertificateThumbprint $CertificateThumbprint -UseDefaultCredentials -SessionVariable websession -ErrorAction:Stop
get cookie authentification in reponse, and then add it in your csom query
$request.ClientCertificates.Add($global:cert)
$request.CookieContainer = New-Object System.Net.CookieContainer
$c3 = New-Object System.Net.Cookie($global:cookieName3, $global:cookieVal3, "/", $global:cookieDomaine);
$request.CookieContainer.Add($c3);
here is a working sample

Related

Third party IIS Module not printing to log files

I have an asp.net core application hosted and webdav enabled in IIS for storing files as well. I want to know when a user saves a file in the webdav server (ie, if opened and saved in Microsoft word). I have put together this IIS module to try and intercept all http requests so I can find out what a webdav HTTP requests look like and then hopefully create a if statement using this logic once I can identify the save request. So far here is the IIS module I have created:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace WebDAVTargetDetectorIIS
{
public class LoggingModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(OnPreRequestHandlerExecute);
context.PostLogRequest += new EventHandler(PostLogEvent);
}
#endregion
public void OnPreRequestHandlerExecute(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpRequest request = app.Context.Request;
if (!String.IsNullOrEmpty(request["HTTP_CF_CONNECTING_IP"]))
{
request.ServerVariables.Set("REMOTE_ADDR", request["HTTP_CF_CONNECTING_IP"]);
}
}
public void PostLogEvent(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpRequest request = app.Context.Request;
app.Response.AppendToLog("This is a test");
}
}
}
I have created the BIN folder in the root folder of my web application and used the IIS Manager to add the new module. It is added to the end of the ordered list. The log files in IIS seem to save to "C:\inetpub\logs\LogFiles\W3SVC1" however my module does not seem to be printing my test line in there. Is there a particular reason the code above would not implement on any even a login request? Or should I be attaching this to some other event?

use TLS 1.2 to connect securely to RabbitMQ

I am trying to connect to a RabbitMQ server using TLS1.2 but I can't seem to do it. I have verified that my username and password are working as I can connect to the RabbitMQ web client.
using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
namespace DigitalFulfillmentRabbitMQ
{
public class RabbitMQService
{
public IConnection GetRabbitMqConnection()
{
ConnectionFactory connectionFactory = new ConnectionFactory();
// ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
// connectionFactory.Ssl.CertificateValidationCallback = CheckValidationResult();
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
connectionFactory.HostName = ConfigurationManager.AppSettings["RabbitMQServer"].ToString();
connectionFactory.VirtualHost = ConfigurationManager.AppSettings["RabbitMQVHOST"].ToString();
connectionFactory.Port = Int32.Parse(ConfigurationManager.AppSettings["RabbitMQPort"].ToString());
connectionFactory.UserName = ConfigurationManager.AppSettings["RabbitMQAccountUserName"].ToString();
connectionFactory.Password = ConfigurationManager.AppSettings["RabbitMQAccountPassword"].ToString();
// connectionFactory.Ssl.ServerName = System.Net.Dns.GetHostName();
connectionFactory.Ssl.ServerName = ConfigurationManager.AppSettings["RabbitMQServer"].ToString();
connectionFactory.Ssl.CertPath = ConfigurationManager.AppSettings["RabbitMQSSLCertPath"].ToString();
// connectionFactory.Ssl.CertPassphrase = ConfigurationManager.AppSettings["RabbitMQSSLCertPassphrase"].ToString();
connectionFactory.Ssl.Enabled = Convert.ToBoolean(ConfigurationManager.AppSettings["RabbitMQSSLIsEnabled"].ToString());
connectionFactory.Ssl.Version = System.Security.Authentication.SslProtocols.Tls12;
return connectionFactory.CreateConnection();
}
}
}
The certificate is a .pem certificate I have put on the client. I'm using port 8071. The certificate path is of format "D:\RabbitMQ_DF_SIT_Server_certificate\ca_certificate.pem". I'm using the RabbitMQ client from NuGet 5.1.0
I doubt I need Certificate Validation Callback Method because from what I understand its one way connection. This application will only consume & not publish at all. What am I missing? The certificate is sitting on the client server but not installed per se.
It throws an error :
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.AggregateException: One or more errors occurred. ---> System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm
In order to use TLS with RabbitMQ one has to enable this via the RabbitMQ config located in Windows at %APPDATA%/RabbitMQ/rabbitmq.conf file.
Depending on the Erlang version being used, the config can be the classic format / ini style. For more details, please refer to https://www.rabbitmq.com/configure.html
With the newer ini style configuration format, the config should look like this
listeners.ssl.default = 5671
ssl_options.verify = verify_none
ssl_options.fail_if_no_peer_cert = false
ssl_options.cacertfile = <location to cacertfile.crt>
ssl_options.certfile = <location to certfile.crt>
ssl_options.keyfile = <location to private.key>
All of the above can be automated and verified via a script that I wrote for this
https://gist.github.com/skewl84/a72321379a65c4c5cfd447f8806b5188
The script above does
Check if OpenSSL is installed else download to generate Self-Signed certificate if neccessary
Modify RabbbitMQ config to enable TLS
Use OpenSSL to Test TLS after it has been enabled on the RabbitMQ

VSTO-specific web request not working (System.Net.WebException)

I wrote a 2013/2016 VSTO app for Microsoft Word using C#. My app creates a new toolbar with buttons. One such button runs my app, which launches a basic Windows Form.
Before the user can work with my app, they need to enter information like their license code and email address. My code in turns sends a basic request to my licensing server and awaits a response.
All my code has been running just fine and now it no longer is. Now, when I run the code, I receive the following two error messages:
System.Net.WebException: 'The underlying connection was closed: An
unexpected error occurred on a send.' Inner Exception: IOException:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host.
and
System.Net.WebException: 'The underlying connection was closed: An
unexpected error occurred on a send.' Inner Exception:
SocketException: An existing connection was forcibly closed by the
remote host
I decided to run the code using a standard console app to see if I received the same error message, and sure enough, it worked great! Now I am wondering if Word or the Microsoft VSTO technology is blocking my app from accessing my server.
Here is the code in VSTO that does not work
Note 1: Created a basic 2013/2016 C# VSTO add-in, added a toolbar, and added
Note 2: Added a reference to System.Web.
Note 3: Modified the website link and the query strings as I did not want to publish them on this public forum.
using System;
using Microsoft.Office.Tools.Ribbon;
using System.Web;
using System.Net;
namespace WordAddIn3
{
public partial class Ribbon1
{
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
}
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// Attempt to activate the product using the licensing server on the website.
Console.WriteLine("** ActivateLicense");
//build the url to call the website's software licensing component.
var builder = new UriBuilder("https://validwebsite.com");
builder.Port = -1;
//build the query string.
var query = HttpUtility.ParseQueryString(builder.Query);
query["license_key"] = "validactivationcdode";
query["product_id"] = "validproductid";
query["email"] = "validemailaddress";
builder.Query = query.ToString();
string url = builder.ToString();
Console.WriteLine("activation request:");
Console.WriteLine(url); //display the REST endpoint.
//make the synchronous call to the web service.
var syncClient = new WebClient();
var responseStream = syncClient.DownloadString(url);
Console.WriteLine("Response stream:");
Console.WriteLine(responseStream); //display the server json response.
}
}
}
Here is what is pretty much the same exact code in a console app that does work
Note 1: Created a basic C# console app.
Note 2: Added a reference to System.Web.
Note 3: Modified the website link and the query strings as I did not want to publish them on this public forum. You will receive an error, but that is due to the sample website not having a licensing server.
using System;
using System.Net;
using System.Web;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// Attempt to activate the product using the licensing server on the website.
Console.WriteLine("** ActivateLicense");
//build the url to call the website's software licensing component.
var builder = new UriBuilder("https://validwebsite.com");
builder.Port = -1;
//build the query string.
var query = HttpUtility.ParseQueryString(builder.Query);
query["license_key"] = "validactivationcdode";
query["product_id"] = "validproductid";
query["email"] = "validemailaddress";
builder.Query = query.ToString();
string url = builder.ToString();
Console.WriteLine("activation request:");
Console.WriteLine(url); //display the REST endpoint.
//make the synchronous call to the web service.
var syncClient = new WebClient();
var responseStream = syncClient.DownloadString(url);
Console.WriteLine("Response stream:");
Console.WriteLine(responseStream); //display the server json response.
Console.ReadKey();
}
}
}
Can you help me determine why the code is no longer working in the add-in where it did before (with no code changes)?
I read a lot online and there seem to be too many reasons why this might happen. As an FYI, the website with the licensing server is running. It is (and always has been) a little slow, but when running the code with VSTO, the response is immediate (suggesting no timeout). The Console code runs and there is never a timeout.. I always get a response from the licensing server.
On another thread for a similar problem, someone recommended running WireShark. I am not really familiar with the product, but during my working console run, I received no error messages and instead I got messages like these:
Standard query 0x626a AAAA mywebsite.com
and
Standard query response 0x626a AAAA mywebsite.com
However, if I run the same code in VSTO, I get additional messages that are errors (this one shows up twice):
TCP 60 443 → 50308 [RST, ACK] Seq=1 Ack=125 Win=32768 Len=0

Capturing traffic by fiddler in .net 4.5

I wrote simple application on VS2010 that send httpwebrequest and without any configurations fiddler is captures this request. But after, I installed VS2012 and run fiddler, and when i send request i have exception "Operation timed out" and request is no captured. When i close fiddler all requests are sends.
I delete VS2012 and .net framework 4.5. After that request are sends and fiddler capturing them.
Why fiddler dont't capture traffic when .net4.5 installed?
Did you by any chance try to set the Host property of the HttpWebRequest?
This may be the cause of your problem.
I have also .NET 4.5 installed and experience the same situation.
I get the same error when fiddler is running and is acting as a proxy. The error is:
System.Net.WebException: The operation has timed out at
System.Net.HttpWebRequest.GetResponse()
Here is a trivial sample that reproduces the problem:
using System;
using System.IO;
using System.Net;
namespace WebRequestTest
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com");
request.Host = "www.microsoft.com";//If I comment this line, capturing with fiddler works OK.
request.Method = "GET";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader sr = new StreamReader(stream))
{
string content = sr.ReadToEnd();
Console.WriteLine(content);
}
}
}
}
In my case I just had to comment the request.Host="www.microsoft.com" line and everything worked OK.
I suspect same behavior will occur when using an HTTP proxy other than fiddler, but I have not tested it though.

I'm having trouble launching my WCF service using a console application. What can be wrong?

Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using BankServiceClient.BankServiceReference;
namespace BankServiceClient
{
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8000/Simple");
Type instanceType = typeof(BankServiceReference.BankClient);
ServiceHost host = new ServiceHost(instanceType,baseAddress);
using (host)
{
Type contractType = typeof(BankServiceReference.IBank);
string relativeAddress = "BankService";
host.AddServiceEndpoint(contractType, new BasicHttpBinding(), relativeAddress);
host.Open();
Console.WriteLine("Press <ENTER> to quit.");
Console.ReadLine();
host.Close();
}
/*
* Consuming a WCF Service and using its method.
*/
//IBank proxy = new BankClient();
//double number = proxy.GetBalance(1234);
//Console.WriteLine(number.ToString());
//Console.ReadLine();
}
}
}
First, a couple of questions:
The 'baseAddress' attribute, what exactly is it? When I launched my service using the default F5 (no console application) the service launched on a random port on localHost. How can I write in an exact number and expect it to go there? Confused at this one.
What is the relativeAddress attribute? It says BankService but what should I write in that attribute? Confused at this one as well.
Here's the exact error message I get when I try to run this Console application:
HTTP could not register URL
http://+:8000/Simple/. Your process
does not have access rights to this
namespace (see
http://go.microsoft.com/fwlink/?LinkId=70353
for details).
First is your client project set to be the start up project?
And to answer your questions.
1) baseAddress (URI Class) is the base address for your hosted service. I am thinking you are launching some other project.
2) You have two options on configuring endpoints(reference). Relative and Absolute. The way you did it will take your base and appends your relative -> http://localhost:8000/Simple/BankService
Lastly to fix your hosting issue see this SO link:
WCF ServiceHost access rights