RTSP: Not receiving SDP from the server after sending "describe" request - camera

I have a Bosch camera(server) and my end goal is to get the video content description via metadata from it. I am using LwIP Raw API's(1.4.0) for this purpose. At present, I am trying to authenticate with the camera and receive the SDP so I can setup the session. However, after I authenticate by resending the describe request with the digest, I don't get any response from the server and after a while the server resets the connection. Below is the sequence of operations I perform for authentication.
Step 1: Client to Server (mcu sends 1st describe request)
DESCRIBE rtsp://service:PRBUWPCs7*f40j#192.168.1.129/?enablevideo=0&vcd=1 RTSP/1.0
CSeq: 1
User-Agent: rtsp://service:PRBUWPCs7*f40j#192.168.1.129(LIVE555 Streaming Media v2018.02.28)
Accept: application/sdp
Step 2: Server to Client (server responds with nonce for authentication, rx via callback)
Payload:RTSP/1.0 401 Unauthorized
CSeq: 1
WWW-Authenticate: Digest realm="Please log in with a valid
username",nonce="7bd251bb670e45966c415838679f778f",opaque="",stale=FALSE,algorithm=MD5
Step 3: Client to Server (mcu computes the response and resends the describe command )
DESCRIBE rtsp://service:PRBUWPCs7*f40j#192.168.1.129/?enablevideo=0&vcd=1 RTSP/1.0
CSeq: 2
Authorization: Digest username="service", realm="Please log in with a valid username", nonce="7bd251bb670e45966c415838679f778f", uri="rtsp://service:PRBUWPCs7*f40j#192.168.1.129/?enablevideo=0&vcd=1", response="4c87974de2e3ecc3d534beddef9e6962"
User-Agent: rtsp://service:PRBUWPCs7*f40j#192.168.1.129(LIVE555 Streaming Media v2018.02.28)
Accept: application/sdp
Step 4: mcu waiting for SDP, but instead receives pbuf *p as null in the receive call back function.
After a few seconds, also receives a tcp err callback with err code ERR_RST i.e. connection reset.
Could anyone please clarify if my above procedure is correct and if so, any insights on what could likely cause the camera not to respond with the SDP description leading to connection reset and receiving pbuff as NULL in the receive callback? 

Fixed it. There was an issue with md5 module.

Related

FIWARE CEP (Proton) REST ouput authentication error

I'm training to send an output event from FIWARE CEP (Proton), using the REST consumer, to an ActiveMQ queue. The credential for access the ActiveMQ queue are included in the URL, as http://user:passwrd#X.X.X.X:xxxx/api/message/myqueue, but I have the following error:
com.ibm.hrl.proton.webapp.resources.EventResource submitNewEvent
INFO: events sent to proton runtime...
org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme
INFO: basic authentication scheme selected
org.apache.commons.httpclient.HttpMethodDirector processWWWAuthChallenge
INFO: No credentials available for BASIC 'ActiveMQRealm'#X.X.X.X
com.ibm.hrl.proton.server.executorServices.SimpleThreadFactory$ProtonExceptionHandler uncaughtException
SEVERE: Uncaught exception in thread: Thread[4,5,main],exception: com.ibm.hrl.proton.adapters.rest.client.RESTException: com.ibm.hrl.proton.adapters.rest.client.RESTException: Could not perform POST of event instance: ...
with request headers:
Content-Type: text/plain
User-Agent: Jakarta Commons-HttpClient/3.0
Host: X.X.X.X:xxxx
Content-Length: 389
to consumer http://user:passwrd#X.X.X.X:xxx/api/message/myqueue, responce result: 401
Seems like that Proton doesn't extract the credential from the URL.
Anyone else had the same problem?
You can add to the CEP REST consumer definition an AuthToken parameter.
From the CEP user guide (can be found here):
AuthToken – an optional parameter. When set, it is added as an X-Auth-Token
HTTP header of the request.

Possible to emulate flow control in HTTP protocol ? (raw HTTP protocol)

