String IoesptAzure::createEventHubSas(char *key, String url) {
	// START: Create SAS  
	// https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/
	// Where to get seconds since the epoch: local service, SNTP, RTC

	String stringToSign = url + "\n" + cloud.sasExpiryDate;

	// START: Create signature
	Sha256.initHmac((const uint8_t*)key, 44);
	Sha256.print(stringToSign);

	char* sign = (char*)Sha256.resultHmac();
	int signLen = 32;
	// END: Create signature

	// START: Get base64 of signature
	int encodedSignLen = base64_enc_len(signLen);
	char encodedSign[encodedSignLen];
	base64_encode(encodedSign, sign, signLen);
	// END: Get base64 of signature

	// SharedAccessSignature
	return "sr=" + url + "&sig=" + urlEncode(encodedSign) + "&se=" + cloud.sasExpiryDate + "&skn=" + cloud.id;
	// END: create SAS
}
String IoesptAzure::createIotHubSas(char *key, String url) {
	String stringToSign = url + "\n" + cloud.sasExpiryDate;

	// START: Create signature
	// https://raw.githubusercontent.com/adamvr/arduino-base64/master/examples/base64/base64.ino

	int keyLength = strlen(key);

	int decodedKeyLength = base64_dec_len(key, keyLength);
	char decodedKey[decodedKeyLength];  //allocate char array big enough for the base64 decoded key

	base64_decode(decodedKey, key, keyLength);  //decode key

	Sha256.initHmac((const uint8_t*)decodedKey, decodedKeyLength);
	Sha256.print(stringToSign);
	char* sign = (char*)Sha256.resultHmac();
	// END: Create signature

	// START: Get base64 of signature
	int encodedSignLen = base64_enc_len(HASH_LENGTH);
	char encodedSign[encodedSignLen];
	base64_encode(encodedSign, sign, HASH_LENGTH);

	// SharedAccessSignature
	return "sr=" + url + "&sig=" + urlEncode(encodedSign) + "&se=" + cloud.sasExpiryDate;
	// END: create SAS  
}
Beispiel #3
0
int ki_autheph_authenticate(sip_msg_t *_m, str *susername, str *spassword)
{
	char generated_password[base64_enc_len(SHA_DIGEST_LENGTH)];
	str sgenerated_password;
	struct secret *secret_struct;

	if (susername->len == 0)
	{
		LM_ERR("invalid username parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (spassword->len == 0)
	{
		LM_ERR("invalid password parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (autheph_verify_timestamp(susername) < 0)
	{
		LM_ERR("invalid timestamp in username\n");
		return AUTH_ERROR;
	}

	LM_DBG("username: %.*s\n", susername->len, susername->s);
	LM_DBG("password: %.*s\n", spassword->len, spassword->s);

	sgenerated_password.s = generated_password;
	SECRET_LOCK;
	secret_struct = secret_list;
	while (secret_struct != NULL)
	{
		LM_DBG("trying secret: %.*s\n",
			secret_struct->secret_key.len,
			secret_struct->secret_key.s);
		if (get_pass(susername, &secret_struct->secret_key,
				&sgenerated_password) == 0)
		{
			LM_DBG("generated password: %.*s\n",
				sgenerated_password.len, sgenerated_password.s);
			if (strncmp(spassword->s, sgenerated_password.s,
					spassword->len) == 0)
			{
				SECRET_UNLOCK;
				return AUTH_OK;
			}
		}
		secret_struct = secret_struct->next;
	}
	SECRET_UNLOCK;

	return AUTH_ERROR;
}
Beispiel #4
0
int XMPPClient::authenticate(char *username, char *password) {
  int plainStringLen = strlen(username) + strlen(password) + 2;
  int encStringLen = base64_enc_len(plainStringLen);
  char plainString[plainStringLen];
  char encString[encStringLen];
  
  /* Set up our plain auth string. It's in the form:
   * "\0username\0password"
   * where \0 is the null character
   */
   memset(plainString, '\0', plainStringLen);
   memcpy(plainString + 1, username, strlen(username));
   memcpy(plainString + 2 + strlen(username), password, strlen(password));

  /* Encode to base64 */
   base64_encode(encString, plainString, plainStringLen);
   sendTemplate(plain_auth_template, encStringLen, encString);
 }
Beispiel #5
0
static inline int get_pass(str *_username, str *_secret, str *_password)
{
	unsigned int hmac_len = SHA_DIGEST_LENGTH;
	unsigned char hmac_sha1[hmac_len];

	if (HMAC(EVP_sha1(), _secret->s, _secret->len,
			(unsigned char *) _username->s,
			_username->len, hmac_sha1, &hmac_len) == NULL)
	{
		LM_ERR("HMAC-SHA1 failed\n");
		return -1;
	}

	_password->len = base64_enc(hmac_sha1, hmac_len,
					(unsigned char *) _password->s,
					base64_enc_len(hmac_len));
	LM_DBG("calculated password: %.*s\n", _password->len, _password->s);

	return 0;
}
Beispiel #6
0
static inline int get_ha1(struct username *_username, str *_domain,
				str *_secret, char *_ha1)
{
	char password[base64_enc_len(SHA512_DIGEST_LENGTH)];
	str spassword;

	spassword.s = (char *) password;
	spassword.len = 0;

	if (get_pass(&_username->whole, _secret, &spassword) < 0)
	{
		LM_ERR("calculating password\n");
		return -1;
	}

	eph_auth_api.calc_HA1(HA_MD5, &_username->whole, _domain, &spassword,
				0, 0, _ha1);
	LM_DBG("calculated HA1: %s\n", _ha1);

	return 0;
}
Beispiel #7
0
bool base64_enc(const void *data, size_t dlen, char *buf, size_t *blen)
{
	size_t n;
	size_t boffs = 0;
	const char *d = data;

	n = base64_enc_len(dlen);
	if (*blen < n) {
		*blen = n;
		return false;
	}

	for (n = 0; n < dlen; n += 3) {
		uint32_t igrp;

		igrp = d[n];
		igrp <<= 8;

		if ((n + 1) < dlen)
			igrp |= d[n + 1];
		igrp <<= 8;

		if ((n + 2) < dlen)
			igrp |= d[n + 2];

		buf[boffs] = base64_table[(igrp >> 18) & 0x3f];
		buf[boffs + 1] = base64_table[(igrp >> 12) & 0x3f];
		if ((n + 1) < dlen)
			buf[boffs + 2] = base64_table[(igrp >> 6) & 0x3f];
		else
			buf[boffs + 2] = '=';
		if ((n + 2) < dlen)
			buf[boffs + 3] = base64_table[igrp & 0x3f];
		else
			buf[boffs + 3] = '=';

		boffs += 4;
	}
Beispiel #8
0
static inline int get_pass(str *_username, str *_secret, str *_password)
{
	unsigned int hmac_len = SHA_DIGEST_LENGTH;
	unsigned char hmac_sha1[512];

	switch(autheph_sha_alg) {
		case AUTHEPH_SHA1:
			hmac_len = SHA_DIGEST_LENGTH;
			if (HMAC(EVP_sha1(), _secret->s, _secret->len,
					(unsigned char *) _username->s,
					_username->len, hmac_sha1, &hmac_len) == NULL)
			{
				LM_ERR("HMAC-SHA1 failed\n");
				return -1;
			}
			break;
		case AUTHEPH_SHA256:
			hmac_len = SHA256_DIGEST_LENGTH;
			if (HMAC(EVP_sha256(), _secret->s, _secret->len,
					(unsigned char *) _username->s,
					_username->len, hmac_sha1, &hmac_len) == NULL)
			{
				LM_ERR("HMAC-SHA256 failed\n");
				return -1;
			}
			break;
		case AUTHEPH_SHA384:
			hmac_len = SHA384_DIGEST_LENGTH;
			if (HMAC(EVP_sha256(), _secret->s, _secret->len,
					(unsigned char *) _username->s,
					_username->len, hmac_sha1, &hmac_len) == NULL)
			{
				LM_ERR("HMAC-SHA256 failed\n");
				return -1;
			}
			break;
		case AUTHEPH_SHA512:
			hmac_len = SHA512_DIGEST_LENGTH;
			if (HMAC(EVP_sha512(), _secret->s, _secret->len,
					(unsigned char *) _username->s,
					_username->len, hmac_sha1, &hmac_len) == NULL)
			{
				LM_ERR("HMAC-SHA512 failed\n");
				return -1;
			}
			break;
		default:
			LM_ERR("Inavlid SHA Algorithm\n");
			return -1;

	}

	LM_DBG("HMAC-Len (%i)\n", hmac_len);


	_password->len = base64_enc(hmac_sha1, hmac_len,
					(unsigned char *) _password->s,
					base64_enc_len(hmac_len));
	LM_DBG("calculated password: %.*s (%i)\n", _password->len, _password->s, _password->len);

	return 0;
}
Beispiel #9
0
int ws_handle_handshake(struct sip_msg *msg)
{
	str key = {0, 0}, headers = {0, 0}, reply_key = {0, 0}, origin = {0, 0};
	unsigned char sha1[SHA_DIGEST_LENGTH];
	unsigned int hdr_flags = 0, sub_protocol = 0;
	int version = 0;
	struct hdr_field *hdr = msg->headers;
	struct tcp_connection *con;
	ws_connection_t *wsc;

	/* Make sure that the connection is closed after the response _and_
	   the existing connection (from the request) is reused for the
	   response.  The close flag will be unset later if the handshake is
	   successful. */
	msg->rpl_send_flags.f |= SND_F_CON_CLOSE;
	msg->rpl_send_flags.f |= SND_F_FORCE_CON_REUSE;

	if (cfg_get(websocket, ws_cfg, enabled) == 0)
	{
		LM_INFO("disabled: bouncing handshake\n");
		ws_send_reply(msg, 503, &str_status_service_unavailable,
				NULL);
		return 0;
	}

	/* Retrieve TCP/TLS connection */
	if ((con = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, 0)) == NULL)
	{
		LM_ERR("retrieving connection\n");
		ws_send_reply(msg, 500, &str_status_internal_server_error,
				NULL);
		return 0;
	}

	if (con->type != PROTO_TCP && con->type != PROTO_TLS)
	{
		LM_ERR("unsupported transport: %d", con->type);
		goto end;
	}

	if (parse_headers(msg, HDR_EOH_F, 0) < 0)
	{
		LM_ERR("error parsing headers\n");
		ws_send_reply(msg, 500, &str_status_internal_server_error,
				NULL);
		goto end;
	}

	/* Process HTTP headers */
	while (hdr != NULL)
	{
		/* Decode and validate Connection */
		if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_connection.s,
				str_hdr_connection.len) == 0)
		{
			strlower(&hdr->body);
			if (str_search(&hdr->body, &str_upgrade) != NULL)
			{
				LM_DBG("found %.*s: %.*s\n",

					hdr->name.len, hdr->name.s,
					hdr->body.len, hdr->body.s);
				hdr_flags |= CONNECTION;
			}
		}
		/* Decode and validate Upgrade */
		else if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_upgrade.s,
				str_hdr_upgrade.len) == 0)
		{
			strlower(&hdr->body);
			if (str_search(&hdr->body, &str_websocket) != NULL)
			{
				LM_DBG("found %.*s: %.*s\n",
					hdr->name.len, hdr->name.s,
					hdr->body.len, hdr->body.s);
				hdr_flags |= UPGRADE;
			}
		}
		/* Decode and validate Sec-WebSocket-Key */
		else if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_sec_websocket_key.s, 
				str_hdr_sec_websocket_key.len) == 0) 
		{
			if (hdr_flags & SEC_WEBSOCKET_KEY)
			{
				LM_WARN("%.*s found multiple times\n",
					hdr->name.len, hdr->name.s);
				ws_send_reply(msg, 400,
						&str_status_bad_request,
						NULL);
				goto end;
			}

			LM_DBG("found %.*s: %.*s\n",
				hdr->name.len, hdr->name.s,
				hdr->body.len, hdr->body.s);
			key = hdr->body;
			hdr_flags |= SEC_WEBSOCKET_KEY;
		}
		/* Decode and validate Sec-WebSocket-Protocol */
		else if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_sec_websocket_protocol.s,
				str_hdr_sec_websocket_protocol.len) == 0)
		{
			strlower(&hdr->body);
			if (str_search(&hdr->body, &str_sip) != NULL)
			{
				LM_DBG("found %.*s: %.*s\n",
					hdr->name.len, hdr->name.s,
					hdr->body.len, hdr->body.s);
				hdr_flags |= SEC_WEBSOCKET_PROTOCOL;
				sub_protocol |= SUB_PROTOCOL_SIP;
			}
			if (str_search(&hdr->body, &str_msrp) != NULL)
			{
				LM_DBG("found %.*s: %.*s\n",
					hdr->name.len, hdr->name.s,
					hdr->body.len, hdr->body.s);
				hdr_flags |= SEC_WEBSOCKET_PROTOCOL;
				sub_protocol |= SUB_PROTOCOL_MSRP;
			}
		}
		/* Decode and validate Sec-WebSocket-Version */
		else if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_sec_websocket_version.s,
				str_hdr_sec_websocket_version.len) == 0)
		{
			if (hdr_flags & SEC_WEBSOCKET_VERSION)
			{
				LM_WARN("%.*s found multiple times\n",
					hdr->name.len, hdr->name.s);
				ws_send_reply(msg, 400,
						&str_status_bad_request,
						NULL);
				goto end;
			}

			str2sint(&hdr->body, &version);

			if (version != WS_VERSION)
			{
				LM_WARN("Unsupported protocol version %.*s\n",
					hdr->body.len, hdr->body.s);
				headers.s = headers_buf;
				headers.len = snprintf(headers.s, HDR_BUF_LEN,
					"%.*s: %d\r\n",
					str_hdr_sec_websocket_version.len,
					str_hdr_sec_websocket_version.s,
					WS_VERSION);
				ws_send_reply(msg, 426,
						&str_status_upgrade_required,
						&headers);
				goto end;
			}

			LM_DBG("found %.*s: %.*s\n",
				hdr->name.len, hdr->name.s,
				hdr->body.len, hdr->body.s);
			hdr_flags |= SEC_WEBSOCKET_VERSION;
		}
		/* Decode Origin */
		else if (cmp_hdrname_strzn(&hdr->name,
				str_hdr_origin.s,
				str_hdr_origin.len) == 0)
		{
			if (hdr_flags & ORIGIN)
			{
				LM_WARN("%.*s found multiple times\n",
					hdr->name.len, hdr->name.s);
				ws_send_reply(msg, 400,
						&str_status_bad_request,
						NULL);
				goto end;
			}

			LM_DBG("found %.*s: %.*s\n",
				hdr->name.len, hdr->name.s,
				hdr->body.len, hdr->body.s);
			origin = hdr->body;
			hdr_flags |= ORIGIN;
		}

		hdr = hdr->next;
	}

	/* Final check that all required headers/values were found */
	sub_protocol &= ws_sub_protocols;
	if ((hdr_flags & REQUIRED_HEADERS) != REQUIRED_HEADERS
			|| sub_protocol == 0)
	{

		LM_WARN("required headers not present\n");
		headers.s = headers_buf;
		headers.len = 0;

		if (ws_sub_protocols & SUB_PROTOCOL_SIP)
			headers.len += snprintf(headers.s + headers.len,
						HDR_BUF_LEN - headers.len,
						"%.*s: %.*s\r\n",
					str_hdr_sec_websocket_protocol.len,
					str_hdr_sec_websocket_protocol.s,
					str_sip.len, str_sip.s);

		if (ws_sub_protocols & SUB_PROTOCOL_MSRP)
			headers.len += snprintf(headers.s + headers.len,
						HDR_BUF_LEN - headers.len,
						"%.*s: %.*s\r\n",
					str_hdr_sec_websocket_protocol.len,
					str_hdr_sec_websocket_protocol.s,
					str_msrp.len, str_msrp.s);

		headers.len += snprintf(headers.s + headers.len,
					HDR_BUF_LEN - headers.len,
					"%.*s: %d\r\n",
					str_hdr_sec_websocket_version.len,
					str_hdr_sec_websocket_version.s,
					WS_VERSION);
		ws_send_reply(msg, 400, &str_status_bad_request, &headers);
		goto end;
	}

	/* Construct reply_key */
	reply_key.s = (char *) pkg_malloc(
				(key.len + str_ws_guid.len) * sizeof(char)); 
	if (reply_key.s == NULL)
	{
		LM_ERR("allocating pkg memory\n");
		ws_send_reply(msg, 500, &str_status_internal_server_error,
				NULL);
		goto end;
	}
	memcpy(reply_key.s, key.s, key.len);
	memcpy(reply_key.s + key.len, str_ws_guid.s, str_ws_guid.len);
	reply_key.len = key.len + str_ws_guid.len;
	SHA1((const unsigned char *) reply_key.s, reply_key.len, sha1);
	pkg_free(reply_key.s);
	reply_key.s = key_buf;
	reply_key.len = base64_enc(sha1, SHA_DIGEST_LENGTH,
				(unsigned char *) reply_key.s,
				base64_enc_len(SHA_DIGEST_LENGTH));

	/* Add the connection to the WebSocket connection table */
	wsconn_add(msg->rcv, sub_protocol);

	/* Make sure Kamailio core sends future messages on this connection
	   directly to this module */
	if (con->type == PROTO_TLS)
		con->type = con->rcv.proto = PROTO_WSS;
	else
		con->type = con->rcv.proto = PROTO_WS;

	/* Now Kamailio is ready to receive WebSocket frames build and send a
	   101 reply */
	headers.s = headers_buf;
	headers.len = 0;

	if (ws_cors_mode == CORS_MODE_ANY)
		headers.len += snprintf(headers.s + headers.len,
					HDR_BUF_LEN - headers.len,
					"%.*s: *\r\n",
					str_hdr_access_control_allow_origin.len,
					str_hdr_access_control_allow_origin.s);
	else if (ws_cors_mode == CORS_MODE_ORIGIN && origin.len > 0)
		headers.len += snprintf(headers.s + headers.len,
					HDR_BUF_LEN - headers.len,
					"%.*s: %.*s\r\n",
					str_hdr_access_control_allow_origin.len,
					str_hdr_access_control_allow_origin.s,
					origin.len,
					origin.s);

	if (sub_protocol & SUB_PROTOCOL_SIP)
		headers.len += snprintf(headers.s + headers.len,
					HDR_BUF_LEN - headers.len,
					"%.*s: %.*s\r\n",
					str_hdr_sec_websocket_protocol.len,
					str_hdr_sec_websocket_protocol.s,
					str_sip.len, str_sip.s);
	else if (sub_protocol & SUB_PROTOCOL_MSRP)
		headers.len += snprintf(headers.s + headers.len,
					HDR_BUF_LEN - headers.len,
					"%.*s: %.*s\r\n",
					str_hdr_sec_websocket_protocol.len,
					str_hdr_sec_websocket_protocol.s,
					str_msrp.len, str_msrp.s);

	headers.len += snprintf(headers.s + headers.len,
				HDR_BUF_LEN - headers.len,
				"%.*s: %.*s\r\n"
				"%.*s: %.*s\r\n"
				"%.*s: %.*s\r\n",
				str_hdr_upgrade.len, str_hdr_upgrade.s,
				str_websocket.len, str_websocket.s,
				str_hdr_connection.len, str_hdr_connection.s,
				str_upgrade.len, str_upgrade.s,
				str_hdr_sec_websocket_accept.len,
				str_hdr_sec_websocket_accept.s, reply_key.len,
				reply_key.s);
	msg->rpl_send_flags.f &= ~SND_F_CON_CLOSE;
	if (ws_send_reply(msg, 101, &str_status_switching_protocols,
				&headers) < 0)
	{
		if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) != NULL)
			wsconn_rm(wsc, WSCONN_EVENTROUTE_NO);

		goto end;
	}
	else
	{
		if (sub_protocol & SUB_PROTOCOL_SIP)
			update_stat(ws_sip_successful_handshakes, 1);
		else if (sub_protocol & SUB_PROTOCOL_MSRP)
			update_stat(ws_msrp_successful_handshakes, 1);
	}

	tcpconn_put(con);
	return 1;
