Usage examples tls-interaction property for rtspsrc and souphttpsrc

enthusiastic geek enthusiasticgeek at gmail.com
Sat Oct 7 15:17:05 UTC 2017


I did all those things I have no idea why it is not working

Here is the full source

*rtsp_client.c*

//First run 
// ./rtsp_server
//Second run 
//./rtsp_client rtsps://127.0.0.1:8554/test


//Display RTSP streaming of video 
 //(c) 2011 virgo 
 // This code is distributed in the hope that it will be useful, 
 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   

#include <string.h>
#include <math.h>
#include <gst/gst.h>
#include <glib.h>
#include <gio/gio.h>
#include "surveillance-tls-interaction.h"

static gboolean bus_call (GstBus *bus,GstMessage *msg, gpointer data){ 
  GMainLoop *loop = (GMainLoop *) data; 

  switch (GST_MESSAGE_TYPE (msg)) { 

    case GST_MESSAGE_EOS: 
      g_print ("Stream Ends\n"); 
      g_main_loop_quit (loop); 
      break; 

    case GST_MESSAGE_ERROR: { 
      gchar  *debug; 
      GError *error; 

      gst_message_parse_error (msg, &error, &debug); 
      g_free (debug); 

      g_printerr ("Error: %s\n", error->message); 
      g_error_free (error); 

      g_main_loop_quit (loop); 
      break; 
    } 
    default: 
      break; 
  } 

  return TRUE; 
} 

static void on_pad_added (GstElement *element, GstPad *pad, gpointer data){ 

  GstPad *sinkpad; 
  GstElement *decoder = (GstElement *) data; 

  /* We can now link this pad with the rtsp-decoder sink pad */ 
  g_print ("Dynamic pad created, linking source/demuxer\n"); 

  sinkpad = gst_element_get_static_pad (decoder, "sink"); 

  gst_pad_link (pad, sinkpad); 

  gst_object_unref (sinkpad); 
} 


int main (int argc, char *argv[]) 
{ 
  GMainLoop *loop; 
  GstBus *bus; 
  GstElement *source; 
  GstElement *decoder; 
  GstElement *sink; 
  GstElement *pipeline; 
  GstElement *demux; 
  GstElement *parse; 
  GstElement *videoconvert; 

  GTlsConnection *conn;


  /* Initializing GStreamer */ 
  gst_init (&argc, &argv); 
  loop = g_main_loop_new (NULL, FALSE); 

 //gst-launch-0.10 rtspsrc location=rtsp://<ip> ! decodebin !
ffmpegvideoconvert ! autovideosink 
 //gst-launch -v rtspsrc location="rtsp://<ip> ! rtpmp4vdepay !
mpeg4videoparse ! ffdec_mpeg4 ! ffmpegvideoconvert! autovideosink 
 //gst-launch -v rtspsrc location="rtsp://<ip> ! rtpmp4vdepay ! ffdec_mpeg4
! ffmpegvideoconvert! autovideosink 
  /* Create Pipe's Elements */ 
  pipeline = gst_pipeline_new ("video player"); 
  g_assert (pipeline); 
  source   = gst_element_factory_make ("rtspsrc", "Source"); 
  g_assert (source); 
  demux = gst_element_factory_make ("rtph264depay", "Depay"); 
  g_assert (demux); 
  parse = gst_element_factory_make ("h264parse", "Parse"); 
  g_assert (parse); 
  decoder = gst_element_factory_make ("avdec_h264", "Decoder"); 
  g_assert (decoder); 
  videoconvert     = gst_element_factory_make ("videoconvert",
"VideoConvert"); 
  g_assert(videoconvert); 
  sink     = gst_element_factory_make ("autovideosink", "Output"); 
  g_assert (sink); 

  /*Make sure: Every elements was created ok*/ 
  if (!pipeline || !source || !demux || !parse || !decoder || !videoconvert
|| !sink) { 
    g_printerr ("One of the elements wasn't create... Exiting\n"); 
    return -1; 
  } 

  g_print(" \nPipeline is Part(A) ->(dynamic/runtime link)  Part(B)[
Part(B-1) -> Part(B-2) -> Part(B-3) ]\n\n"); 
  g_print("
[source](dynamic)->(dynamic)[demux]->[parse]->[decoder]->[videoconvert]->[videosink]
\n\n"); 

  /* Set video Source */ 
  g_object_set (G_OBJECT (source), "location", argv[1], NULL); 
  //g_object_set (G_OBJECT (source), "do-rtcp", TRUE, NULL); 
  //g_object_set (G_OBJECT (source), "latency", 0, NULL); 
  g_object_set (G_OBJECT (source), "user-id", "user", NULL); 
  g_object_set (G_OBJECT (source), "user-pw", "password", NULL); 


/*

typedef enum {
  G_TLS_CERTIFICATE_UNKNOWN_CA    = (1 << 0),
  G_TLS_CERTIFICATE_BAD_IDENTITY  = (1 << 1),
  G_TLS_CERTIFICATE_NOT_ACTIVATED = (1 << 2),
  G_TLS_CERTIFICATE_EXPIRED       = (1 << 3),
  G_TLS_CERTIFICATE_REVOKED       = (1 << 4),
  G_TLS_CERTIFICATE_INSECURE      = (1 << 5),
  G_TLS_CERTIFICATE_GENERIC_ERROR = (1 << 6),

  G_TLS_CERTIFICATE_VALIDATE_ALL  = 0x007f
} GTlsCertificateFlags;
G_TLS_CERTIFICATE_UNKNOWN_CA
	The signing certificate authority is not known.

G_TLS_CERTIFICATE_BAD_IDENTITY
	The certificate does not match the expected identity of the site that it
was retrieved from.

G_TLS_CERTIFICATE_NOT_ACTIVATED
	The certificate's activation time is still in the future

G_TLS_CERTIFICATE_EXPIRED
	The certificate has expired

G_TLS_CERTIFICATE_REVOKED
	The certificate has been revoked according to the GTlsConnection's
certificate revocation list.

G_TLS_CERTIFICATE_INSECURE
	The certificate's algorithm is considered insecure.

G_TLS_CERTIFICATE_GENERIC_ERROR
	Some other error occurred validating the certificate

G_TLS_CERTIFICATE_VALIDATE_ALL
	the combination of all of the above flags 
*/


  //g_object_set (G_OBJECT (source), "protocols" ,0x00000020, NULL);
  // generic error 
  //g_object_set (G_OBJECT (source), "tls-validation-flags",
G_TLS_CERTIFICATE_GENERIC_ERROR, NULL); 
  //validate all 
  //g_object_set (G_OBJECT (source), "tls-validation-flags",
G_TLS_CERTIFICATE_VALIDATE_ALL, NULL); 
  //insecure
  //g_object_set (G_OBJECT (source), "tls-validation-flags",
