How to generate GetSystemDateAndTime xml - c#

I have the following bit of code that i took from this source...
public bool Initialise(string cameraAddress, string userName, string password)
{
bool result = false;
try
{
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/Media"));
mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
var profs = mediaClient.GetProfiles();
//rest of the code...
When i run wireshark while going through the GetProfiles() part in the debugger, I see that the generated XML looks like:
What code would it take to change the xml to look like:
How am i supposed to call the GetSystemDateAndTime function?
To call the GetProfiles function, I had to create a MediaClient and, then, call that function...
Is there such thing as a MediaClient to get access to the GetSystemDateAndTime??
Edit:
I found that you could use the DeviceClient to get access the the GetSystemDateAndTime function...
You'll need to add the device management wsdl to your connected services before:
https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl
I also added System.Net.ServicePointManager.Expect100Continue = false; in there because i saw someone said it helped at this link...
So i added :
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
System.Net.ServicePointManager.Expect100Continue = false;
DeviceClient d = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));
var time = d.GetSystemDateAndTime();
Note:
I'm still getting the error:
ErrorMessage "The header 'To' from the namespace 'http://www.w3.org/2005/08/addressing' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding. " string

This error is saying that there is trouble when trying to read a message, so i tough it was probably due to some sort of encoding ...
AND I WAS RIGHT!!
All I had to do was changing a parameter in the TextMessageEncodingBindingElement's creation.
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)
All you need to do is make sure that you have good encoding and AuthenticationScheme...
Here's my final code to get an onvif camera's (here cohuHD camera) system and date and time settings:
public bool Initialise(string cameraAddress, string userName, string password)
{
bool result = false;
try
{
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
System.Net.ServicePointManager.Expect100Continue = false;
DeviceClient deviceClient = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));
var temps = deviceClient.GetSystemDateAndTime();
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
}
return result;
}
Bonus:
If you want to execute a function that needs credentials, you can add those to your deviceClient like so:
//DIGEST (httpBinding)
deviceClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
Watch out also for the EndpointAddress' URL... I think some cameras use Device_service and other device_service .

Related

How to dynamically Configure different "SubscriptionProperties" for Azure ServiceSub Subscription in C#

I'm trying to configure Azure ServiceBus Topic Subscription dynamically(using C#) with all of its properties which we can set up using Azure Portal.
I have tried the below code, but it's giving me an "object reference error" for SubscriptionProperties while setting up its values.
static SubscriptionProperties subscriptionProperties;
static async Task Main(string[] args)
{
adminClient = new ServiceBusAdministrationClient(connectionString);
client = new ServiceBusClient(connectionString);
subscriptionProperties.AutoDeleteOnIdle = TimeSpan.FromDays(14);
subscriptionProperties.DefaultMessageTimeToLive = TimeSpan.FromDays(14);
subscriptionProperties.TopicName = topicName;
subscriptionProperties.SubscriptionName = subscriptionName;
subscriptionProperties.MaxDeliveryCount = 3;
subscriptionProperties.LockDuration = TimeSpan.FromSeconds(5.00);
subscriptionProperties.DeadLetteringOnMessageExpiration = true;
subscriptionProperties.EnableDeadLetteringOnFilterEvaluationExceptions = true;
Console.WriteLine($"Creating the subscription {subscriptionName} with a correlation filter");
if (!await adminClient.SubscriptionExistsAsync(topicName, subscriptionName))
{
await adminClient.CreateSubscriptionAsync(
new CreateSubscriptionOptions(subscriptionProperties),
new CreateRuleOptions(subscriptionFilterName, new CorrelationRuleFilter() { Subject = correlationFilterValue }));
}
}
Let me know if this is the correct way of setting the property values for "SubscriptionProperties" class or how can I do so?
I was able to fix this issue by following this link https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample07_CrudOperations.md#create-a-topic-and-subscription
var client = new ServiceBusAdministrationClient(connectionString);
string subscriptionName = "<subscription_name>";
var subscriptionOptions = new CreateSubscriptionOptions(topicName, subscriptionName)
{
AutoDeleteOnIdle = TimeSpan.FromDays(7),
DefaultMessageTimeToLive = TimeSpan.FromDays(2),
EnableBatchedOperations = true,
UserMetadata = "some metadata"
};
SubscriptionProperties createdSubscription = await client.CreateSubscriptionAsync(subscriptionOptions);
This might be helpful for other readers as well as having similar doubuts.

An Application Connect with Multiple database and set Membership cookies