I have hundreds of hardware devices at customers which need to send HTTP data through a telnet interface.
The destination is an Apache 2 Webserver with a PHP script waiting for the data.
This is already working however we found that the hardware involved is not able to handle hw-flow-control, this means that once data is filled (around 250 bytes) the buffer can overflow resulting in data corruption.
Fixing the HW-flow is not an option, the "modem" firmware is closed and can not be modified by the vendor anymore as it's quite old hardware.
Normally we'd use this:
POST / HTTP/1.1
Host: api.server
User-Agent: P8
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 767
VARIABLE=URLENCODED_DATA(total length 767 bytes)
This would work perfectly fine with flow-control, but in my case the 767 bytes are too much.
After around 200 bytes buffers would be overwritten and some bytes are lost.
The only current way to get it working now was using a delay when sending to the "modem" so it can empty it's buffers in time. However in the field this will not work due to instable internet connections with unpredictable timings.
I am not an expert in HTTP, I just hope it is possible to fragment a package.
I thought about using "Connection: keep-alive" or something similar.
My main question:
Is there a way to send POST data ($VARIABLE) to a Apache 2 server in smaller chunks in a way that makes the HTTP server combine them to one stream internally ?
Pseudo code:
POST / HTTP/1.1
Host: api.server
User-Agent: P8
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 400
Connection: keep-alive
VARIABLE=URLENCODED_DATA(200 bytes)
END\n\n
Server responds in TCP stream once received with "OK".
Next chunk is sent:
VARIABLE=URLENCODED_DATA(200 bytes)
Connection is closed.
As 400 bytes have been reached the process is ready, Apache forwards VARIABLE to PHP scripts POST input.
So like a HTTP flow-control within an open TCP connection.
Maybe there is a HTTP feature which is built for that purpose, or something that can be "ab"used to act in that way. keep-alive was just a guess.
If current HTTP protocols do not have such a feature the only way I can think about solving my issue is to implement flow-control on PHP side.
I hope for a better way than that though.
Update:
Meanwhile I found two interesting parameters:
Expect: 100-continue
Transfer-Encoding: chunked
What I would need is a mix of both.
A chunked transfer encoding which is expecting a 100-continue after each chunk !
This is a very interesting question, and it really has nothing to do with HTTP but with TCP.
The way to solve this is to use an intermediary proxy that takes care of spoon-feeding your devices. Ideally, this device will be able to set the window size on the TCP packet ACKs to whatever the size of the buffer the device is. That window size will close to zero when the device cannot handle any more. If you do this, you will be utilizing TCP's built-in flow control and solve the problem in a simple way.
Another thing you can do is keep this entirely in the application layer and have this intermediary proxy buffer all of the data from the response. For most normal HTTP responses this will be okay.

Why does a browser in a different domain not respond at all to "WWW Authenticate : Negotiate" header sent by mod_auth_kerb?

I have implemented SSO through mod_auth_kerb in our apache-active directory environment and it works just as expected. However the following knowledge is bugging me :
I requested a Kerberos protected page from two client machines, one user belonged to the Kerberos-setup domain and the other user belonged to some other domain.
I then compared the HTTP packets on the two machines. On both the machines, after the request for the Kerberos protected page is sent, the server responds with the following HTTP packet :
HTTP/1.1 401 Authorization Required
Date: Wed, 05 Sep 2012 14:25:20 GMT
Server: Apache WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="Kerberos Login"
Content-Length: 60
Connection: close
Content-Type: text/html; charset=iso-8859-1
However, after the above response from the server the client machine's browser belonging to the Kerberos-setup domain responds with a WWW-Authenticate : Negotiate 'token', whereas the other client browser(user belonging to some other domain) does not respond at all.
Now my understanding is, that the client belonging to the other domain should have also responded with its own TGT+Session key token, which the active directory should have rejected. But why this client does not respond at all to the server's WWW-Authenticate : Negotiate challenge is beyond my logic.
What is even more confusing is that the server's HTTP response(given above), does not contain any information about the domain it is linked to.
So on what basis is the client browser belonging to the correct domain decide that it has to respond to the server's WWW-Authenticate : Negotiate challenge, and on what basis does the client belonging to some other domain decide not to respond to the same ?
Note : Both the client machines have Windows 7 and active directory is a Windows 2008 server.
I am trying to understand mod_auth_kerb's implementation of SSO, and this particular knowledge is key to that.
The module has the option KrbMethodK5Passwd turned on. It sends a Basic header to collect you Kerberos credentials. This is pointless for a non-domain client. Disable this option.
There is a hierarchy of strengths of auth mechanisms, the browser is obliged to choose the best. This is: Negotiate, Digest, NTLM, Basic.

