/* 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;
}
// Caller needs to free the returned pointer
char* condor_base64_encode(const unsigned char *input, int length)
{
	char *buff = NULL;

	if ( length < 1 ) {
		buff = (char *)malloc(1);
		buff[0] = '\0';
		return buff;
	}

	int buff_len = (length+2)/3*4+1;
	buff = (char *)malloc(buff_len);
	ASSERT(buff);
	memset(buff,0,buff_len);

	struct soap soap;
	soap_init(&soap);

	soap_s2base64(&soap,input,buff,length);

	soap_destroy(&soap);
	soap_end(&soap);
	soap_done(&soap);

	return buff;
}
Exemple #3
0
static int http_md5_post_header(struct soap *soap, const char *key, const char *val)
{ struct http_md5_data *data = (struct http_md5_data*)soap_lookup_plugin(soap, http_md5_id);
  char buf64[25]; /* 24 base64 chars + '\0' */
  int err;
  if (!data)
    return SOAP_PLUGIN_ERROR;
  if (!key) /* last line */
  { if ((err = md5_handler(soap, &data->context, MD5_FINAL, data->digest, 0)))
      return err;
    data->fposthdr(soap, "Content-MD5", soap_s2base64(soap, (unsigned char*)data->digest, buf64, 16));
  }
  return data->fposthdr(soap, key, val);
}