I'm writing a method that set all of database connection string with it.The method has some parameters like connection string and cookie domain (for single sign on state) , ...
I can get Membership and role Information with specified connection string that send as a parameter.
//membership
System.Web.Security.SqlMembershipProvider mp = new System.Web.Security.SqlMembershipProvider();
System.Collections.Specialized.NameValueCollection config_Membership = new System.Collections.Specialized.NameValueCollection();
config_Membership.Add("connectionString", connectionstring);
config_Membership.Add("applicationName", "/");
mp.Initialize("SQL_test_Membership", config_Membership);
var u = mp.GetUser(username, false);
int TotalRecords = 0;
var p = mp.GetAllUsers(0, 1, out TotalRecords);
//login
bool valid = mp.ValidateUser(username, password);
System.Web.Security.SqlRoleProvider rp = new System.Web.Security.SqlRoleProvider();
System.Collections.Specialized.NameValueCollection config_Role = new System.Collections.Specialized.NameValueCollection();
config_Role.Add("connectionString", connectionstring);
config_Role.Add("applicationName", "/");
rp.Initialize("SQL_test_Role", config_Role);
var roles = rp.GetRolesForUser(username);
I want to get ProfileBase Information like above code
https://technet.microsoft.com/nl-nl/library/system.web.profile.profilebase.initialize(v=vs.85).aspx
and I found below code:
System.Web.Profile.ProfileBase pro = new System.Web.Profile.ProfileBase();
System.Collections.Specialized.NameValueCollection config_profile = new System.Collections.Specialized.NameValueCollection();
config_profile.Add("connectionString", connectionstring);
config_profile.Add("applicationName", "/");
pro.Initialize(?????)
but I dont know how to send parameter to pro.Initialize(), can any one help me? Thanks.
My problem solved. My code was changed :
//login
bool valid = mp.ValidateUser(username, password);
if (valid)
{
System.Web.Profile.ProfileBase pro = new System.Web.Profile.ProfileBase();
System.Collections.Specialized.NameValueCollection config_profile = new System.Collections.Specialized.NameValueCollection();
config_profile.Add("connectionString", connectionstring);
config_profile.Add("applicationName", "/");
pro.Initialize(username, true);
string Name = pro.GetPropertyValue("Name").ToString();
string Family = pro.GetPropertyValue("Family").ToString();
string phone = pro.GetPropertyValue("Phone").ToString();
string address = pro.GetPropertyValue("Address").ToString();
}

ONVIF api capture image in C#