G_TLS_CERTIFICATE_INSECURE, NULL); 
  GTlsCertificate *cert; 
  GError *error=NULL; 
  cert =
g_tls_certificate_new_from_files("/home/virgo/gstreamer/cert/toyIntermediate.pem","/home/virgo/gstreamer/cert/toyDecryptedIntermediate.key",&error); 
  //cert =
g_tls_certificate_new_from_files("/home/virgo/gstreamer/cert/toyCA.pem","/home/virgo/gstreamer/cert/toyCA.key",&error); 
  if (cert == NULL) { 
    g_printerr ("failed to parse PEM: %s\n", error->message); 
    return -1; 
  } 
  //GTlsDatabase* database = g_tls_file_database_new
("/home/virgo/gstreamer/cert/toyCA.pem", &error); 
  
  GTlsCertificate *ca_cert; 
  ca_cert =
g_tls_certificate_new_from_file("/home/virgo/gstreamer/cert/toyCA.pem",&error); 
  if (ca_cert == NULL) { 
    g_printerr ("failed to parse CA PEM: %s\n", error->message); 
    return -1; 
  } 

  //g_object_set (G_OBJECT (source), "tls-database", database, NULL); 
  SurveillanceTlsInteraction *interaction =
  surveillance_tls_interaction_new (cert, ca_cert);

  g_object_set (G_OBJECT (source), "tls-interaction", interaction, NULL); 

  /* Putting a Message handler */ 
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 
  gst_bus_add_watch (bus, bus_call, loop); 
  gst_object_unref (bus); 

  /* Add Elements to the Bin */ 
  gst_bin_add_many (GST_BIN (pipeline), source, demux, parse, decoder,
videoconvert, sink, NULL); 

  /* Link confirmation */ 
  if (!gst_element_link_many (demux, parse, decoder, videoconvert, sink,
NULL)){ 
     g_warning ("Linking part (B) Fail..."); 
  } 

  g_print("\nNote that the source will be linked to the demuxer(depayload)
dynamically.\n" 
     "The reason is that rtspsrc may contain various elements (for
example\n" 
     "audio and video). The source pad(s) will be created at run time,\n" 
     "by the rtspsrc when it detects the amount and nature of elements.\n" 
     "Therefore we connect a callback function which will be executed\n" 
     "when the \"pad-added\" is emitted.\n"); 

  /* Dynamic Pad Creation */ 
  if(! g_signal_connect (source, "pad-added", G_CALLBACK
(on_pad_added),demux)) 
  { 
    g_warning ("Linking part (A) with part (B) Fail..."); 
  } 
  /* Run the pipeline */ 
  g_print ("Playing: %s\n", argv[1]); 
  gst_element_set_state (pipeline, GST_STATE_PLAYING); 
  g_main_loop_run (loop); 

  /* Ending Playback */ 
  g_print ("End of the Streaming... ending the playback\n"); 
  gst_element_set_state (pipeline, GST_STATE_NULL); 

  /* Eliminating Pipeline */ 
  g_print ("Eliminating Pipeline\n"); 
  gst_object_unref (GST_OBJECT (pipeline)); 

  return 0; 
}                         

