예제 #1
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;
}
예제 #2
0
// Enumeration of the secure objects
LIST *EnumSecObject(SECURE *sec)
{
	CK_BBOOL b_true = true, b_false = false;
	UINT objects[MAX_OBJ];
	UINT i;
	UINT ret;
	LIST *o;
	CK_ATTRIBUTE dummy[1];
	CK_ATTRIBUTE a[] =
	{
		{CKA_TOKEN,		&b_true,		sizeof(b_true)},
	};
	UINT num_objects = MAX_OBJ;
	// Validate arguments
	if (sec == NULL)
	{
		return NULL;
	}
	if (sec->SessionCreated == false)
	{
		sec->Error = SEC_ERROR_NO_SESSION;
		return NULL;
	}

	Zero(dummy, sizeof(dummy));

	// If there is a cache, return it
	if (sec->EnumCache != NULL)
	{
		return CloneEnumSecObject(sec->EnumCache);
	}

	// Enumerate
//	if (sec->Dev->Id != 2 && sec->Dev->Id != 14)
//	{
		// Normal tokens
		ret = sec->Api->C_FindObjectsInit(sec->SessionId, a, sizeof(a) / sizeof(a[0]));
//	}
//	else
//	{
		// ePass and SafeSign
//		ret = sec->Api->C_FindObjectsInit(sec->SessionId, dummy, 0);
//	}

	if (ret != CKR_OK)
	{
		sec->Error = SEC_ERROR_HARDWARE_ERROR;
		return NULL;
	}
	if (sec->Api->C_FindObjects(sec->SessionId, objects, sizeof(objects) / sizeof(objects[0]), &num_objects) != CKR_OK)
	{
		sec->Api->C_FindObjectsFinal(sec->SessionId);
		sec->Error = SEC_ERROR_HARDWARE_ERROR;
		return NULL;
	}
	sec->Api->C_FindObjectsFinal(sec->SessionId);

	o = NewListFast(NULL);

	for (i = 0;i < num_objects;i++)
	{
		char label[MAX_SIZE];
		UINT obj_class = 0;
		bool priv = false;
		CK_ATTRIBUTE get[] =
		{
			{CKA_LABEL, label, sizeof(label) - 1},
			{CKA_CLASS, &obj_class, sizeof(obj_class)},
			{CKA_PRIVATE, &priv, sizeof(priv)},
		};

		Zero(label, sizeof(label));

		if (sec->Api->C_GetAttributeValue(sec->SessionId, objects[i],
			get, sizeof(get) / sizeof(get[0])) == CKR_OK)
		{
			UINT type = INFINITE;

			switch (obj_class)
			{
			case CKO_DATA:
				// Data
				type = SEC_DATA;
				break;

			case CKO_CERTIFICATE:
				// Certificate
				type = SEC_X;
				break;

			case CKO_PUBLIC_KEY:
				// Public key
				type = SEC_P;
				break;

			case CKO_PRIVATE_KEY:
				// Secret key
				type = SEC_K;
				break;
			}

			if (type != INFINITE)
			{
				SEC_OBJ *obj = ZeroMalloc(sizeof(SEC_OBJ));

				obj->Type = type;
				obj->Object = objects[i];
				obj->Private = (priv == false) ? false : true;
				EnSafeStr(label, '?');
				TruncateCharFromStr(label, '?');
				obj->Name = CopyStr(label);

				Add(o, obj);
			}
		}
	}

	// Creating a cache
	sec->EnumCache = CloneEnumSecObject(o);

	return o;
}