Exemple #1
0
static int http_da_parse(struct soap *soap)
{ 
  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);

  if (!data)
    return SOAP_PLUGIN_ERROR;

  data->qop = NULL;

  /* HTTP GET w/o body with qop=auth-int still requires a digest */
  if (soap_smd_init(soap, &data->smd_data, SOAP_SMD_DGST_MD5, NULL, 0)
   || soap_smd_final(soap, &data->smd_data, data->digest, NULL))
    return soap->error;

  if ((soap->error = data->fparse(soap)))
    return soap->error;

  if (data->qop && !soap_tag_cmp(data->qop, "auth-int"))
  {
    if (soap->fpreparerecv != http_da_preparerecv)
    {
      data->fpreparerecv = soap->fpreparerecv;
      soap->fpreparerecv = http_da_preparerecv;
    }
    if (soap->fpreparefinalrecv != http_da_preparefinalrecv)
    {
      data->fpreparefinalrecv = soap->fpreparefinalrecv;
      soap->fpreparefinalrecv = http_da_preparefinalrecv;
    }
    if (soap_smd_init(soap, &data->smd_data, SOAP_SMD_DGST_MD5, NULL, 0))
      return soap->error;
  }
 
  return SOAP_OK;
}
/**
@fn int soap_smd_begin(struct soap *soap, int alg, const void *key, int keylen)
@brief Initiates a digest or signature computation.
@param soap context
@param[in] alg is the digest or signature (sign/verification) algorithm used
@param[in] key is a HMAC key or pointer to EVP_PKEY object or NULL for digests
@param[in] keylen is the length of the HMAC key or 0
@return SOAP_OK, SOAP_EOM, or SOAP_SSL_ERROR
*/
int
soap_smd_begin(struct soap *soap, int alg, const void *key, int keylen)
{ struct soap_smd_data *data;
  data = (struct soap_smd_data*)SOAP_MALLOC(soap, sizeof(struct soap_smd_data));
  if (!data)
    return soap->error = SOAP_EOM;
  /* save and set the engine's 'data' field to pass data to the callbacks */
  soap->data[0] = (void*)data;
  /* save and override the send and recv callbacks */
  data->fsend = soap->fsend;
  data->frecv = soap->frecv;
  soap->fsend = soap_smd_send;
  soap->frecv = soap_smd_recv;
  /* save the mode flag */
  data->mode = soap->mode;
  /* clear the IO flags and DOM flag */
  soap->mode &= ~(SOAP_IO | SOAP_IO_LENGTH | SOAP_ENC_ZLIB | SOAP_XML_DOM);
  /* clear the XML attribute store */
  soap_clr_attr(soap);
  /* load the local XML namespaces store */
  soap_set_local_namespaces(soap);
  if (soap->mode & SOAP_XML_CANONICAL)
    soap->ns = 0; /* for in c14n, we must have all xmlns bindings available */
  else if (!(alg & SOAP_SMD_PASSTHRU))
    soap->ns = 2; /* we don't want leading whitespace in serialized XML */
  /* init the soap_smd engine */
  return soap_smd_init(soap, data, alg, key, keylen);
}
Exemple #3
0
static int http_da_calc_HA1(struct soap *soap, struct soap_smd_data *smd_data, const char *alg, const char *userid, const char *realm, const char *passwd, const char *nonce, const char *cnonce, char HA1hex[65])
{
  int smd_alg = SOAP_SMD_DGST_MD5;
  size_t smd_len = 16;
  char HA1[32];

  if (alg && !soap_tag_cmp(alg, "SHA-256*"))
  {
    smd_alg = SOAP_SMD_DGST_SHA256;
    smd_len = 32;
  }

  if (soap_smd_init(soap, smd_data, smd_alg, NULL, 0)
   || soap_smd_update(soap, smd_data, userid, strlen(userid))
   || soap_smd_update(soap, smd_data, ":", 1)
   || soap_smd_update(soap, smd_data, realm, strlen(realm))
   || soap_smd_update(soap, smd_data, ":", 1)
   || soap_smd_update(soap, smd_data, passwd, strlen(passwd))
   || soap_smd_final(soap, smd_data, HA1, NULL))
    return soap->error;

  if (alg && !soap_tag_cmp(alg, "*-sess"))
  {
    if (soap_smd_init(soap, smd_data, smd_alg, NULL, 0)
     || soap_smd_update(soap, smd_data, HA1, smd_len))
      return soap->error;

    if (nonce)
    {
      if (soap_smd_update(soap, smd_data, ":", 1)
       || soap_smd_update(soap, smd_data, nonce, strlen(nonce)))
        return soap->error;
    }

    if (soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, cnonce, strlen(cnonce))
     || soap_smd_final(soap, smd_data, HA1, NULL))
      return soap->error;
  }

  (void)soap_s2hex(soap, (unsigned char*)HA1, HA1hex, smd_len);

  return SOAP_OK;
};
/* Most of this function is taken from the function 'soap_wsse_add_UsernameTokenDigest()' defined in wsseapi.cpp //
// Used to alter the soap request for an offset time (for authorization purposes - replay attack protection) */
int OnvifClientDevice::LocalAddUsernameTokenDigest(struct soap *soapOff,double cam_pc_offset) 
{
	string strUrl;
	string strUser;
	string strPass;
	if (this->GetUserPasswd(strUser, strPass) == false 
			|| this->GetUrl(strUrl) == false)
	{
		return SOAP_ERR;
	}
	/* start soap_wsse_add_UsernameTokenDigest; Taken from wsseapi.cpp*/
	/* All of this is taken from the function soap_wsse_add_UsernameTokenDigest() defined in wsseapi.cpp */
	_wsse__Security *security = soap_wsse_add_Security(soapOff);
	time_t now = time(NULL);
	now -= (time_t) cam_pc_offset; //offset so digest comes out correctly (synced times between cam and pc);
	const char *created = soap_dateTime2s(soapOff, now);
	char HA[SOAP_SMD_SHA1_SIZE], HABase64[29];
	char nonce[20], *nonceBase64;

	/*start calc_nonce(soapOff, nonce); Taken from wsseapi.cpp */
	time_t r = time(NULL);
	cout << "now time: " << r << endl;
	r -= (time_t) cam_pc_offset; //offset so digest comes out correctly (synced times between cam and pc);
	cout << "now time minus offset: " << r << endl;
	memcpy(nonce, &r, 4);
	for (int i = 4; i < 20; i += 4)
	{ r = soap_random;
	memcpy(nonce + i, &r, 4);
	}
	/*end calc_nonce(soapOff, nonce); */

	nonceBase64 = soap_s2base64(soapOff, (unsigned char*)nonce, NULL, 20);

	/* start calc_digest(soapOff, created, nonce, 20, strPass, HA);  Taken from wsseapi.cpp */
	struct soap_smd_data context;
	/* use smdevp engine */
	soap_smd_init(soapOff, &context, SOAP_SMD_DGST_SHA1, NULL, 0);
	soap_smd_update(soapOff, &context, nonce, 20);
	soap_smd_update(soapOff, &context, created, strlen(created));
	soap_smd_update(soapOff, &context, strPass.c_str(), strlen(strPass.c_str()));
	soap_smd_final(soapOff, &context, HA, NULL);
	/* end calc_digest(soapOff, created, nonce, 20, strPass, HA); */

	soap_s2base64(soapOff, (unsigned char*)HA, HABase64, SOAP_SMD_SHA1_SIZE);
	/* populate the UsernameToken with digest */
	soap_wsse_add_UsernameTokenText(soapOff, "Id", strUser.c_str(), HABase64);
	/* populate the remainder of the password, nonce, and created */
	security->UsernameToken->Password->Type = (char*)wsse_PasswordDigestURI;
	security->UsernameToken->Nonce = nonceBase64;
	security->UsernameToken->wsu__Created = soap_strdup(soapOff, created);
	/* end soap_wsse_add_UsernameTokenDigest */
	return SOAP_OK;
}
Exemple #5
0
static int http_da_prepareinitsend(struct soap *soap)
{
  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);

  if (!data)
    return SOAP_PLUGIN_ERROR;

  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MIME)))
  { /* support non-streaming MIME/DIME attachments by buffering the message */
    soap->omode &= ~SOAP_IO;
    soap->omode |= SOAP_IO_STORE;
    soap->mode &= ~SOAP_IO;
    soap->mode |= SOAP_IO_STORE;
  }
  else
  {
    if ((soap->userid && soap->passwd)
     || (soap->proxy_userid && soap->proxy_passwd))
    {
      if (soap_smd_init(soap, &data->smd_data, SOAP_SMD_DGST_MD5, NULL, 0))
        return soap->error;
      if (soap->fpreparesend != http_da_preparesend)
      {
        data->fpreparesend = soap->fpreparesend;
        soap->fpreparesend = http_da_preparesend;
      }
      if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
        soap->mode |= SOAP_IO_LENGTH;
    }
  }

  if (data->fprepareinitsend)
    return data->fprepareinitsend(soap);

  return SOAP_OK;
}
Exemple #6
0
static int http_da_calc_response(struct soap *soap, struct soap_smd_data *smd_data, const char *alg, char HA1hex[65], const char *nonce, const char *ncount, const char *cnonce, const char *qop, const char *method, const char *uri, char entityHAhex[65], char response[65], char responseHA[32])
{
  int smd_alg = SOAP_SMD_DGST_MD5;
  size_t smd_len = 16;
  char HA2[32], HA2hex[65];

  if (alg && !soap_tag_cmp(alg, "SHA-256*"))
  {
    smd_alg = SOAP_SMD_DGST_SHA256;
    smd_len = 32;
  }

  if (soap_smd_init(soap, smd_data, smd_alg, NULL, 0)
   || soap_smd_update(soap, smd_data, method, strlen(method))
   || soap_smd_update(soap, smd_data, ":", 1)
   || soap_smd_update(soap, smd_data, uri, strlen(uri)))
    return soap->error;

  if (qop && !soap_tag_cmp(qop, "auth-int"))
  {
    if (soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, entityHAhex, 2*smd_len))
      return soap->error;
  }

  if (soap_smd_final(soap, smd_data, HA2, NULL))
    return soap->error;

  (void)soap_s2hex(soap, (unsigned char*)HA2, HA2hex, smd_len);

  if (soap_smd_init(soap, smd_data, smd_alg, NULL, 0)
   || soap_smd_update(soap, smd_data, HA1hex, 2*smd_len))
    return soap->error;

  if (nonce)
  {
    if (soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, nonce, strlen(nonce)))
      return soap->error;
  }

  if (qop && *qop)
  {
    if (soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, ncount, strlen(ncount))
     || soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, cnonce, strlen(cnonce))
     || soap_smd_update(soap, smd_data, ":", 1)
     || soap_smd_update(soap, smd_data, qop, strlen(qop)))
      return soap->error;
  }

  if (soap_smd_update(soap, smd_data, ":", 1)
   || soap_smd_update(soap, smd_data, HA2hex, 2*smd_len)
   || soap_smd_final(soap, smd_data, responseHA, NULL))
    return soap->error;

  (void)soap_s2hex(soap, (unsigned char*)responseHA, response, smd_len);

  return SOAP_OK;
}