Websocket and Safari 6.0

I am using Safari 6 and websockets. My server is receiving the following handshake from the browser:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: nomad.local:1299
Origin: file://
Sec-WebSocket-Key: WhZTuybN4i2ZshDBxco42w==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
There is no Protocol included. My server can deal with that, but when it tries to complete the handshake with the browser client I get the following message:
Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch
Is there an implied Protocol in the message sent to server that I need to return in the handshake to the client?
This worked before I upgraded to latest Safari
If the client does not send any sub-protocols in the handshake (Sec-WebSocket-Protocol) then the server must not send back a sub-protocol header (Sec-WebSocket-Protocol). If the server sends back the common default of "Sec-WebSocket-Protocol: chat" even though the client did not include a sub-protocol header, the client must refuse the connection. Some browsers were sloppy about this and have recently begun to tighten up their compliance.
If the client does send a sub-protocol list, then the server must select a single sub-protocol that it supports and send this back to the client as the chosen sub-protocol.
Well the protocol is WebSockets ;-) See the RFC for further explanations on Sec-WebSocket-Protocol: http://datatracker.ietf.org/doc/rfc6455/?include_text=1
The handshake from the client looks as follows:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
The handshake from the server looks as follows:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Don't know wether the Safari 6 implemenation differs, but protocols from RFC are usually a nightmare... There might be a standard implied?

Authentication on a very low level TCP Server written for Node.JS?

How do I implement something similar to the HTTP Basic authentication, in a TCP server written for Node.JS ? The code for a basic TCP server is the following:
// Load the net module to create a tcp server.
var net = require('net');
// Setup a tcp server
var server = net.createServer(function (socket) {
// Every time someone connects, tell them hello and then close the connection.
socket.addListener("connect", function () {
console.log("Connection from " + socket.remoteAddress);
socket.end("Hello World\n");
});
});
// Fire up the server bound to port 7000 on localhost
server.listen(7000, "localhost");
// Put a friendly message on the terminal
console.log("TCP server listening on port 7000 at localhost.");
While there are several ways to provide authentication over a TCP connection, all require some form of "protocol" being an agreed-upon communications grammar/syntax.
For example, in the Simple Mail Transport Protocol, the following conversation occurs (where S: and C: designate lines provided by the SMTP server and email client, respectively):
S: 220 server.example.com
C: HELO client.example.com
S: 250 server.example.com
C: MAIL FROM:<sender#example.com>
S: 250 2.1.0 sender#example.com... Sender ok
C: RCPT TO:<recipient#example.com>
S: 250 recipient <recipient#example.com> OK
C: DATA
S: 354 enter mail, end with line containing only "."
C: full email message appears here, where any line
C: containing a single period is sent as two periods
C: to differentiate it from the "end of message" marker
C: .
S: 250 message sent
C: QUIT
S: 221 goodbye
In replies from the server, the initial numeric value indicates the success or failure of the requested operation, or that the reply contains an informational message. Using a three digit numeric value allows for efficient parsing as all replies beginning with 2xx indicate success, 3xx are informational, 4xx indicate protocol errors, and 5xx are reserved for server errors. See IETF RFC 5321 - https://www.rfc-editor.org/rfc/rfc5321 for the full protocol.
So in your specific case, you might consider something as simple as:
[connect to TCP server]
S: ? # indicates the server is ready for authorization
C: username password # send authentication credentials
The server would then reply with:
S: ! # indicates successful authentication and
# that server is ready for more commands
Or
S: ? # indicates authentication failure
If too many failed attempts to authenticate are seen, the server might sever the connection to reduce the potential for abuse, such as DDOS attacks.
Once authenticated, the client could send:
C: > # begin streaming
Or any other command you which to support.