*rtsp_server.c*


#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gio/gio.h>

/* define this if you want the resource to only be available when using 
 * user/password as the password */ 
#undef WITH_AUTH 
#define WITH_AUTH 1 

/* define this if you want the server to use TLS (it will also need
WITH_AUTH 
 * to be defined) */ 
#undef WITH_TLS 
#define WITH_TLS 1 

/* this timeout is periodically run to clean up the expired sessions from
the 
 * pool. This needs to be run explicitly currently but might be done 
 * automatically as part of the mainloop. */ 
static gboolean 
timeout (GstRTSPServer * server) 
{ 
  GstRTSPSessionPool *pool; 

  pool = gst_rtsp_server_get_session_pool (server); 
  gst_rtsp_session_pool_cleanup (pool); 
  g_object_unref (pool); 

  return TRUE; 
} 

int 
main (int argc, char *argv[]) 
{ 
  GMainLoop *loop; 
  GstRTSPServer *server; 
  GstRTSPMountPoints *mounts; 
  GstRTSPMediaFactory *factory; 
#ifdef WITH_AUTH 
  GstRTSPAuth *auth; 
  GstRTSPToken *token; 
  gchar *basic; 
  GstRTSPPermissions *permissions; 
#endif 
#ifdef WITH_TLS 
  GTlsCertificate *cert; 
  GTlsCertificate *ca_cert; 
  GError *error = NULL; 
#endif 

  gst_init (&argc, &argv); 

  loop = g_main_loop_new (NULL, FALSE); 

  /* create a server instance */ 
  server = gst_rtsp_server_new (); 

#ifdef WITH_AUTH 
  /* make a new authentication manager. it can be added to control access to
all 
   * the factories on the server or on individual factories. */ 
  auth = gst_rtsp_auth_new (); 
#ifdef WITH_TLS 
  g_print("Here in TLS portion\n");
  cert =
g_tls_certificate_new_from_files("/home/virgo/gstreamer/cert/toyIntermediate.pem","/home/virgo/gstreamer/cert/toyDecryptedIntermediate.key",&error); 
  //cert =
g_tls_certificate_new_from_files("/home/virgo/gstreamer/cert/toyCA.pem","/home/virgo/gstreamer/cert/toyCA.key",&error); 
  if (cert == NULL) { 
    g_printerr ("failed to parse PEM: %s\n", error->message); 
    return -1; 
  } 
  //GTlsDatabase* database = g_tls_file_database_new
("/home/virgo/gstreamer/cert/toyCA.pem", &error); 
  //gst_rtsp_auth_set_tls_database (auth, database); 
  //ca_cert =
g_tls_certificate_new_from_file("/home/virgo/gstreamer/cert/toyCA.pem",&error); 
  //if (ca_cert == NULL) { 
  //  g_printerr ("failed to parse CA PEM: %s\n", error->message); 
  //  return -1; 
  //} 
  //gst_rtsp_auth_set_tls_authentication_mode(auth,
G_TLS_AUTHENTICATION_REQUIRED); 
  //gst_rtsp_auth_set_tls_authentication_mode(auth,
G_TLS_AUTHENTICATION_REQUESTED); 
  //GTlsCertificateFlags verification = g_tls_certificate_verify(cert, NULL,
ca_cert); 
  //g_print("verification code = %d\n", verification); 
  gst_rtsp_auth_set_tls_certificate (auth, cert); 
  g_object_unref (cert); 
#endif 

  /* make user token */ 
  token = 
      gst_rtsp_token_new (GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, 
      "user", NULL); 
  basic = gst_rtsp_auth_make_basic ("user", "password"); 
  gst_rtsp_auth_add_basic (auth, basic, token); 
  g_free (basic); 
  gst_rtsp_token_unref (token); 

  /* configure in the server */ 
  gst_rtsp_server_set_auth (server, auth); 