end:
	if (con)
		tcpconn_put(con);
	return 0;
}
Beispiel #10
0
#define REQUIRED_HEADERS	(CONNECTION | UPGRADE | SEC_WEBSOCKET_KEY\
					| SEC_WEBSOCKET_PROTOCOL\
					| SEC_WEBSOCKET_VERSION)

/* HTTP status text */
static str str_status_switching_protocols = str_init("Switching Protocols");
static str str_status_bad_request = str_init("Bad Request");
static str str_status_upgrade_required = str_init("Upgrade Required");
static str str_status_internal_server_error = str_init("Internal Server Error");
static str str_status_service_unavailable = str_init("Service Unavailable");

#define HDR_BUF_LEN		(512)
static char headers_buf[HDR_BUF_LEN];

static char key_buf[base64_enc_len(SHA_DIGEST_LENGTH)];

static int ws_send_reply(sip_msg_t *msg, int code, str *reason, str *hdrs)
{
	if (hdrs && hdrs->len > 0)
	{
		if (add_lump_rpl(msg, hdrs->s, hdrs->len, LUMP_RPL_HDR) == 0)
		{
			LM_ERR("inserting extra-headers lump\n");
			update_stat(ws_failed_handshakes, 1);
			return -1;
		}
	}

	if (ws_slb.freply(msg, code, reason) < 0)
	{
Beispiel #11
0
bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupname, UINT timeout, UCHAR* challenge8, UCHAR* MsChapV2_ClientResponse, UCHAR* nt_pw_hash_hash)
{
	bool  auth = false;
	int   fds[2];
	FILE* out, *in;
	PID   pid;
	char  buffer[255];
	char  ntlm_timeout[32];
	char* proc_parameter[6];
	
	if (name == NULL || password == NULL || domainname == NULL || groupname == NULL)
	{
		Debug("Sam.c - SmbAuthenticate - wrong password parameter\n");
		return false;
	}

	if (password[0] == '\0' && (challenge8 == NULL || MsChapV2_ClientResponse == NULL || nt_pw_hash_hash == NULL))
	{
		Debug("Sam.c - SmbAuthenticate - wrong MsCHAPv2 parameter\n");
		return false;
	}

	Zero(buffer, sizeof(buffer));

	// Truncate string if unsafe char
	EnSafeStr(domainname, '\0');

	if (strlen(domainname) > 255)
	{
		// there is no domainname longer then 255 chars!
		// http://tools.ietf.org/html/rfc1035 section 2.3.4
		domainname[255] = '\0';
	}
	
	// set timeout to 15 minutes even if timeout is disabled, to prevent ntlm_auth from hung up
	if (timeout <= 0 || timeout > 900)
	{
		timeout = 999;
	}
	
	snprintf(ntlm_timeout, sizeof(ntlm_timeout), "%is", timeout);
	Debug("Sam.c - timeout for ntlm_auth %s\n", ntlm_timeout);

	proc_parameter[0] = "timeout";
	proc_parameter[1] = ntlm_timeout;
	proc_parameter[2] = "ntlm_auth";
	proc_parameter[3] = "--helper-protocol=ntlm-server-1";
	proc_parameter[4] = 0;

	if (strlen(groupname) > 1)
	{
		// DNS Name 255 chars + OU names are limited to 64 characters +  cmdline 32 + 1
		char  requiremember[352];

		// Truncate string if unsafe char
		EnSafeStr(groupname, '\0');

		snprintf(requiremember, sizeof(requiremember), "--require-membership-of=%s\\%s", domainname, groupname);
		
		proc_parameter[4] = requiremember;
		proc_parameter[5] = 0;
	}

	pid = OpenChildProcess("timeout", proc_parameter, fds);

	if (pid < 0)
	{
		Debug("Sam.c - SmbCheckLogon - error fork child process (ntlm_auth)\n");
		return false;
	}

	out = fdopen(fds[1], "w");
	if (out == 0)
	{
		CloseChildProcess(pid, fds);

		Debug("Sam.c - cant open out pipe (ntlm_auth)\n");
		return false;
	}

	in = fdopen(fds[0], "r");
	if (in == 0)
	{
		fclose(out);
		CloseChildProcess(pid, fds);

		Debug("Sam.c - cant open in pipe (ntlm_auth)\n");
		return false;
	}

	if (base64_enc_len(strlen(name)) < sizeof(buffer)-1 &&
		base64_enc_len(strlen(password)) < sizeof(buffer)-1 &&
		base64_enc_len(strlen(domainname)) < sizeof(buffer)-1)
	{
		char  answer[300];

		unsigned int end = B64_Encode(buffer, name, strlen(name));
		buffer[end] = '\0';
		fputs("Username:: ", out);
		fputs(buffer, out);
		fputs("\n", out);
		Debug("Username: %s\n", buffer);
		buffer[0] = 0;

		end = B64_Encode(buffer, domainname, strlen(domainname));
		buffer[end] = '\0';
		fputs("NT-Domain:: ", out);
		fputs(buffer, out);
		fputs("\n", out);
		Debug("NT-Domain: %s\n", buffer);
		buffer[0] = 0;

		if (password[0] != '\0')
		{
			Debug("Password authentication\n");
			end = B64_Encode(buffer, password, strlen(password));
			buffer[end] = '\0';
			fputs("Password:: ", out);
			fputs(buffer, out);
			fputs("\n", out);
			Debug("Password: %s\n", buffer);
			buffer[0] = 0;
		}
		else
		{
			char* mschapv2_client_response;
			char* base64_challenge8;

			Debug("MsChapV2 authentication\n");
			mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24);
			end = B64_Encode(buffer, mschapv2_client_response, 48);
			buffer[end] = '\0';
			fputs("NT-Response:: ", out);
			fputs(buffer, out);
			fputs("\n", out);
			Debug("NT-Response:: %s\n", buffer);
			buffer[0] = 0;
			Free(mschapv2_client_response);

			base64_challenge8 = CopyBinToStr(challenge8, 8);
			end = B64_Encode(buffer, base64_challenge8 , 16);
			buffer[end] = '\0';
			fputs("LANMAN-Challenge:: ", out);
			fputs(buffer, out);
			fputs("\n", out);
			Debug("LANMAN-Challenge:: %s\n", buffer);
			buffer[0] = 0;
			Free(base64_challenge8);

			fputs("Request-User-Session-Key: Yes\n", out);
 		}

		// Start authentication
		fputs( ".\n", out );
		fflush (out);
		// Request send!

		Zero(answer, sizeof(answer));

		while (fgets(answer, sizeof(answer)-1, in))
		{
			char* response_parameter;

			if (strncmp(answer, ".\n", sizeof(answer)-1 ) == 0)
			{
				break;
			}

			/* Indicates a base64 encoded structure */
			response_parameter = strstr(answer, ":: ");
			if (!response_parameter) {
				char* newline;

				response_parameter = strstr(answer, ": ");

				if (!response_parameter) {
					continue;
				}

				response_parameter[0] ='\0';
				response_parameter++;
				response_parameter[0] ='\0';
				response_parameter++;

				newline  = strstr(response_parameter, "\n");
				if( newline )
					newline[0] = '\0';
			} else {
				response_parameter[0] ='\0';
				response_parameter++;
				response_parameter[0] ='\0';
				response_parameter++;
				response_parameter[0] ='\0';
				response_parameter++;

				end = Decode64(response_parameter, response_parameter);
				response_parameter[end] = '\0';
			}

			if (strncmp(answer, "Authenticated", sizeof(answer)-1 ) == 0)
			{
				if (strcmp(response_parameter, "Yes") == 0)
				{
					Debug("Authenticated!\n");
					auth = true;
				}
				else if (strcmp(response_parameter, "No") == 0)
				{
					Debug("Authentication failed!\n");
					auth = false;
				}
			}
			else if (strncmp(answer, "User-Session-Key", sizeof(answer)-1 ) == 0)
			{
				if (nt_pw_hash_hash != NULL)
				{
					BUF* Buf = StrToBin(response_parameter);
					Copy(nt_pw_hash_hash, Buf->Buf, 16);
					FreeBuf(Buf);
				}
			}
		}
	}

	fclose(in);
	fclose(out);

	CloseChildProcess(pid, fds);

	return auth;
}
Beispiel #12
0
int autheph_authenticate(struct sip_msg *_m, char *_username, char *_password)
{
	str susername, spassword;
	char generated_password[base64_enc_len(SHA_DIGEST_LENGTH)];
	str sgenerated_password;
	struct secret *secret_struct;

	if (_m == NULL || _username == NULL || _password == NULL)
	{
		LM_ERR("invalid parameters\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&susername, _m, (fparam_t*)_username) < 0)
	{
		LM_ERR("failed to get username value\n");
		return AUTH_ERROR;
	}

	if (susername.len == 0)
	{
		LM_ERR("invalid username parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (get_str_fparam(&spassword, _m, (fparam_t*)_password) < 0)
	{
		LM_ERR("failed to get password value\n");
		return AUTH_ERROR;
	}

	if (spassword.len == 0)
	{
		LM_ERR("invalid password parameter - empty value\n");
		return AUTH_ERROR;
	}

	if (autheph_verify_timestamp(&susername) < 0)
	{
		LM_ERR("invalid timestamp in username\n");
		return AUTH_ERROR;
	}

	LM_DBG("username: %.*s\n", susername.len, susername.s);
	LM_DBG("password: %.*s\n", spassword.len, spassword.s);

	sgenerated_password.s = generated_password;
	SECRET_LOCK;
	secret_struct = secret_list;
	while (secret_struct != NULL)
	{
		LM_DBG("trying secret: %.*s\n",
			secret_struct->secret_key.len,
			secret_struct->secret_key.s);
		if (get_pass(&susername, &secret_struct->secret_key,
				&sgenerated_password) == 0)
		{
			LM_DBG("generated password: %.*s\n",
				sgenerated_password.len, sgenerated_password.s);
			if (strncmp(spassword.s, sgenerated_password.s,
					spassword.len) == 0)
			{
				SECRET_UNLOCK;
				return AUTH_OK;
			}
		}
		secret_struct = secret_struct->next;
	}
	SECRET_UNLOCK;

	return AUTH_ERROR;
}