Unable to connect to OnVif enabled camera using C#

一世执手 提交于 2020-01-02 07:36:33

问题


I am working with IPCams for the first time and I am trying to connect to an OnVif camera. I have looked on various forums and stack overflow and I have come up with the following code.I know the code doesn't do anything useful but it is just a proof of concept for now. It finds all 4 cameras on my network and then I am manually connecting to one of them to pull back some information such as GetServices.

I get a 400 bad response error at this stage. I have looked at the traffic back and forth with WireShark and it appears that everything is working ok regarding the password being generated in so far as I can tell (security and encryption is not my area at all!).

Can anyone help or advise?

class Program
{

    static void Main(string[] args)
    {
        var endPoint = new UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);

        var discoveryClient = new DiscoveryClient(endPoint);

        discoveryClient.FindProgressChanged += discoveryClient_FindProgressChanged;

        discoveryClient.FindCompleted += discoveryClient_FindCompleted;

        FindCriteria findCriteria = new FindCriteria();
        findCriteria.Duration = new TimeSpan(0, 0, 2);//TimeSpan.MaxValue;
        findCriteria.MaxResults = int.MaxValue;
        discoveryClient.FindAsync(findCriteria);

        Console.ReadKey();
    }

    private static void discoveryClient_FindCompleted(object sender, FindCompletedEventArgs e)
    {
        Console.WriteLine("Discovery complete");
    }

    static void discoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
    {

        foreach (var u in e.EndpointDiscoveryMetadata.ListenUris)
        {

            string uri = u.OriginalString;

            if (uri.Contains("http://192.168.1.162/onvif/device_service"))
            {

                Console.WriteLine(uri);

                EndpointAddress serviceAddress = new EndpointAddress(uri);

                HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();

                httpBinding.AuthenticationScheme = AuthenticationSchemes.Digest;

                var messegeElement = new TextMessageEncodingBindingElement();

                messegeElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);

                CustomBinding bind = new CustomBinding(messegeElement, httpBinding);

                DeviceClient client = new DeviceClient(bind, serviceAddress);

                // Add our custom behavior - this require the Microsoft WSE 3.0 SDK
                PasswordDigestBehavior behavior = new PasswordDigestBehavior("test", "test");

                client.Endpoint.Behaviors.Add(behavior);

                foreach (Service s in client.GetServices(false))
                    Console.WriteLine(s.ToString());

                client.Open();

                Console.WriteLine("WSDL = " + client.GetWsdlUrl());
                Console.WriteLine("DateTime = " + client.GetSystemDateAndTime());

                string a1, b1, c1, d1;
                Console.Write(client.GetDeviceInformation(out a1, out b1, out c1, out d1));

            }
        }
    }
}

Wireshark (username and passwor are both test)

POST /onvif/device_service HTTP/1.1

Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/GetServices"

Host: 192.168.1.162

Content-Length: 1232

Expect: 100-continue

Accept-Encoding: gzip, deflate

Connection: Keep-Alive



<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo7uVma6HRQNDh2l6T2ZDNzIAAAAA2/ITWE91IUaNFF3UObayz0mz6QvnZppBlYrNJBd1QGsACQAA</VsDebuggerCausalityData>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="SecurityToken-56f9081e-e9b4-4660-9158-7419af1efde0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>test</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">WSKWE5XjP5aPiIiA9JicCOYoDkU=</wsse:Password>
        <wsse:Nonce>6sYgS41VHsWKj7n8TNKFjA==</wsse:Nonce>
        <wsu:Created>2013-08-09T14:52:45Z</wsu:Created>
      </wsse:UsernameToken>
    </Security>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetServices xmlns="http://www.onvif.org/ver10/device/wsdl">
      <IncludeCapability>false</IncludeCapability>
    </GetServices>
  </s:Body>
</s:Envelope>HTTP/1.1 400 Bad Request

Server: gSOAP/2.7

Content-Type: application/soap+xml; charset=utf-8

Content-Length: 2751

Connection: close



<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" xmlns:aa="http://www.axis.com/vapix/ws/action1" xmlns:aev="http://www.axis.com/vapix/ws/event1" xmlns:tan1="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" xmlns:tan2="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tev1="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" xmlns:tev2="http://www.onvif.org/ver10/events/wsdl/EventBinding" xmlns:tev3="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:tev4="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tnsaxis="http://www.axis.com/2009/event/topics">
  <SOAP-ENV:Header>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo7uVma6HRQNDh2l6T2ZDNzIAAAAA2/ITWE91IUaNFF3UObayz0mz6QvnZppBlYrNJBd1QGsACQAA</VsDebuggerCausalityData>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
      <SOAP-ENV:Code>
        <SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
        <SOAP-ENV:Subcode>
          <SOAP-ENV:Value>ter:NotAuthorized</SOAP-ENV:Value>
        </SOAP-ENV:Subcode>
      </SOAP-ENV:Code>
      <SOAP-ENV:Reason>
        <SOAP-ENV:Text xml:lang="en">Sender not authorized</SOAP-ENV:Text>
      </SOAP-ENV:Reason>
      <SOAP-ENV:Detail>
        <SOAP-ENV:Text>The action requested requires authorization and the sender is not authorized</SOAP-ENV:Text>
      </SOAP-ENV:Detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I have onvif enabled on the camera (by creating an administrator user called "test" with a password "test". The camera password is the default "root" and "pass" as it is an Axis camera.


回答1:


Configure the connection to the camera this way:

    ServicePointManager.Expect100Continue = false;
    var endPointAddress = new EndpointAddress("http://" + cameraAddress + "/onvif/device_service");
    var httpTransportBinding = new HttpTransportBindingElement { AuthenticationScheme = AuthenticationSchemes.Digest };
    var textMessageEncodingBinding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None) };
    var customBinding = new CustomBinding(textMessageEncodingBinding, httpTransportBinding);
    var passwordDigestBehavior = new PasswordDigestBehavior(adminName, adminPassword);
    var deviceClient = new DeviceClient(customBinding, endPointAddress);
    deviceClient.Endpoint.Behaviors.Add(passwordDigestBehavior);

I know it's almost what you have done but it is important to make ServicePointManager.Expect100Continue false.




回答2:


Check if the camera have the replay attack protection enabled. If so check the time difference between your computer's time and the camera's. According to the ONVIF's specs the allowed time difference must be +- 5 seconds. Otherwise you get your error.

If this is your case you have several options:

1- Disable the replay attack protection feature. This is not recommended because you would need to disable this feature in all the cameras you need to work with.

2- You can sync the camera's time with your computer time. Again not recommended for the same issue of the first option.

3- If you can change the WSE 3.0 for other option. In WSE3.0 once you have created the UsernameToken you can't change the Created property, which is used to create the encryption. This problem is described in here



来源:https://stackoverflow.com/questions/18149866/unable-to-connect-to-onvif-enabled-camera-using-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!