#endif 

  /* get the mount points for this server, every server has a default object 
   * that be used to map uri mount points to media factories */ 
  mounts = gst_rtsp_server_get_mount_points (server); 

  /* make a media factory for a test stream. The default media factory can
use 
   * gst-launch syntax to create pipelines. 
   * any launch line works as long as it contains elements named pay%d. Each 
   * element with pay%d names will be a stream */ 
  factory = gst_rtsp_media_factory_new (); 
  gst_rtsp_media_factory_set_launch (factory, "( " 
      "videotestsrc ! video/x-raw,width=352,height=288,framerate=15/1 ! " 
      "x264enc ! rtph264pay name=pay0 pt=96 " 
      "audiotestsrc ! audio/x-raw,rate=8000 ! " 
      "alawenc ! rtppcmapay name=pay1 pt=97 " ")"); 
#ifdef WITH_AUTH 
  /* add permissions for the user media role */ 
  permissions = gst_rtsp_permissions_new (); 
  gst_rtsp_permissions_add_role (permissions, "user", 
      GST_RTSP_PERM_MEDIA_FACTORY_ACCESS, G_TYPE_BOOLEAN, TRUE, 
      GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT, G_TYPE_BOOLEAN, TRUE, NULL); 
  gst_rtsp_media_factory_set_permissions (factory, permissions); 
  gst_rtsp_permissions_unref (permissions); 
#ifdef WITH_TLS 
  gst_rtsp_media_factory_set_profiles (factory, GST_RTSP_PROFILE_SAVP); 
#endif 
#endif 

  /* attach the test factory to the /test url */ 
  gst_rtsp_mount_points_add_factory (mounts, "/test", factory); 

  /* don't need the ref to the mapper anymore */ 
  g_object_unref (mounts); 

  /* attach the server to the default maincontext */ 
  if (gst_rtsp_server_attach (server, NULL) == 0) 
    goto failed; 

  /* add a timeout for the session cleanup */ 
  g_timeout_add_seconds (2, (GSourceFunc) timeout, server); 

  /* start serving, this never stops */ 
#ifdef WITH_TLS 
  g_print ("stream ready at rtsps://127.0.0.1:8554/test\n"); 
#else 
  g_print ("stream ready at rtsp://127.0.0.1:8554/test\n"); 
#endif 
  g_main_loop_run (loop); 

  return 0; 

  /* ERRORS */ 
failed: 
  { 
    g_print ("failed to attach the server\n"); 
    return -1; 
  } 
} 

*I kept your surveillance-tls files same*

The certs are 

*toyCA.pem*

-----BEGIN CERTIFICATE-----
MIICxTCCAi4CCQCnMN2oz9uJbTANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMC
VVMxCzAJBgNVBAgMAk1EMRYwFAYDVQQHDA1TaWx2ZXIgU3ByaW5nMRUwEwYDVQQK
DAxoYXdrZXllZ3VhcmQxFTATBgNVBAsMDGhhd2tleWVndWFyZDEdMBsGA1UEAwwU
d3d3Lmhhd2tleWVndWFyZC5jb20xJTAjBgkqhkiG9w0BCQEWFmFkbWluQGhhd2tl
eWVndWFyZC5jb20wHhcNMTcwOTEwMTMwMDQ4WhcNMTgwOTEwMTMwMDQ4WjCBpjEL
MAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1EMRYwFAYDVQQHDA1TaWx2ZXIgU3ByaW5n
MRUwEwYDVQQKDAxoYXdrZXllZ3VhcmQxFTATBgNVBAsMDGhhd2tleWVndWFyZDEd
MBsGA1UEAwwUd3d3Lmhhd2tleWVndWFyZC5jb20xJTAjBgkqhkiG9w0BCQEWFmFk
bWluQGhhd2tleWVndWFyZC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
ANQD2yE+/VBnReE62XIr7V0yS4Ckc6hZAxYjZMKzs/fU7PNp6EHI66h4HLgZAP07
z+9UHF7oQYExJVdOmtIf+wTv6VSeF3UwP/q9XYqR5MQXh1+FfpHUWbC7d9BE5Azv
MWHLlxeuahJPaEeKkl2VAA6iS/8HjKRod+LFqNHov2u3AgMBAAEwDQYJKoZIhvcN
AQELBQADgYEAvpYKm/LtKmGwsPQeVMj6DDY1VRp45TTQkSiCMfY8ege4TXoWAc5I
6lAq3/+XSmNEBkb0LhhwmsDIxSU4BHPIulLLdi7VkwGjk/WKRUXITUWp1O8m94ga
ZynBX+pMzDcmtWkJ5oiwsb6/SlvWqXqUKVHyX3iSW5aMtMF5j4K9lWo=
-----END CERTIFICATE-----

