I'm using SoftEther APIs to connect to a VPS and then try to build a VPN on that .
I can successfully connect to server using IP and Port, then at Authentication step I get "Access denied" and no more details.
The authentication step is using Password and HubName.
I've read the APIs codes deeply and I realized it using SHA0 algorithm to encrypt password and take a random arrays of bytes from server and use that as salt in encrypt method .
So I've changed the encryption method at SoftEther Application to AES128 , AES256 and some others but the result has not been changed at all.
I also tried to send password as an ASCII but none of them worked.
The exact API code without change:
using (var softEther = new SoftEther(ip, port))
{
// the connection step that would pass successfully :
var connectResult = softEther.Connect();
if (!connectResult.Valid())
{
Console.WriteLine(connectResult.Error);
return;
}
// the Authentication step that got problem :
var authResult = softEther.Authenticate(pw, hubName);
if (!authResult.Valid())
{
Console.WriteLine(authResult.Error);
return;
}
// the code stops and don't get here :
var user = softEther.HubApi.GetUser(hubName, userName);
Console.WriteLine(user.Valid() ? "Success" :
user.Error.ToString());
}
And this is the authResult I get
Well since you are working on server side of SoftEther i would recommend you to use VPNCMD for managing or retrieving info from SoftEther server.
VPNCMD Virtual Hub commands:
https://www.softether.org/4-docs/1-manual/6._Command_Line_Management_Utility_Manual/6.4_VPN_Server_%2F%2F_VPN_Bridge_Management_Command_Reference_(For_Virtual_Hub)
For example enter the following in cmd/terminal:
vpncmd /server {serverIP} /PASSWORD:{server password}
/adminhub:{server HUB Name} /CMD UserCreate {username}
/GROUP:{groupname} /REALNAME:{user fullname} /NOTE:{anything}
Requirements:
Download and install SoftEther server manager for your machine OS(ie from where you want to control remote server)
You can also execute VPN Client functions from VPNCMD:https://www.softether.org/4-docs/1-manual/6._Command_Line_Management_Utility_Manual/6.5_VPN_Client_Management_Command_Reference
Related
My scenario:
I have an EC2 instance running Windows Server 2016 DataCenter OS in it. This EC2 instance is configured to work as CA and IIS server (I am testing cloudhsm so it is okay for me to have multiple services in the same server). My CA is configured with RSA#Cavium Key Storage Provider (as it supports AWS CloudHSM Key Storage Provider). Now from my sample .Net WebAPI app, I can create a CSR using below code:
private async Task<CertificateSigningResponse> ActualSigningAsync(CertificateSigningRequest csr)
{
CertificateSigningResponse certificateSigningResponse;
try
{
using (RSA rsa = RSA.Create(csr.KeySize))
{
CertificateRequest request = new CertificateRequest("CN=servername-CA2", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
OidCollection oidCollection = new OidCollection();
oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.8"));
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, true));
request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(request.PublicKey, false));
var serialNumberInBytes = System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
/*
// below line creates a self signed certificate
var selfSignedCertificate = request.Create(
new X500DistinguishedName("CN=servername-CA2"),
X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1),
DateTimeOffset.Now,
DateTimeOffset.Now.AddMonths(1),
serialNumberInBytes);
*/
var certSigningRequest = request.CreateSigningRequest(X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1));
if (certSigningRequest != null)
{
certificateSigningResponse = PopulateCertificateSigningResponse(JsonConvert.SerializeObject(certSigningRequest), $"Sample Cert with Sl#: {certSigningRequest}");
}
else
{
certificateSigningResponse = PopulateCertificateSigningResponse("", $"Error: {request.PublicKey}");
}
}
}
catch (Exception ex)
{
certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, ex.Message);
}
return certificateSigningResponse;
}
Now, I want to send this CSR to my CA (which is running on EC2) and get it signed. Once signed, I want to send the signed certificate back to the user. Currently, I have hosted my sample webapi app on the same EC2 instance. This app actually exposes an endpoint, which I can hit via postman and pass in some data as request body (POST).
So, ideally, the app receives my POST request and extracts data from it, then using that data, it is creating a csr. And now I want to send this csr to my CA, get it signed and finally return the signed certificate to user. Below pseudo code may give you some idea about my requirements:
//pseudo code; not existed
// request is generated in above code
var caService = new CAService();//can use my ca info i.e. name, public dns, ip
var response = await caService.SignAsync(request);//response should be a cert
return response;
I have seen few posts using CertUtilLib/CertEnrollLib but I want to achieve this by fully managed code. Also if it is not possible, please suggest me some alternatives. Thanks.
EDIT 1 (after Michal's comment)
Below are some info for your interest:
Current Scenario:
we are using a 3rd party API to sign some critical data.
In this way, we make a POST request to that particular endpoint with the data we wanted to be signed.
The 3rd party API handles everything for us behind the scene. We know that they are using some HSM service at their end to sign data.
My intention:
I am trying to achieve the same functionality using AWS CloudHSM.
The calling process should be same, i.e. we should still call an endpoint with data and get the signed copy of the data.
For this, my understanding was to create the CSR at server end and sign it using CloudHSM from within the server.
For that, I have created a sample .Net API app that exposes an endpoint where I can post my data to be signed.
Then it is my app's responsibility to create the CSR (I did it already), and then send the CSR to a CA (this is my EC2 Windows
Server 2016 instance which has the CA feature enabled on it) for
signing (I am stuck here at the moment).
I have a piece of code that should connect to the server. The code is as following:
var rdp = new MsRdpClient8NotSafeForScripting();
rdp.Server = "192.168.0.101"; //adress
rdp.Domain = "localdomain"; //domain
rdp.UserName = "test"; //login
rdp.AdvancedSettings8.ClearTextPassword = "123456";//password
try
{
rdp.Connect();
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine(rdp.Connected);
if (rdp.Connected != 0)
{
rdp.Disconnect();
}
Console.ReadLine();
This is supposed to "connect" to my remote server via 3389 port so that I can be able to read a file from my desktop which is called: "min.txt"
So far I have tried specifying the login data of my server but I always just get output of "0" in the console's window, regardless of whether I specify correct or incorrect login data..
My questions here are:
Why is it connecting even with wrong login data (ip, user + password)
How can I, once I've been indeed successfully connected to the server, access the min.txt file on my remote server, which is located at desktop...
Can someone help me out?
Probably you can try specifying the password like below:
MSTSClib.IMsTscNonScriptable secured = (MSTSClib.IMsTscNonScriptable)rdp.GetOcx();
secured.ClearTextPassword = “123456”;
For reference: MSDN link is here
Once connected, you can access the file like a shared network file via UNC.
Example:
System.IO.FileStream stream = System.IO.File.OpenRead("\\servername\sharedname\path\somefile.txt");
Then need to ensure that permissions are in place to access the folder.
I'm writing a UWP app in C# that is eventually destined for IoT, but right now I've only been debugging locally. I'm using Windows.Web.Http.HttpClient to connect to a self-hosted WCF REST web service that I've also written and have running as a Console app on the same machine for testing. The service requires mutual authentication with certificates, so I have a CA cert, service cert, and client cert.
My UWP code works like this:
Check app cert store for client cert and CA cert installed.
If not, install from PFX file and CER file, respectively.
Attach the Certificate to the HttpBaseProtocolFilter and add the filter to the HttpClient
Call the HttpClient.PostAsync
After I call PostAsync I get the following error: An Error Occurred in the Secure Channel Support. After plenty of searching online, and by common sense, I'm pretty sure HttpClient is barfing because of a problem establishing the mutually-authenticated SSL connection. But based on my troubleshooting I can't figure why.
To troublshoot further, I've written a plain old Console app using System.Net.Http.HttpClient, attached the client certificate to the request and everything works great. Sadly, System.Net isn't fully supported on UWP. I've also tried NOT attaching the certificate to the UWP HttpClient and the app prompts me with a UI to select an installed certificate. I select the correct cert and still get the same exception (this at least lets me know the cert is installed correctly and validating properly with the CA from the app's perspective). In additon, I hit the GET on the web service from a browser, select the client cert when prompted, and am able to download a file.
I've tried using Fiddler and, I assume because of the way it proxies traffic, it seems to work a little bit further, except my web service rejects the request as Forbidden (presumably because Fiddler is not including the correct client cert in the request). I haven't hit up Wireshark yet because it's a pain to get Wireshark to work using localhost on Windows.
My next step is to start changing the web service to not require client authentication and see if that is the problem.
Two questions: Why is Windows.Web.Http.HttClient not working in this case? And, less important, any recommendations on good HTTP monitoring tools to help me debug this further?
This MSDN post proved to have the answer. Seems like an oversight on MS part requiring a separate, meaningless call to the API beforehand. Oh well.
http://blogs.msdn.com/b/wsdevsol/archive/2015/03/26/how-to-use-a-shared-user-certificate-for-https-authentication-in-an-enterprise-application.aspx
Excerpt from the article:
However, the security subsystem requires user confirmation before allowing access to a certificates private key of a certificate stored in the shared user certificates store. To complicate matters, if a client certificate is specified in code then the lower level network functions assume the application has already taken care of this and will not prompt the user for confirmation.
If you look at the Windows Runtime classes related to certificates you won’t find any method to explicitly request access to the certificate private key, so what is the app developer to do?
The solution is to use the selected certificate to 'Sign' some small bit of data. When an application calls CryptographicEngine.SignAsync, the underlying code requests access to the private key to do the signing at which point the user is asked if they want to allow the application to access the certificate private key. Note that you must call 'Async' version of this function because the synchronous version of the function: Sign, uses an option that blocks the display of the confirmation dialog.
For example:
public static async Task<bool> VerifyCertificateKeyAccess(Certificate selectedCertificate)
{
bool VerifyResult = false; // default to access failure
CryptographicKey keyPair = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(
selectedCertificate, HashAlgorithmNames.Sha1,
CryptographicPadding.RsaPkcs1V15);
String buffer = "Data to sign";
IBuffer Data = CryptographicBuffer.ConvertStringToBinary(buffer, BinaryStringEncoding.Utf16BE);
try
{
//sign the data by using the key
IBuffer Signed = await CryptographicEngine.SignAsync(keyPair, Data);
VerifyResult = CryptographicEngine.VerifySignature(keyPair, Data, Signed);
}
catch (Exception exp)
{
System.Diagnostics.Debug.WriteLine("Verification Failed. Exception Occurred : {0}", exp.Message);
// default result is false so drop through to exit.
}
return VerifyResult;
}
You can then modify the earlier code example to call this function prior to using the client certificate in order to ensure the application has access to the certificate private key.
Add the Certificate file your Project
Add the Certificate to the Manifested file (give file path in attachment)
the Frist Service Call of in Ur Project use to ignore the certificate validation Following Code is most Suitable for Login Function.
try
{
var filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationFailure);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.WrongUsage);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain);
Windows.Web.Http.HttpClient client = new Windows.Web.Http.HttpClient(filter);
TimeSpan span = new TimeSpan(0, 0, 60);
var cts = new CancellationTokenSource();
cts.CancelAfter(span);
var request = new Windows.Web.Http.HttpRequestMessage()
{
RequestUri = new Uri(App.URL + "/oauth/token"),
Method = Windows.Web.Http.HttpMethod.Post,
};
//request.Properties. = span;
string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(Server_Username + ":" + Server_Password));
var values = new Dictionary<string, string>
{ { "grant_type", "password" },{ "username", Uname}, { "password", Pwd }};
var content = new HttpFormUrlEncodedContent(values);
request.Headers.Add("Authorization", "Basic " + encoded);
request.Content = content;
User root = new User();
using (Windows.Web.Http.HttpResponseMessage response = await client.SendRequestAsync(request).AsTask(cts.Token))
{
HttpStatusCode = (int)response.StatusCode;
if (HttpStatusCode == (int)HttpCode.OK)
{
using (IHttpContent content1 = response.Content)
{
var jsonString = await content1.ReadAsStringAsync();
root = JsonConvert.DeserializeObject<User>(jsonString);
App.localSettings.Values["access_token"] = root.Access_token;
App.localSettings.Values["refresh_token"] = root.Refresh_token;
App.localSettings.Values["expires_in"] = root.Expires_in;
var json = JsonConvert.SerializeObject(root.Locations);
App.localSettings.Values["LocationList"] = json;
App.localSettings.Values["LoginUser"] = Uname;
}
}
}
}
catch (Exception ex)
{
ex.ToString();
}
We've been using VisualSVN (standard edition) for a few years without any problems. We have a C# application which stores data in SVN. It uses SharpSvn (https://sharpsvn.open.collab.net) library for SVN access. Occasionally, the application executes a server-side SVN COPY command (SharpSvn's "RemoteCopy") to create a branch based on a series of existing in the repository files.
We recently updated VisualSVN from version 2.5.2 to 3.2.2 and also purchased a license to unlock enterprise features of the product. We enabled Integrated Windows Authentication, but also kept Basic Authentication for backward compatibility.
After running for a week without any problems (performing only reads from SVN), our application tried to perform the copy for the first time, and it failed with the following error complaining about one of the files that had to be copied:
"COPY request on '/svn/repository/!svn/rvr/12345/trunk/file.xml' failed: 501 Method Not Implemented"
The server log reveals the following:
Level,Date and Time,Source,Event ID,Task Category
Error,2015-03-03 9:37:26 AM,VisualSVN Server 3.2,1001,Apache,"Multi-author commits not supported. [501, #175002] [client 192.168.1.100]"
Error,2015-03-03 9:37:26 AM,VisualSVN Server 3.2,1001,Apache,"Could not fetch resource information. [501, #0] [client 192.168.1.100]"
Error,2015-03-03 9:37:26 AM,VisualSVN Server 3.2,1001,Apache,"SSPI Challenge failed: The token supplied to the function is invalid [client 192.168.1.100]"
Error,2015-03-03 9:37:21 AM,VisualSVN Server 3.2,1001,Apache,"SSPI Challenge failed: The token supplied to the function is invalid [client 192.168.1.100]"
After restarting VisualSVN service, the command completed without any problems. This had never happened before with the older versions of VisualSVN.
This is how we create a branch using SharpSvn:
private static void Branch(ICollection<SvnUriTarget> sources, Uri targetUri, string comment, string userName, string password)
{
if (sources == null) throw new ArgumentNullException("sources");
if (targetUri == null) throw new ArgumentNullException("targetUri");
if (comment.IsNullEmptyOrSpaces()) throw new ArgumentNullException("comment");
if (userName.IsNullEmptyOrSpaces()) throw new ArgumentNullException("userName");
if (password.IsNullEmptyOrSpaces()) throw new ArgumentNullException("password");
using (var client = new SvnClient())
{
client.Authentication.Clear();
client.Authentication.DefaultCredentials = new NetworkCredential(userName, password);
client.Authentication.SslServerTrustHandlers += (sender, e) => { e.AcceptedFailures = e.Failures; e.Save = true; };
SvnCommitResult commitResult;
if (!client.RemoteCopy(sources, targetUri, new SvnCopyArgs { CreateParents = true, LogMessage = comment }, out commitResult))
throw new ApplicationException("Failed to create tag/branch in Repository");
}
}
In our application, we are still using Basic Authentication, and credentials are explicitly passed to every SharpSvn call. The application requests credentials from the user, and then it uses these credentials to perform a single call of the "Branch" method.
Two different users tried to do this using their own credentials on two different machine with the same result. Only restart of VisualSVN service fixed the problem. I'm worried that this problem may come back again...
You should disable SharpSvn (and Subversion) to use Integrated Authentication ('ntlm' and 'negotiate') if you're going to specify credentials for operation.
Try add code like this:
client.Configuration.SetOption("servers", "global", "http-auth-types", "basic");
Probably this is a bug in Subversion, SharpSvn or serf, but proposed workaround should work.
I am trying to develop a C# based build tool using p4api.net apis. I am new to perforce p4api.net. I followed the instructions given in p4api.net library downloaded from their site, but was never successful in running a basic command on perforce. I am attaching piece of code which is supposed to fetch clients from Perforce. Please correct it, if am wrong. The code throws a run time error (unhandled expection) while executing GetClients().
static void Main(string[] args)
{
string uri = "perforce:1666";
string user = "User1";
Server server = new Server(new ServerAddress(uri));
Repository rep = new Repository(server);
Connection con = rep.Connection;
con.UserName = user;
con.Client = new Client();
// connect to the server
con.Connect(null);
// run the command against the current repository
IList<Client> changes = rep.GetClients(null);
}
Any useful guide to perforce C# documents/examples would be appreciated.
Thanks,
Madhu
tickets are granted to the user by p4 login. If you login with P4V or another client the ticket should still be valid until expiration unless you explicitly p4 logout. You can create this credential in P4API.NET after you connect and before you run a command:
// connect to the server
con.Connect(null);
string password = "pw";
Credential cred = con.Login(password, null, null);
con.Credential = cred;
Are you sure that the exception is coming from GetClients? I ran your code successfully, but when I changed uri to a non-existent server:port I get the unhandled exception at con.Connect(null).
Confirm that you do have access to a perforce:1666 server with User1 and that User1 does not require a password on that server.