I have an ONVIF ip camera.
I want to to capture an image from the camera so that I can process that image and save it to the file system.
I found out that there is an onvif api which provides a method GetSnapshotUri which should provide me with an image snapshot:
http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
I managed to import this api in visual studio by adding a service reference to it:
How do I construct a client to call GetSnapshotUri from this service?
So, after lots of searching I managed to capture an image from the camera.
The first Problem was that I have used "Add Service Reference->Advanced->Add Web reference" instead of typing the service address directly in the "Add Service Reference" box.
Here, I added the address: http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
Then I could use the MediaClient class, correctly pointed out by pepOS in a comment, and the final code looks like:
var messageElement = new TextMessageEncodingBindingElement();
messageElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();
httpBinding.AuthenticationScheme = AuthenticationSchemes.Basic;
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
EndpointAddress mediaAddress = new EndpointAddress("http://192.168.1.168:10001/onvif/Media");
MediaClient mediaClient = new MediaClient(bind, mediaAddress);
mediaClient.ClientCredentials.UserName.UserName = "admin";
mediaClient.ClientCredentials.UserName.Password = "admin";
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[1].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
The uri of the image could then be fount at the MediaUri.Uriaddress
The GetSnapshotUri returns a uri for downloading an image using HTTP get.
So in theory you just need to call this function, and use the returned uri in the function shown in this Stackoverflow article:
https://stackoverflow.com/a/3615831/4815603
I am using onvif device manager dll here. To implement this method camera's IP, username and password must be known.
// Onvif ODM
using onvif.services;
using odm.core;
using onvif.utils;
using utils;
public string GetSnapshotUrl()
{
try
{
string camera_ip = "http://" + camIp + "/onvif/device_service";
Uri Camuri = new Uri(camera_ip);
NvtSessionFactory sessionFactory = new NvtSessionFactory(account);
INvtSession session = sessionFactory.CreateSession(Camuri);
Profile[] Profiles = session.GetProfiles().RunSynchronously();
var snapshotlink = session.GetSnapshotUri(Profiles[0].token).RunSynchronously(); // taking snapshot on the first profile of the camera
return snapshotlink.uri;
}
catch (Exception ex)
{
return null;
}
}
For me basic authentication didn't work. The following code works for me and downloads the image:
string username = "username";
string password = "password";
string cameraIP = "";
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(
EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
MediaClient mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraIP}/onvif/device_service"));
mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = username;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[0].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
WebClient webCl = new WebClient()
{
Credentials = new NetworkCredential(username, password)
};
webCl.DownloadFile(mediaUri.Uri, #"D:\test.jpg");

SSH terminal in a webapp using ASP.NET

Hello I creating a webapp that has a working SSH terminal similar to Putty. I'm using SSH Library as a means of handling the ssh stream. However there is a problem. I can log into a Cisco 2950 and type in commands but it comes out jumbled and in one line.
Also when I try "conf t" it gets into the configuration terminal but then you can't do anything and this pops up "Line has invalid autocommand "?".
Here is the code I have so far:
This is the SSH.cs that interacts with the library.
public class SSH
{
public string cmdInput { get; set; }
public string SSHConnect()
{
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
// jmccarthy is the username
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
var ssh = new SshClient(connectionInfo);
ssh.Connect();
var cmd = ssh.CreateCommand(cmdInput);
var asynch = cmd.BeginExecute(delegate(IAsyncResult ar)
{
//Console.WriteLine("Finished.");
}, null);
var reader = new StreamReader(cmd.OutputStream);
var myData = "";
while (!asynch.IsCompleted)
{
var result = reader.ReadToEnd();
if (string.IsNullOrEmpty(result))
continue;
myData = result;
}
cmd.EndExecute(asynch);
return myData;
}
}
This the code in the .aspx.cs that displays the code on the web page.
protected void CMD(object sender, EventArgs e)
{
SSH s = new SSH();
s.cmdInput = input.Text;
output.Text = s.SSHConnect();
}
Any help would be appreciated.
From looking through the test cases in the code for the SSH.NET library, you can use the RunCommand method instead of CreateCommand, which will synchronously process the command. I also added a using block for the SshClient ssh object since it implements iDisposable. Remember to call Disconnect as well so you don't get stuck with open connections.
Also the SshCommand.Result property (used in the command.Result call below), encapsulates the logic to pull the results from the OutputSteam, and uses this._session.ConnectionInfo.Encoding to read the OutputStream using the proper encoding. This should help with the jumbled lines you were receiving.
Here is an example:
public string SSHConnect() {
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
string myData = null;
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
using (SshClient ssh = new SshClient(connectionInfo)){
ssh.Connect();
var command = ssh.RunCommand(cmdInput);
myData = command.Result;
ssh.Disconnect();
}
return myData;
}

"An error occurred when verifying security for the message" exception when authenticating to ADFS

As I described in another question I build a web service that will take username/password and based on these credentials authenticate users (mobile apps) in ADFS2. My web service is configured as RP on the ADFS. ADFS issues SAML 2.0 tokens.
Here is a code of the web method:
public class MobileAuthService : IMobileAuthService
{
private const string adfsBaseAddress = #"https://<my_adfs_hostname>/adfs/services/";
private const string endpointSuffix = #"trust/13/issuedtokenmixedsymmetricbasic256";
public string AuthenticateUser(string username, string password)
{
var binding = new WS2007HttpBinding(SecurityMode.Message);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(adfsBaseAddress + endpointSuffix))
{
TrustVersion = TrustVersion.WSTrust13
};
trustChannelFactory.Credentials.UserName.UserName = username;
trustChannelFactory.Credentials.UserName.Password = password;
var tokenClient = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue, KeyTypes.Symmetric);
var token = tokenClient.Issue(rst);
// do some token-related stuff
return token.Id;
}
}
When I try to run it (GET call from browser since it's configured with web http binding for this endpoint) I get the following exception:
System.ServiceModel.Security.MessageSecurityException - "An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail."
with inner exception:
System.ServiceModel.FaultException - "An error occurred when verifying security for the message."
I guess it's related with the response signature or certificate but I have no idea how to overcome this since I'm quite new in WIF.
I've managed to (partly) solve this issue. I've changes few things in my code, but the problems seems to be related with:
STS endpoint -should be /trust/13/usernamemixed for this type of authentication
RST key type - when I've set it Bearer it started returning a SAML token
Here is my most recent version:
public class MobileAuthService : IMobileAuthService
{
private const string stsEndpointAddress = #"https://<my_adfs_hostname>/adfs/services/trust/13/usernamemixed";
private const string relyingPartyAddress =
"https://<my_service_addr>/Auth.svc";
public string AuthenticateUser(string username, string password)
{
var binding = new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential)
{
ClientCredentialType = HttpClientCredentialType.None
};
var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(stsEndpointAddress))
{
TrustVersion = TrustVersion.WSTrust13
};
var channelCredentials = trustChannelFactory.Credentials;
channelCredentials.UserName.UserName = username;
channelCredentials.UserName.Password = password;
channelCredentials.SupportInteractive = false;
var tokenClient = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue, KeyTypes.Bearer)
{
AppliesTo = new EndpointReference(relyingPartyAddress),
ReplyTo = relyingPartyAddress,
TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
};
// to some token-related stuff (like transformations etc...)
}
}
I hope this will help people who ends up with similar problem.

Categories