*toyIntermediate.pem*

-----BEGIN CERTIFICATE-----
MIICvDCCAiUCAQEwDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNVBAYTAlVTMQswCQYD
VQQIDAJNRDEWMBQGA1UEBwwNU2lsdmVyIFNwcmluZzEVMBMGA1UECgwMaGF3a2V5
ZWd1YXJkMRUwEwYDVQQLDAxoYXdrZXllZ3VhcmQxHTAbBgNVBAMMFHd3dy5oYXdr
ZXllZ3VhcmQuY29tMSUwIwYJKoZIhvcNAQkBFhZhZG1pbkBoYXdrZXllZ3VhcmQu
Y29tMB4XDTE3MDkxMDEzMDM0MVoXDTI3MDkwODEzMDM0MVowgaUxCzAJBgNVBAYT
AlVTMQswCQYDVQQIDAJNRDEWMBQGA1UEBwwNU2lsdmVyIFNwcmluZzEUMBIGA1UE
CgwLaGF3ZXllZ3VhcmQxFTATBgNVBAsMDGhhd2tleWVndWFyZDEdMBsGA1UEAwwU
d3d3Lmhhd2tleWVndWFyZC5jb20xJTAjBgkqhkiG9w0BCQEWFmFkbWluQGhhd2tl
eWVndWFyZC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOPfvasAi1qe
E1JsimWzuFjf0xfCiiAzX264IJne6ywiUsmrZhbhkaW9xycTxft7+8LxFpDCPetE
B6a+eG8eMJt7SnHj6lPqXKposp77DauUJM+odt2LbWoYLXurE1E8YOUCleqIvwzO
p3UljYmU+OSlRpqvLcrnl7D5BLZJvj6hAgMBAAEwDQYJKoZIhvcNAQELBQADgYEA
Eom9e/0txvjZsdS3LXp/nWvtSV4tZFbDUVIyhnSBHXmKL7da05zqMRRXdvXH3cRH
jXSfijf4cJhETrEn44ucX5YM0WQSLEhsa7VWsOfXF6EUANt8f/fDUFRsZS+/Oppo
8KU5xhoIL4ZJxDLAhv+Fp4vZLefLeyq0x4ZEzzempIE=
-----END CERTIFICATE-----


*toyDecryptedIntermediate.key*

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDj372rAItanhNSbIpls7hY39MXwoogM19uuCCZ3ussIlLJq2YW
4ZGlvccnE8X7e/vC8RaQwj3rRAemvnhvHjCbe0px4+pT6lyqaLKe+w2rlCTPqHbd
i21qGC17qxNRPGDlApXqiL8Mzqd1JY2JlPjkpUaary3K55ew+QS2Sb4+oQIDAQAB
AoGADExZ/y2jV7uqTUuAWKbPbzR9Pw4HyF8damtTjxph1NrxXuL6OofoBWrtoaVG
jSEO4GGEl0F0eAsO4qfq9gxKETAM4i2XwATTgtppQFumaowy/vIQaiQmL3dHuGvn
PxxSrQ1DW9/fAGmFeu1CxtI6lQCaySvB9FgVAR8v+wOTY4UCQQD36HIYwTYzbi/C
Tk1o+bG/kTDDZsDQfLMGBudwndj8mwGKdhbcpkBYLqVQHsPSWdVaK7gbIQj5Scin
aNew5QiPAkEA60/jYxYuZGHx3Jhf+x1MXmq3f7VDaVjSd+Z5VMGJpqMewEFT6K+d
BHwb2VzRH4ZvQLKtaeq7jxo3DUbiLPn9zwJACBhTAXPtrSg/7vxXksH0h+jZysek
LCqmPeAj1o2Q9E6rcjYA8RuMplR/mWonwsqkKNmcnWYqwNkj8DOAN4qDCQJBAN44
lLHnqaotAR7lW4cnVQ65U0+sm9vqAOEwa5bKKzeORqUjTJ2q8urgVeCBEhDmgTwl
QTWMctIi3KiSL1hwQesCQA0nZbwaLBA+x0x825ejvWBAq10/A719Wyo+ZNkZwf1O
Hrl7YDVmb8S1+kxvK5czcnSQV9YJZDKzzOMmAZ4AC8I=
-----END RSA PRIVATE KEY-----







--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/


More information about the gstreamer-devel mailing list