Exemplo n.º 1
3
BOOL ClientAuthenticate(const char *name, const char *hostname)
{
	int rc, rcISC;
	SEC_WINNT_AUTH_IDENTITY nameAndPwd = {0};
	int bytesReceived = 0, bytesSent = 0;
	char myTokenSource[256];
	TimeStamp useBefore;
	DWORD ctxReq, ctxAttr;
	int dwRead,dwWritten;
	// input and output buffers
	SecBufferDesc obd, ibd;
	SecBuffer ob, ib[2];
	BOOL haveInbuffer = FALSE;
	BOOL haveContext = FALSE;
	SCHANNEL_CRED cred = {0};
	PCCERT_CONTEXT cert = NULL;

	HANDLE hMy = CertOpenSystemStore(0,"MY");
	if(!hMy)
	{
		rcISC = SEC_E_NO_CREDENTIALS;
		server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC));
		return FALSE;
    }

	if(name)
	{
		cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t *)cvs::wide(name),	NULL);
		if(!cert)
		{
			rcISC = SEC_E_NO_CREDENTIALS;
			server_error(1,"No certificate for '%s': %s\n",name,GetErrorString(rcISC));
			return FALSE;
		}
	}

	cred.dwVersion = SCHANNEL_CRED_VERSION;
	cred.dwFlags = SCH_CRED_USE_DEFAULT_CREDS;

	if(cert)
	{
		cred.cCreds     = 1;
		cred.paCred     = &cert;
	}

	rc = AcquireCredentialsHandle( NULL, "SChannel", SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credHandle, &useBefore );

	ctxReq = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS;
	strncpy(myTokenSource,hostname,sizeof(myTokenSource));

	CertCloseStore(hMy,0);

	ib[0].pvBuffer = NULL;

	while ( 1 )
	{
		obd.ulVersion = SECBUFFER_VERSION;
		obd.cBuffers = 1;
		obd.pBuffers = &ob; // just one buffer
		ob.BufferType = SECBUFFER_TOKEN; // preping a token here
		ob.cbBuffer = secPackInfo->cbMaxToken;
		ob.pvBuffer = malloc(secPackInfo->cbMaxToken);

		rcISC = InitializeSecurityContext( &credHandle, haveContext? &contextHandle: NULL,
			myTokenSource, ctxReq, 0, SECURITY_NATIVE_DREP, haveInbuffer? &ibd: NULL,
			0, &contextHandle, &obd, &ctxAttr, &useBefore );

		if ( ib[0].pvBuffer != NULL )
		{
			free(ib[0].pvBuffer);
			ib[0].pvBuffer = NULL;
		}

		if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE || rcISC == SEC_I_COMPLETE_NEEDED )
		{
			CompleteAuthToken( &contextHandle, &obd );
			if ( rcISC == SEC_I_COMPLETE_NEEDED )
				rcISC = SEC_E_OK;
			else if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE )
				rcISC = SEC_I_CONTINUE_NEEDED;
		}

		if(rcISC<0)
		{
			server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC));
		}

		// send the output buffer off to the server
		if ( ob.cbBuffer != 0 )
		{
			if((dwWritten=tcp_write( (const char *) ob.pvBuffer, ob.cbBuffer))<=0)
				break;
			bytesSent += dwWritten;
		}
		free(ob.pvBuffer);
		ob.pvBuffer = NULL;
		ob.cbBuffer = 0;

		if ( rcISC != SEC_I_CONTINUE_NEEDED )
			break;

		// prepare to get the server's response
		ibd.ulVersion = SECBUFFER_VERSION;
		ibd.cBuffers = 2;
		ibd.pBuffers = ib; // just one buffer
		ib[0].BufferType = SECBUFFER_TOKEN; // preping a token here
		ib[0].cbBuffer = secPackInfo->cbMaxToken;
		ib[0].pvBuffer = malloc(secPackInfo->cbMaxToken);
		ib[1].cbBuffer = 0;
		ib[1].pvBuffer = NULL;
		ib[1].BufferType = SECBUFFER_EMPTY; // Spare stuff

		// receive the server's response
		if((dwRead=tcp_read(ib[0].pvBuffer,ib[0].cbBuffer))<=0)
			break;
		bytesReceived += dwRead;

		// by now we have an input buffer and a client context

		haveInbuffer = TRUE;
		haveContext = TRUE;
	}

	// we arrive here as soon as InitializeSecurityContext()
	// returns != SEC_I_CONTINUE_NEEDED.

	if ( rcISC != SEC_E_OK )
		haveContext = FALSE;
	else
		haveContext = TRUE; /* Looopback kerberos needs this */

	return haveContext;
}
Exemplo n.º 2
0
static
DWORD
ServerAcquireCreds(
    IN PCHAR pServiceName,
    IN PCHAR pServicePassword,
    IN PCHAR pServiceRealm,
    IN PCHAR pSecPkgName,
    OUT CredHandle *pServerCreds
    )
{
    DWORD dwError = SEC_E_OK;
    TimeStamp Expiry;
    SEC_WINNT_AUTH_IDENTITY_A AuthIdentity;
    PSEC_WINNT_AUTH_IDENTITY_A pAuthId = NULL;

    memset(&Expiry, 0, sizeof(TimeStamp));
    memset(&AuthIdentity, 0, sizeof(SEC_WINNT_AUTH_IDENTITY_A));

    memset(pServerCreds, 0, sizeof(CredHandle));

    if (pServiceName)
    {
        AuthIdentity.User = (PBYTE) pServiceName;
        AuthIdentity.UserLength = (ULONG)strlen(pServiceName);
        pAuthId = &AuthIdentity;
    }

    if (pServicePassword)
    {
        AuthIdentity.Password = (PBYTE) pServicePassword;
        AuthIdentity.PasswordLength = (ULONG)strlen(pServicePassword);
        pAuthId = &AuthIdentity;
    }

    if (pServiceRealm)
    {
        AuthIdentity.Domain = (PBYTE) pServiceRealm;
        AuthIdentity.DomainLength = (ULONG)strlen(pServiceRealm);
        pAuthId = &AuthIdentity;
    }

    AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    dwError = AcquireCredentialsHandle(
        NULL,
        pSecPkgName,
        SECPKG_CRED_INBOUND,
        NULL,                       // no logon id
        pAuthId,
        NULL,                       // no get key fn
        NULL,                       // no get key arg
        pServerCreds,
        &Expiry
        );

    BAIL_ON_ERROR(dwError);

error:
    return dwError;
}
Exemplo n.º 3
0
int SSL_SOCKET :: ClientInit(bool NoLoop)
	{
	SECURITY_STATUS ss = 0;
	if (IsExternalCert)
		{
		;
		}
	else
		{
		OurCertificate = CreateOurCertificate();
		}

	// Configure our SSL SChannel
	memset(&m_SchannelCred,0,sizeof(m_SchannelCred));
	m_SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
	m_SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
	m_SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_REVOCATION_CHECK_CHAIN;

	if (OurCertificate)
		{
		m_SchannelCred.cCreds     = 1;
		m_SchannelCred.paCred     = &OurCertificate;
		}

	// AcquireCredentialsHandle

	ss = AcquireCredentialsHandle(0,SCHANNEL_NAME,SECPKG_CRED_OUTBOUND,0,&m_SchannelCred,0,0,&hCred,0);
//	ss = AcquireCredentialsHandle(0,UNISP_NAME,SECPKG_CRED_OUTBOUND,0,&m_SchannelCred,0,0,&hCred,0);
	if (FAILED(ss))
		return 0;

	if (NoLoop)
		return 0;
	return ClientLoop();
	}
Exemplo n.º 4
0
GSSAPISession::GSSAPISession(QString authMethod) : _authMethod(authMethod), _first(true)
{
#ifdef Q_OS_WIN
    SECURITY_STATUS status;

    LPWSTR methodName = new WCHAR[_authMethod.length()+1];
    _authMethod.toWCharArray(methodName);
    methodName[_authMethod.length()] = 0;
    status = QuerySecurityPackageInfo(methodName, &_info);
    TimeStamp serverLifetime;
    status = AcquireCredentialsHandle(NULL, methodName, SECPKG_CRED_BOTH, NULL, NULL, NULL, NULL, &_serverHandle, &serverLifetime);

    _outSecBufDesc.ulVersion = 0;
    _outSecBufDesc.cBuffers = 1;
    _outSecBufDesc.pBuffers = &_outSecBuf;
    _outSecBuf.cbBuffer = _info->cbMaxToken;
    _outSecBuf.BufferType = SECBUFFER_TOKEN;
    _outSecBuf.pvBuffer = static_cast<PBYTE>(malloc (_info->cbMaxToken));
    _inSecBufDesc.ulVersion = 0;
    _inSecBufDesc.cBuffers = 1;
    _inSecBufDesc.pBuffers = &_inSecBuf;
    _inSecBuf.BufferType = SECBUFFER_TOKEN;
    delete methodName;
#endif
}
Exemplo n.º 5
0
apr_status_t
serf__kerb_create_sec_context(serf__kerb_context_t **ctx_p,
                              apr_pool_t *scratch_pool,
                              apr_pool_t *result_pool)
{
    SECURITY_STATUS sspi_status;
    serf__kerb_context_t *ctx;

    ctx = apr_pcalloc(result_pool, sizeof(*ctx));

    SecInvalidateHandle(&ctx->sspi_context);
    SecInvalidateHandle(&ctx->sspi_credentials);
    ctx->initalized = FALSE;

    apr_pool_cleanup_register(result_pool, ctx,
                              cleanup_ctx,
                              apr_pool_cleanup_null);

    sspi_status = AcquireCredentialsHandle(
        NULL, "Negotiate", SECPKG_CRED_OUTBOUND,
        NULL, NULL, NULL, NULL,
        &ctx->sspi_credentials, NULL);

    if (FAILED(sspi_status)) {
        return map_sspi_status(sspi_status);
    }

    *ctx_p = ctx;

    return APR_SUCCESS;
}
Exemplo n.º 6
0
NTSTATUS
AcquireLMCredentials (
    VOID
    )
{
    UNICODE_STRING Ntlm;
    PUCHAR AllocateMemory = NULL;
    ULONG AllocateLength = 8;
    NTSTATUS status;
    TimeStamp Expiry;

    status = NtAllocateVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                0,
                &AllocateLength,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    if ( !NT_SUCCESS(status) ) {
        return status;
    }

    Ntlm.Length = Ntlm.MaximumLength = 8;
    Ntlm.Buffer = (LPWSTR)AllocateMemory,
    RtlCopyMemory( Ntlm.Buffer, L"NTLM", 8 );

    status = AcquireCredentialsHandle(
                NULL,                   // Default principal
                (PSECURITY_STRING) &Ntlm,
                SECPKG_CRED_INBOUND,    // Need to define this
                NULL,                   // No LUID
                NULL,                   // No AuthData
                NULL,                   // No GetKeyFn
                NULL,                   // No GetKeyArg
                &SrvLmLsaHandle,
                &Expiry
                );

     (VOID)NtFreeVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                &AllocateLength,
                MEM_DECOMMIT
                );

    if ( !NT_SUCCESS(status) ) {
        status = MapSecurityError(status);
        return status;
    }
    SrvHaveCreds |= HAVENTLM;

    return status;

} // AcquireLMCredentials
Exemplo n.º 7
0
void LSSLContext::AcquireCredentials()
{
	//SSPI:инициализация удостоверения
	//параметны получаемого удостоверения пользователя
	SCHANNEL_CRED credData;
	ZeroMemory(&credData, sizeof(credData));
	credData.dwVersion = SCHANNEL_CRED_VERSION;

	//получение дискриптора удостоверения пользователя
	SECURITY_STATUS sec_s = AcquireCredentialsHandle(0, UNISP_NAME, SECPKG_CRED_OUTBOUND, 0, &credData, 0, 0, &m_hUserCred, &m_UserCredExpiry);
	//ASSERT(SEC_E_OK==sec_s);
}
Exemplo n.º 8
0
	SchannelCredential(ULONG usage, SchannelCredentialData* pCredentialData)
	{
		SECURITY_STATUS result = AcquireCredentialsHandle(
			NULL,
			UNISP_NAME,
			usage,
			NULL,
			pCredentialData,
			NULL,
			NULL,
			&credentialHandle_,
			NULL);
	}
Exemplo n.º 9
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *c = h->priv_data;
    TLSShared *s = &c->tls_shared;
    SECURITY_STATUS sspi_ret;
    SCHANNEL_CRED schannel_cred = { 0 };
    int ret;

    if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
        goto fail;

    if (s->listen) {
        av_log(h, AV_LOG_ERROR, "TLS Listen Sockets with SChannel is not implemented.\n");
        ret = AVERROR(EINVAL);
        goto fail;
    }

    /* SChannel Options */
    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;

    if (s->verify)
        schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
                                SCH_CRED_REVOCATION_CHECK_CHAIN;
    else
        schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
                                SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
                                SCH_CRED_IGNORE_REVOCATION_OFFLINE;

    /* Get credential handle */
    sspi_ret = AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND,
                                        NULL,  &schannel_cred, NULL, NULL, &c->cred_handle,
                                        &c->cred_timestamp);
    if (sspi_ret != SEC_E_OK) {
        av_log(h, AV_LOG_ERROR, "Unable to acquire security credentials (0x%lx)\n", sspi_ret);
        ret = AVERROR_UNKNOWN;
        goto fail;
    }

    ret = tls_client_handshake(h);
    if (ret < 0)
        goto fail;

    c->connected = 1;

    return 0;

fail:
    tls_close(h);
    return ret;
}
Exemplo n.º 10
0
apr_status_t
serf__spnego_create_sec_context(serf__spnego_context_t **ctx_p,
                                const serf__authn_scheme_t *scheme,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
    SECURITY_STATUS sspi_status;
    serf__spnego_context_t *ctx;
    const char *sspi_package;

    ctx = apr_pcalloc(result_pool, sizeof(*ctx));

    SecInvalidateHandle(&ctx->sspi_context);
    SecInvalidateHandle(&ctx->sspi_credentials);
    ctx->initalized = FALSE;
    ctx->pool = result_pool;
    ctx->target_name = NULL;
    ctx->authn_type = scheme->type;

    apr_pool_cleanup_register(result_pool, ctx,
                              cleanup_ctx,
                              apr_pool_cleanup_null);

    if (ctx->authn_type == SERF_AUTHN_NEGOTIATE)
        sspi_package = "Negotiate";
    else
        sspi_package = "NTLM";

    sspi_status = AcquireCredentialsHandle(
        NULL, sspi_package, SECPKG_CRED_OUTBOUND,
        NULL, NULL, NULL, NULL,
        &ctx->sspi_credentials, NULL);

    if (FAILED(sspi_status)) {
        return map_sspi_status(sspi_status);
    }

    *ctx_p = ctx;

    return APR_SUCCESS;
}
Exemplo n.º 11
0
BOOL AcquireCreds()
{
    SECURITY_STATUS   ss;
    TimeStamp         Lifetime;
    PSecPkgInfo       pkgInfo;

    //  Set the default package to negotiate.
    tstrcpy_s(g_lpPackageName, 1024, TEXT("Negotiate"));

    // Initialize the security package.
    ss = QuerySecurityPackageInfo(g_lpPackageName, &pkgInfo);

    // get the max token size
    g_cbMaxMessage = pkgInfo->cbMaxToken;
    FreeContextBuffer(pkgInfo);

    // set the max token sizes
    g_pInBuf = (PBYTE)malloc(g_cbMaxMessage);
    g_pOutBuf = (PBYTE)malloc(g_cbMaxMessage);

    // get the security handles
    ss = AcquireCredentialsHandle(
        NULL,
        g_lpPackageName,
        SECPKG_CRED_INBOUND,
        NULL,
        NULL,
        NULL,
        NULL,
        &hcred,
        &Lifetime);

    if (!SEC_SUCCESS(ss))
    {
        fprintf(stderr, "AcquireCreds failed: 0x%08x\n", ss);
        return(FALSE);
    }

    return (TRUE);
}
Exemplo n.º 12
0
static void
GetNewSchannelClientCredentials(
		CredHandle *phCreds,
		CtxtHandle *phContext)
{
	SCHANNEL_CRED	SchannelCred;
	CredHandle	hCreds;
	SecPkgContext_IssuerListInfoEx	IssuerListInfo;
	PCCERT_CHAIN_CONTEXT		pChainContext;
	CERT_CHAIN_FIND_BY_ISSUER_PARA	FindByIssuerPara;
	PCCERT_CONTEXT	pCertContext;
	TimeStamp	tsExpiry;
	SECURITY_STATUS	Status;

	/*
	 * Read list of trusted issuers from schannel.
	 */

	Status = QueryContextAttributes(phContext,
					SECPKG_ATTR_ISSUER_LIST_EX,
					(PVOID)&IssuerListInfo);
	if (Status != SEC_E_OK)
	{
		mylog("Error 0x%p querying issuer list info\n", Status);
		return;
	}

	/*
	 * Enumerate the client certificates.
	 */

	ZeroMemory(&FindByIssuerPara, sizeof(FindByIssuerPara));

	FindByIssuerPara.cbSize = sizeof(FindByIssuerPara);
	FindByIssuerPara.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH;
	FindByIssuerPara.dwKeySpec	= 0;
	FindByIssuerPara.cIssuer	= IssuerListInfo.cIssuers;
	FindByIssuerPara.rgIssuer	= IssuerListInfo.aIssuers;

	pChainContext = NULL;

	while (TRUE)
	{
		/* Find a certificate chain. */
		pChainContext = CertFindChainInStore(hMyCertStore,
						X509_ASN_ENCODING,
						0,
						CERT_CHAIN_FIND_BY_ISSUER,
						&FindByIssuerPara,
						pChainContext);
		if (pChainContext == NULL)
		{
			mylog("Error 0x%p finding cert chain\n", GetLastError());
			break;
		}
		mylog("\ncertificate chain found\n");

		/* Get pointer to leaf certificate context. */
		pCertContext = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext;

		ZeroMemory(&SchannelCred, sizeof(SchannelCred));
        	/* Create schannel credential. */
        	SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
        	SchannelCred.cCreds = 1;
        	SchannelCred.paCred = &pCertContext;

        	Status = AcquireCredentialsHandle(
                            NULL,		/* Name of principal */
                            UNI_SCHANNEL,	/* Name of package */
                            SECPKG_CRED_OUTBOUND,	/* Flags indicating use */
                            NULL,		/* Pointer to logon ID */
                            &SchannelCred,	/* Package specific data */
                            NULL,		/* Pointer to GetKey() func */
                            NULL,		/* Value to pass to GetKey() */
                            &hCreds,		/* (out) Cred Handle */
                            &tsExpiry);		/* (out) Lifetime (optional) */
		if (Status != SEC_E_OK)
		{
			 mylog("**** Error 0x%p returned by AcquireCredentialsHandle\n", Status);
			continue;
		}
		mylog("\nnew schannel credential created\n");

		/* Destroy the old credentials. */
		FreeCredentialsHandle(phCreds);

		*phCreds = hCreds;

		/*
		 * As you can see, this sample code maintains a single credential
		 * handle, replacing it as necessary. This is a little unusual.
		 *
		 * Many applications maintain a global credential handle that's
		 * anonymous (that is, it doesn't contain a client certificate),
		 * which is used to connect to all servers. If a particular server
		 * should require client authentication, then a new credential 
		 * is created for use when connecting to that server. The global
		 * anonymous credential is retained for future connections to
		 * other servers.
		 *
		 * Maintaining a single anonymous credential that's used whenever
		 * possible is most efficient, since creating new credentials all
		 * the time is rather expensive.
		 */

		break;
	}
}
Exemplo n.º 13
0
int sqAuthInitiate(char *method, char *username, char *password, char *domain, char *principal){
  SEC_WINNT_AUTH_IDENTITY credentials;
  SECURITY_STATUS ret;
  ULONG flags = DEFAULT_AUTH_FLAGS;
  ULONG attrs = 0;
  sqAuthData *auth;


  if(debug) {
    printf("sqAuthInitiate: method=%s, user=%s, pass=%s, domain=%s\n",
	   method, username, password, domain);
  }

  auth = calloc(1, sizeof(sqAuthData));
  if(principal) auth->principal = strdup(principal);
  auth->sbdIn.ulVersion = SECBUFFER_VERSION;
  auth->sbdIn.pBuffers = auth->inbuf;
  auth->sbdOut.ulVersion = SECBUFFER_VERSION;
  auth->sbdOut.pBuffers = auth->outbuf;

  /* initialize additional credentials */
  memset(&credentials,0,sizeof(SEC_WINNT_AUTH_IDENTITY));

  // XXXX: fixme. use unicode and utf8 conversion
  credentials.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  if(username) {
    credentials.User = username;
    credentials.UserLength = strlen(username);
  }
  if(password) {
    credentials.Password = password;
    credentials.PasswordLength = strlen(password);
  }
  if(domain) {
    credentials.Domain = domain;
    credentials.DomainLength = strlen(domain);
  }

  ret = AcquireCredentialsHandle(NULL, method, SECPKG_CRED_OUTBOUND, NULL,
								 username ? &credentials : NULL,
                                 NULL, NULL, &auth->cred, &auth->expiry);

  if (ret != SEC_E_OK) {
    if(debug) printf("AquireCredentialsHandle error: %x\n", ret);
    return 0;
  }

  auth->outbuf[0].BufferType = SECBUFFER_TOKEN;
  auth->outbuf[0].cbBuffer = 0;
  auth->outbuf[0].pvBuffer = NULL;
  auth->outbuf[1].BufferType = SECBUFFER_EMPTY;
  auth->outbuf[1].cbBuffer = 0;
  auth->outbuf[1].pvBuffer = NULL;
  auth->sbdOut.cBuffers = 2;

  ret = InitializeSecurityContext(&auth->cred, 
				  NULL, 
				  auth->principal,
				  flags, 
				  0, 
				  SECURITY_NETWORK_DREP,
				  NULL,
				  0,
				  &auth->ctxt,
				  &auth->sbdOut,
				  &attrs,
				  NULL);

  /* The only expected return value here is SEC_I_CONTINUE_NEEDED
     since we're just trying to establish the auth session */
  if(ret != SEC_I_CONTINUE_NEEDED) {
    if(debug) printf("InitializeSecurityContext returned: %x\n", ret);
    return 0;
  }
  /* XXXX: fixme. return a real handle */
  return (int)auth;

}
Exemplo n.º 14
0
BOOL GenClientContext (
BYTE       *pIn,
DWORD       cbIn,
BYTE       *pOut,
DWORD      *pcbOut,
BOOL       *pfDone,
CHAR       *pszTarget,
CredHandle *hCred,
struct _SecHandle *hcText)
{
	SECURITY_STATUS   ss;
	TimeStamp         Lifetime;
	SecBufferDesc     OutBuffDesc;
	SecBuffer         OutSecBuff;
	SecBufferDesc     InBuffDesc;
	SecBuffer         InSecBuff;
	ULONG             ContextAttributes;
	static TCHAR      lpPackageName[1024];

	if( NULL == pIn )  
	{   
		strcpy_s(lpPackageName, 1024 * sizeof(TCHAR), "Negotiate");
		ss = AcquireCredentialsHandle (
		NULL, 
		lpPackageName,
		SECPKG_CRED_OUTBOUND,
		NULL, 
		NULL, 
		NULL, 
		NULL, 
		hCred,
		&Lifetime);

		if (!(SEC_SUCCESS (ss)))
		{
			MyHandleError("AcquireCreds failed ");
		}
	}

	//--------------------------------------------------------------------
	//  Prepare the buffers.

	OutBuffDesc.ulVersion = 0;
	OutBuffDesc.cBuffers  = 1;
	OutBuffDesc.pBuffers  = &OutSecBuff;

	OutSecBuff.cbBuffer   = *pcbOut;
	OutSecBuff.BufferType = SECBUFFER_TOKEN;
	OutSecBuff.pvBuffer   = pOut;

	//-------------------------------------------------------------------
	//  The input buffer is created only if a message has been received 
	//  from the server.

	if (pIn)   
	{
		InBuffDesc.ulVersion = 0;
		InBuffDesc.cBuffers  = 1;
		InBuffDesc.pBuffers  = &InSecBuff;

		InSecBuff.cbBuffer   = cbIn;
		InSecBuff.BufferType = SECBUFFER_TOKEN;
		InSecBuff.pvBuffer   = pIn;

		ss = InitializeSecurityContext (
		hCred,
		hcText,
		pszTarget,
		MessageAttribute, 
		0,
		SECURITY_NATIVE_DREP,
		&InBuffDesc,
		0, 
		hcText,
		&OutBuffDesc,
		&ContextAttributes,
		&Lifetime);
	}
	else
	{
		ss = InitializeSecurityContext (
		hCred,
		NULL,
		pszTarget,
		MessageAttribute, 
		0, 
		SECURITY_NATIVE_DREP,
		NULL,
		0, 
		hcText,
		&OutBuffDesc,
		&ContextAttributes,
		&Lifetime);
	}

	if (!SEC_SUCCESS (ss))  
	{
		MyHandleError ("InitializeSecurityContext failed " );
	}

	//-------------------------------------------------------------------
	//  If necessary, complete the token.

	if ((SEC_I_COMPLETE_NEEDED == ss) 
			|| (SEC_I_COMPLETE_AND_CONTINUE == ss))  
	{
		ss = CompleteAuthToken (hcText, &OutBuffDesc);
		if (!SEC_SUCCESS(ss))  
		{
			fprintf (stderr, "complete failed: 0x%08x\n", ss);
			return FALSE;
		}
	}

	*pcbOut = OutSecBuff.cbBuffer;

	*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
	(SEC_I_COMPLETE_AND_CONTINUE == ss));

	printf ("Token buffer generated (%lu bytes):\n", OutSecBuff.cbBuffer);
	PrintHexDump (OutSecBuff.cbBuffer, (PBYTE)OutSecBuff.pvBuffer);
	return TRUE;

}
Exemplo n.º 15
0
/*
 * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store
 *                              If one cannot be found, one is created.
 */
BOOL					/* O - 1 on success, 0 on failure */
_sspiGetCredentials(_sspi_struct_t *conn,
					/* I - Client connection */
                    const LPWSTR   container,
					/* I - Cert container name */
                    const TCHAR    *cn,	/* I - Common name of certificate */
                    BOOL           isServer)
					/* I - Is caller a server? */
{
  HCERTSTORE		store = NULL;	/* Certificate store */
  PCCERT_CONTEXT	storedContext = NULL;
					/* Context created from the store */
  PCCERT_CONTEXT	createdContext = NULL;
					/* Context created by us */
  DWORD			dwSize = 0;	/* 32 bit size */
  PBYTE			p = NULL;	/* Temporary storage */
  HCRYPTPROV		hProv = (HCRYPTPROV) NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB	sib;		/* Arbitrary array of bytes */
  SCHANNEL_CRED		SchannelCred;	/* Schannel credential data */
  TimeStamp		tsExpiry;	/* Time stamp */
  SECURITY_STATUS	Status;		/* Status */
  HCRYPTKEY		hKey = (HCRYPTKEY) NULL;
					/* Handle to crypto key */
  CRYPT_KEY_PROV_INFO	kpi;		/* Key container info */
  SYSTEMTIME		et;		/* System time */
  CERT_EXTENSIONS	exts;		/* Array of cert extensions */
  CRYPT_KEY_PROV_INFO	ckp;		/* Handle to crypto key */
  BOOL			ok = TRUE;	/* Return value */


  DEBUG_printf(("_sspiGetCredentials(conn=%p, container=%p, cn=\"%s\", isServer=%d)", conn, container, cn, isServer));

  if (!conn)
    return (FALSE);
  if (!cn)
    return (FALSE);

  if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                           PROV_RSA_FULL,
                           CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                               PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n",
                      GetLastError()));
        ok = FALSE;
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                        X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                        hProv,
                        CERT_SYSTEM_STORE_LOCAL_MACHINE |
                        CERT_STORE_NO_CRYPT_RELEASE_FLAG |
                        CERT_STORE_OPEN_EXISTING_FLAG,
                        L"MY");

  if (!store)
  {
    DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n",
                  GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR,
                     NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n",
                   GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  p = (PBYTE) malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize));
    ok = FALSE;
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL,
                     p, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x",
                 GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  sib.cbData = dwSize;
  sib.pbData = p;

  storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                                             0, CERT_FIND_SUBJECT_NAME, &sib, NULL);

  if (!storedContext)
  {
   /*
    * If we couldn't find the context, then we'll
    * create a new one
    */
    if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
    {
      DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&kpi, sizeof(kpi));
    kpi.pwszContainerName = (LPWSTR) container;
    kpi.pwszProvName = MS_DEF_PROV_W;
    kpi.dwProvType = PROV_RSA_FULL;
    kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
    kpi.dwKeySpec = AT_KEYEXCHANGE;

    GetSystemTime(&et);
    et.wYear += 10;

    ZeroMemory(&exts, sizeof(exts));

    createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL,
                                                   &et, &exts);

    if (!createdContext)
    {
      DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x",
                   GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    if (!CertAddCertificateContextToStore(store, createdContext,
                                          CERT_STORE_ADD_REPLACE_EXISTING,
                                          &storedContext))
    {
      DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&ckp, sizeof(ckp));
    ckp.pwszContainerName = (LPWSTR) container;
    ckp.pwszProvName = MS_DEF_PROV_W;
    ckp.dwProvType = PROV_RSA_FULL;
    ckp.dwFlags = CRYPT_MACHINE_KEYSET;
    ckp.dwKeySpec = AT_KEYEXCHANGE;

    if (!CertSetCertificateContextProperty(storedContext,
                                           CERT_KEY_PROV_INFO_PROP_ID,
                                           0, &ckp))
    {
      DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }
  }

  ZeroMemory(&SchannelCred, sizeof(SchannelCred));

  SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
  SchannelCred.cCreds = 1;
  SchannelCred.paCred = &storedContext;

 /*
  * SSPI doesn't seem to like it if grbitEnabledProtocols
  * is set for a client
  */
  if (isServer)
    SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1;

 /*
  * Create an SSPI credential.
  */
  Status = AcquireCredentialsHandle(NULL, UNISP_NAME,
                                    isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND,
                                    NULL, &SchannelCred, NULL, NULL, &conn->creds,
                                    &tsExpiry);
  if (Status != SEC_E_OK)
  {
    DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status));
    ok = FALSE;
    goto cleanup;
  }

cleanup:

 /*
  * Cleanup
  */
  if (hKey)
    CryptDestroyKey(hKey);

  if (createdContext)
    CertFreeCertificateContext(createdContext);

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  return (ok);
}
Exemplo n.º 16
0
static
DWORD
ClientEstablishContext(
    IN PCSTR pSPN,
    IN INT nSocket,
    IN PCSTR pServiceName,
    IN PCSTR pServicePassword,
    IN PCSTR pServiceRealm,
    IN ULONG DelegFlag,
    OUT CtxtHandle *pSspiContext,
    IN PCSTR pSecPkgName,
    OUT ULONG *pRetFlags
    )
{
    DWORD dwError = ERROR_SUCCESS;
    DWORD dwLoopError = ERROR_SUCCESS;
    PCtxtHandle pContextHandle = NULL;
    INT nCredentialsAcquired = 0;
    INT nContextAcquired = 0;

    SecBuffer SendTokenBuffer;
    SecBuffer RecvTokenBuffer;
    SecBufferDesc InputDesc;
    SecBufferDesc OutputDesc;
    CredHandle CredHandle;
    TimeStamp Expiry;
    SEC_WINNT_AUTH_IDENTITY AuthIdentity;
    PSEC_WINNT_AUTH_IDENTITY pAuthId = NULL;

    memset(&SendTokenBuffer, 0, sizeof(SecBuffer));
    memset(&RecvTokenBuffer, 0, sizeof(SecBuffer));
    memset(&InputDesc, 0, sizeof(SecBufferDesc));
    memset(&OutputDesc, 0, sizeof(SecBufferDesc));
    memset(&CredHandle, 0, sizeof(CredHandle));
    memset(&Expiry, 0, sizeof(TimeStamp));
    memset(&AuthIdentity, 0, sizeof(AuthIdentity));

    memset(pSspiContext, 0, sizeof(CtxtHandle));
    *pRetFlags = 0;

    InputDesc.cBuffers = 1;
    InputDesc.pBuffers = &RecvTokenBuffer;
    InputDesc.ulVersion = SECBUFFER_VERSION;

    RecvTokenBuffer.BufferType = SECBUFFER_TOKEN;
    RecvTokenBuffer.cbBuffer = 0;
    RecvTokenBuffer.pvBuffer = NULL;

    OutputDesc.cBuffers = 1;
    OutputDesc.pBuffers = &SendTokenBuffer;
    OutputDesc.ulVersion = SECBUFFER_VERSION;

    SendTokenBuffer.BufferType = SECBUFFER_TOKEN;
    SendTokenBuffer.cbBuffer = 0;
    SendTokenBuffer.pvBuffer = NULL;

    CredHandle.dwLower = 0;
    CredHandle.dwUpper = 0;

    if (pServiceName)
    {
        AuthIdentity.User = (PBYTE) pServiceName;
        AuthIdentity.UserLength = (DWORD)strlen(pServiceName);
        pAuthId = &AuthIdentity;
    }

    if (pServicePassword)
    {
        AuthIdentity.Password = (PBYTE) pServicePassword;
        AuthIdentity.PasswordLength = (DWORD)strlen(pServicePassword);
        pAuthId = &AuthIdentity;
    }

    if (pServiceRealm)
    {
        AuthIdentity.Domain = (PBYTE) pServiceRealm;
        AuthIdentity.DomainLength = (DWORD)strlen(pServiceRealm);
        pAuthId = &AuthIdentity;
    }
    AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    dwError = AcquireCredentialsHandle(
        NULL,                       // no principal name
        (PSTR) pSecPkgName,                // package name
        SECPKG_CRED_OUTBOUND,
        NULL,                       // no logon id
        pAuthId,
        NULL,                       // no get key fn
        NULL,                       // noget key arg
        &CredHandle,
        &Expiry
        );

    BAIL_ON_ERROR(dwError);

    nCredentialsAcquired = 1;

   /*
    * Perform the context-establishement loop.
    */

    pSspiContext->dwLower = 0;
    pSspiContext->dwUpper = 0;

    do
    {
        // we need to use dwLoopErr in this case because we may get
        // back a "continue" command.  In those cases, we still
        // need dwError to be used and set seperatly based on other
        // calls.
        dwLoopError =
            InitializeSecurityContext(
                &CredHandle,
                pContextHandle,
                (PSTR) pSPN,
                DelegFlag,
                0,          // reserved
                SECURITY_NATIVE_DREP,
                &InputDesc,
                0,          // reserved
                pSspiContext,
                &OutputDesc,
                pRetFlags,
                &Expiry
                );

        if (SEC_E_OK != dwLoopError && SEC_I_CONTINUE_NEEDED != dwLoopError)
        {
            dwError = dwLoopError;
            BAIL_ON_ERROR(dwError);
        }

        nContextAcquired = 1;

        if (SEC_I_CONTINUE_NEEDED == dwLoopError)
        {
	    PNTLM_NEGOTIATE_MESSAGE pMsg = (PNTLM_NEGOTIATE_MESSAGE) SendTokenBuffer.pvBuffer;
	    // Adjust any flags for debugging
	    // pMsg->NtlmFlags |= NTLM_FLAG_SEAL;
            printf("Context partially initialized...\n");

            DumpBuffer(SendTokenBuffer.pvBuffer, SendTokenBuffer.cbBuffer);
            DumpNtlmMessage(SendTokenBuffer.pvBuffer, SendTokenBuffer.cbBuffer);
            printf("\n");
            printf("Flags returned:\n");
            DumpIscRetFlags(*pRetFlags);
            printf("\n");
        }
        else
        {
	    PNTLM_RESPONSE_MESSAGE pMsg = (PNTLM_RESPONSE_MESSAGE) SendTokenBuffer.pvBuffer;
	    // Adjust any flags for debugging
	    //pMsg->NtlmFlags |= NTLM_FLAG_SEAL;

            printf("Context FULLY initialized!\n");
            DumpBuffer(SendTokenBuffer.pvBuffer, SendTokenBuffer.cbBuffer);
            DumpNtlmMessage(SendTokenBuffer.pvBuffer, SendTokenBuffer.cbBuffer);
            printf("\n");
            printf("Flags returned:\n");
            DumpIscRetFlags(*pRetFlags);
            printf("\n");
        }

        pContextHandle = pSspiContext;

        if (RecvTokenBuffer.pvBuffer)
        {
            free(RecvTokenBuffer.pvBuffer);
            RecvTokenBuffer.pvBuffer = NULL;
            RecvTokenBuffer.cbBuffer = 0;
        }

        if (SendTokenBuffer.cbBuffer != 0)
        {
            dwError = SendToken(nSocket, &SendTokenBuffer);
            BAIL_ON_ERROR(dwError);
        }

        FreeContextBuffer(SendTokenBuffer.pvBuffer);
        SendTokenBuffer.pvBuffer = NULL;
        SendTokenBuffer.cbBuffer = 0;

        if (SEC_I_CONTINUE_NEEDED == dwLoopError)
        {
            dwError = RecvToken(nSocket, &RecvTokenBuffer);
            BAIL_ON_ERROR(dwError);
            printf("RECEIVED:\n");
            DumpBuffer(RecvTokenBuffer.pvBuffer, RecvTokenBuffer.cbBuffer);
            DumpNtlmMessage(RecvTokenBuffer.pvBuffer, RecvTokenBuffer.cbBuffer);
            printf("\n");
        }

    } while (dwLoopError == SEC_I_CONTINUE_NEEDED);

    FreeCredentialsHandle(&CredHandle);

finish:
    return dwError;
error:
    if (nCredentialsAcquired)
    {
        FreeCredentialsHandle(&CredHandle);
    }
    if (nContextAcquired)
    {
        DeleteSecurityContext(pSspiContext);
        memset(pSspiContext, 0, sizeof(CtxtHandle));
    }
    if (RecvTokenBuffer.pvBuffer)
    {
        free(RecvTokenBuffer.pvBuffer);
    }
    if (SendTokenBuffer.cbBuffer)
    {
        FreeContextBuffer(SendTokenBuffer.pvBuffer);
    }

    goto finish;
}
Exemplo n.º 17
0
int SSL_SOCKET :: ServerInit(bool NoLoop)
	{
	SECURITY_STATUS ss = 0;

/*	if (wcslen(un))
		{
		// Find certificate in the store
		// Open Certificate Store
		hCS = CertOpenSystemStore(0,_T("MY"));
		if (!hCS)
			return -1;

		CERT_RDN cert_rdn;
		CERT_RDN_ATTR cert_rdn_attr;

		cert_rdn.cRDNAttr = 1;
		cert_rdn.rgRDNAttr = &cert_rdn_attr;

		cert_rdn_attr.pszObjId = szOID_COMMON_NAME;
		cert_rdn_attr.dwValueType = CERT_RDN_ANY_TYPE;
		cert_rdn_attr.Value.cbData = (DWORD)wcslen(un);

		cert_rdn_attr.Value.pbData = (BYTE *)un;
		OurCertificate = CertFindCertificateInStore(hCS, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,0,cft,&cert_rdn,NULL);
		}*/
	if (IsExternalCert)
		{
		;
		}
	else
		{
		//BOOL AX;
		OurCertificate = CreateOurCertificate();
		}

	// Configure our SSL SChannel
	memset(&m_SchannelCred,0,sizeof(m_SchannelCred));
	m_SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
	m_SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
	m_SchannelCred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_REVOCATION_CHECK_CHAIN;
	m_SchannelCred.hRootStore = hCS;
	m_SchannelCred.dwMinimumCipherStrength = 128;




	if (OurCertificate)
		{
		m_SchannelCred.cCreds     = 1;
		m_SchannelCred.paCred     = &OurCertificate;
		}

	// AcquireCredentialsHandle

	ss = AcquireCredentialsHandle(0,SCHANNEL_NAME,SECPKG_CRED_INBOUND,0,&m_SchannelCred,0,0,&hCred,0);
//	ss = AcquireCredentialsHandle(0,UNISP_NAME,SECPKG_CRED_INBOUND,0,&m_SchannelCred,0,0,&hCred,0);
	if (FAILED(ss))
		return -1;

	if (NoLoop)
		return 0;
	return ServerLoop();
	}
Exemplo n.º 18
0
char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw, bool http, unsigned& complete)
{
	if (hSecurity == NULL || ntlmCnt == 0)
		return NULL;

	SecBufferDesc outputBufferDescriptor, inputBufferDescriptor;
	SecBuffer outputSecurityToken, inputSecurityToken;
	TimeStamp tokenExpiration;
	ULONG contextAttributes;
	char *szOutputToken;

	NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity;
	if (mir_tstrcmpi(hNtlm->szProvider, _T("Basic"))) {
		bool isGSSAPI = mir_tstrcmpi(hNtlm->szProvider, _T("GSSAPI")) == 0;
		TCHAR *szProvider = isGSSAPI ? (TCHAR*)_T("Kerberos") : hNtlm->szProvider;
		bool hasChallenge = szChallenge != NULL && szChallenge[0] != '\0';
		if (hasChallenge) {
			unsigned tokenLen;
			BYTE *token = (BYTE*)mir_base64_decode(szChallenge, &tokenLen);
			if (token == NULL)
				return NULL;

			if (isGSSAPI && complete)
				return CompleteGssapi(hSecurity, token, tokenLen);

			inputBufferDescriptor.cBuffers = 1;
			inputBufferDescriptor.pBuffers = &inputSecurityToken;
			inputBufferDescriptor.ulVersion = SECBUFFER_VERSION;
			inputSecurityToken.BufferType = SECBUFFER_TOKEN;
			inputSecurityToken.cbBuffer = tokenLen;
			inputSecurityToken.pvBuffer = token;

			// try to decode the domain name from the NTLM challenge
			if (login != NULL && login[0] != '\0' && !hNtlm->hasDomain) {
				NtlmType2packet* pkt = (NtlmType2packet*)token;
				if (!strncmp(pkt->sign, "NTLMSSP", 8) && pkt->type == 2) {

					wchar_t* domainName = (wchar_t*)&token[pkt->targetName.offset];
					int domainLen = pkt->targetName.len;

					// Negotiate ANSI? if yes, convert the ANSI name to unicode
					if ((pkt->flags & 1) == 0) {
						int bufsz = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, NULL, 0);
						wchar_t* buf = (wchar_t*)alloca(bufsz * sizeof(wchar_t));
						domainLen = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, buf, bufsz) - 1;
						domainName = buf;
					}
					else domainLen /= sizeof(wchar_t);

					if (domainLen) {
						size_t newLoginLen = mir_tstrlen(login) + domainLen + 1;
						TCHAR *newLogin = (TCHAR*)alloca(newLoginLen * sizeof(TCHAR));

						_tcsncpy(newLogin, domainName, domainLen);
						newLogin[domainLen] = '\\';
						mir_tstrcpy(newLogin + domainLen + 1, login);

						char* szChl = NtlmCreateResponseFromChallenge(hSecurity, NULL, newLogin, psw, http, complete);
						mir_free(szChl);
					}
				}
			}
		}
		else {
			if (SecIsValidHandle(&hNtlm->hClientContext))
				DeleteSecurityContext(&hNtlm->hClientContext);
			if (SecIsValidHandle(&hNtlm->hClientCredential))
				FreeCredentialsHandle(&hNtlm->hClientCredential);

			SEC_WINNT_AUTH_IDENTITY auth;

			if (login != NULL && login[0] != '\0') {
				memset(&auth, 0, sizeof(auth));

				NetlibLogf(NULL, "Security login requested, user: %S pssw: %s", login, psw ? "(exist)" : "(no psw)");

				const TCHAR* loginName = login;
				const TCHAR* domainName = _tcschr(login, '\\');
				size_t domainLen = 0;
				size_t loginLen = mir_tstrlen(loginName);
				if (domainName != NULL) {
					loginName = domainName + 1;
					loginLen = mir_tstrlen(loginName);
					domainLen = domainName - login;
					domainName = login;
				}
				else if ((domainName = _tcschr(login, '@')) != NULL) {
					loginName = login;
					loginLen = domainName - login;
					domainLen = mir_tstrlen(++domainName);
				}

				auth.User = (PWORD)loginName;
				auth.UserLength = (ULONG)loginLen;
				auth.Password = (PWORD)psw;
				auth.PasswordLength = (ULONG)mir_tstrlen(psw);
				auth.Domain = (PWORD)domainName;
				auth.DomainLength = (ULONG)domainLen;
				auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

				hNtlm->hasDomain = domainLen != 0;
			}

			SECURITY_STATUS sc = AcquireCredentialsHandle(NULL, szProvider,
				SECPKG_CRED_OUTBOUND, NULL, hNtlm->hasDomain ? &auth : NULL, NULL, NULL,
				&hNtlm->hClientCredential, &tokenExpiration);
			if (sc != SEC_E_OK) {
				ReportSecError(sc, __LINE__);
				return NULL;
			}
		}

		outputBufferDescriptor.cBuffers = 1;
		outputBufferDescriptor.pBuffers = &outputSecurityToken;
		outputBufferDescriptor.ulVersion = SECBUFFER_VERSION;
		outputSecurityToken.BufferType = SECBUFFER_TOKEN;
		outputSecurityToken.cbBuffer = hNtlm->cbMaxToken;
		outputSecurityToken.pvBuffer = alloca(outputSecurityToken.cbBuffer);

		SECURITY_STATUS sc = InitializeSecurityContext(&hNtlm->hClientCredential,
			hasChallenge ? &hNtlm->hClientContext : NULL,
			hNtlm->szPrincipal, isGSSAPI ? ISC_REQ_MUTUAL_AUTH | ISC_REQ_STREAM : 0, 0, SECURITY_NATIVE_DREP,
			hasChallenge ? &inputBufferDescriptor : NULL, 0, &hNtlm->hClientContext,
			&outputBufferDescriptor, &contextAttributes, &tokenExpiration);

		complete = (sc != SEC_I_COMPLETE_AND_CONTINUE && sc != SEC_I_CONTINUE_NEEDED);

		if (sc == SEC_I_COMPLETE_NEEDED || sc == SEC_I_COMPLETE_AND_CONTINUE)
			sc = CompleteAuthToken(&hNtlm->hClientContext, &outputBufferDescriptor);

		if (sc != SEC_E_OK && sc != SEC_I_CONTINUE_NEEDED) {
			ReportSecError(sc, __LINE__);
			return NULL;
		}

		szOutputToken = mir_base64_encode((PBYTE)outputSecurityToken.pvBuffer, outputSecurityToken.cbBuffer);
	}
	else {
		if (!login || !psw) return NULL;

		char *szLogin = mir_t2a(login);
		char *szPassw = mir_t2a(psw);

		size_t authLen = mir_strlen(szLogin) + mir_strlen(szPassw) + 5;
		char *szAuth = (char*)alloca(authLen);

		int len = mir_snprintf(szAuth, authLen, "%s:%s", szLogin, szPassw);
		szOutputToken = mir_base64_encode((BYTE*)szAuth, len);
		complete = true;

		mir_free(szPassw);
		mir_free(szLogin);
	}

	if (szOutputToken == NULL)
		return NULL;

	if (!http)
		return szOutputToken;

	ptrA szProvider(mir_t2a(hNtlm->szProvider));
	size_t resLen = mir_strlen(szOutputToken) + mir_strlen(szProvider) + 10;
	char *result = (char*)mir_alloc(resLen);
	mir_snprintf(result, resLen, "%s %s", szProvider, szOutputToken);
	mir_free(szOutputToken);
	return result;
}
Exemplo n.º 19
0
static int
pg_SSPI_recvauth(Port *port)
{
	int			mtype;
	StringInfoData buf;
	SECURITY_STATUS r;
	CredHandle	sspicred;
	CtxtHandle *sspictx = NULL,
				newctx;
	TimeStamp	expiry;
	ULONG		contextattr;
	SecBufferDesc inbuf;
	SecBufferDesc outbuf;
	SecBuffer	OutBuffers[1];
	SecBuffer	InBuffers[1];
	HANDLE		token;
	TOKEN_USER *tokenuser;
	DWORD		retlen;
	char		accountname[MAXPGPATH];
	char		domainname[MAXPGPATH];
	DWORD		accountnamesize = sizeof(accountname);
	DWORD		domainnamesize = sizeof(domainname);
	SID_NAME_USE accountnameuse;
	HMODULE		secur32;
	QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;

	/*
	 * SSPI auth is not supported for protocol versions before 3, because it
	 * relies on the overall message length word to determine the SSPI payload
	 * size in AuthenticationGSSContinue and PasswordMessage messages.
	 * (This is, in fact, a design error in our SSPI support, because protocol
	 * messages are supposed to be parsable without relying on the length
	 * word; but it's not worth changing it now.)
	 */
	if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
		ereport(FATAL,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("SSPI is not supported in protocol version 2")));

	/*
	 * Acquire a handle to the server credentials.
	 */
	r = AcquireCredentialsHandle(NULL,
								 "negotiate",
								 SECPKG_CRED_INBOUND,
								 NULL,
								 NULL,
								 NULL,
								 NULL,
								 &sspicred,
								 &expiry);
	if (r != SEC_E_OK)
		pg_SSPI_error(ERROR,
			   gettext_noop("could not acquire SSPI credentials handle"), r);

	/*
	 * Loop through SSPI message exchange. This exchange can consist of
	 * multiple messags sent in both directions. First message is always from
	 * the client. All messages from client to server are password packets
	 * (type 'p').
	 */
	do
	{
		mtype = pq_getbyte();
		if (mtype != 'p')
		{
			/* Only log error if client didn't disconnect. */
			if (mtype != EOF)
				ereport(COMMERROR,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
						 errmsg("expected SSPI response, got message type %d",
								mtype)));
			return STATUS_ERROR;
		}

		/* Get the actual SSPI token */
		initStringInfo(&buf);
		if (pq_getmessage(&buf, 2000))
		{
			/* EOF - pq_getmessage already logged error */
			pfree(buf.data);
			return STATUS_ERROR;
		}

		/* Map to SSPI style buffer */
		inbuf.ulVersion = SECBUFFER_VERSION;
		inbuf.cBuffers = 1;
		inbuf.pBuffers = InBuffers;
		InBuffers[0].pvBuffer = buf.data;
		InBuffers[0].cbBuffer = buf.len;
		InBuffers[0].BufferType = SECBUFFER_TOKEN;

		/* Prepare output buffer */
		OutBuffers[0].pvBuffer = NULL;
		OutBuffers[0].BufferType = SECBUFFER_TOKEN;
		OutBuffers[0].cbBuffer = 0;
		outbuf.cBuffers = 1;
		outbuf.pBuffers = OutBuffers;
		outbuf.ulVersion = SECBUFFER_VERSION;


		elog(DEBUG4, "Processing received SSPI token of length %u",
			 (unsigned int) buf.len);

		r = AcceptSecurityContext(&sspicred,
								  sspictx,
								  &inbuf,
								  ASC_REQ_ALLOCATE_MEMORY,
								  SECURITY_NETWORK_DREP,
								  &newctx,
								  &outbuf,
								  &contextattr,
								  NULL);

		/* input buffer no longer used */
		pfree(buf.data);

		if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
		{
			/*
			 * Negotiation generated data to be sent to the client.
			 */
			elog(DEBUG4, "sending SSPI response token of length %u",
				 (unsigned int) outbuf.pBuffers[0].cbBuffer);

			port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
			port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;

			sendAuthRequest(port, AUTH_REQ_GSS_CONT);

			FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
		}

		if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
		{
			if (sspictx != NULL)
			{
				DeleteSecurityContext(sspictx);
				free(sspictx);
			}
			FreeCredentialsHandle(&sspicred);
			pg_SSPI_error(ERROR,
				  gettext_noop("could not accept SSPI security context"), r);
		}

		if (sspictx == NULL)
		{
			sspictx = malloc(sizeof(CtxtHandle));
			if (sspictx == NULL)
				ereport(ERROR,
						(errmsg("out of memory")));

			memcpy(sspictx, &newctx, sizeof(CtxtHandle));
		}

		if (r == SEC_I_CONTINUE_NEEDED)
			elog(DEBUG4, "SSPI continue needed");

	} while (r == SEC_I_CONTINUE_NEEDED);


	/*
	 * Release service principal credentials
	 */
	FreeCredentialsHandle(&sspicred);


	/*
	 * SEC_E_OK indicates that authentication is now complete.
	 *
	 * Get the name of the user that authenticated, and compare it to the pg
	 * username that was specified for the connection.
	 *
	 * MingW is missing the export for QuerySecurityContextToken in the
	 * secur32 library, so we have to load it dynamically.
	 */

	secur32 = LoadLibrary("SECUR32.DLL");
	if (secur32 == NULL)
		ereport(ERROR,
				(errmsg_internal("could not load secur32.dll: %d",
								 (int) GetLastError())));

	_QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
		GetProcAddress(secur32, "QuerySecurityContextToken");
	if (_QuerySecurityContextToken == NULL)
	{
		FreeLibrary(secur32);
		ereport(ERROR,
				(errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: %d",
								 (int) GetLastError())));
	}

	r = (_QuerySecurityContextToken) (sspictx, &token);
	if (r != SEC_E_OK)
	{
		FreeLibrary(secur32);
		pg_SSPI_error(ERROR,
			   gettext_noop("could not get security token from context"), r);
	}

	FreeLibrary(secur32);

	/*
	 * No longer need the security context, everything from here on uses the
	 * token instead.
	 */
	DeleteSecurityContext(sspictx);
	free(sspictx);

	if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
		ereport(ERROR,
			 (errmsg_internal("could not get token user size: error code %d",
							  (int) GetLastError())));

	tokenuser = malloc(retlen);
	if (tokenuser == NULL)
		ereport(ERROR,
				(errmsg("out of memory")));

	if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
		ereport(ERROR,
				(errmsg_internal("could not get user token: error code %d",
								 (int) GetLastError())));

	if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
						  domainname, &domainnamesize, &accountnameuse))
		ereport(ERROR,
			  (errmsg_internal("could not lookup acconut sid: error code %d",
							   (int) GetLastError())));

	free(tokenuser);

	/*
	 * Compare realm/domain if requested. In SSPI, always compare case
	 * insensitive.
	 */
	if (pg_krb_realm && strlen(pg_krb_realm))
	{
		if (pg_strcasecmp(pg_krb_realm, domainname))
		{
			elog(DEBUG2,
				 "SSPI domain (%s) and configured domain (%s) don't match",
				 domainname, pg_krb_realm);

			return STATUS_ERROR;
		}
	}

	/*
	 * We have the username (without domain/realm) in accountname, compare to
	 * the supplied value. In SSPI, always compare case insensitive.
	 */
	if (pg_strcasecmp(port->user_name, accountname))
	{
		/* GSS name and PGUSER are not equivalent */
		elog(DEBUG2,
			 "provided username (%s) and SSPI username (%s) don't match",
			 port->user_name, accountname);

		return STATUS_ERROR;
	}

	return STATUS_OK;
}
Exemplo n.º 20
0
SECURITY_STATUS getToken(char **negotiateToken, WCHAR *targetName, WCHAR *hostName)
{
	//----------------------------------------------------------------------
	unsigned long cPackages;
	PSecPkgInfo PackageInfo;
	SECURITY_STATUS stat;

	// Get the name of the package
	stat = EnumerateSecurityPackages(
		&cPackages,
		&PackageInfo);

	if (stat != SEC_E_OK)
	{
		wprintf(
			L"Security function failed with error: %i\n",
			stat);
		return stat;
	}

	SEC_WCHAR *szPackage = PackageInfo->Name;
	unsigned long m_cbMaxToken = PackageInfo->cbMaxToken;

	PBYTE m_pOutBuf = (PBYTE)malloc(m_cbMaxToken);

	//--------------------------------------------------------------------

	CredHandle hCredential;
	TimeStamp tsExpiry;
	PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentity = NULL; // The structure for storing user data entered

	stat = AcquireCredentialsHandle(
		NULL,
		szPackage,
		SECPKG_CRED_OUTBOUND,
		NULL,
		pAuthIdentity,
		NULL,
		NULL,
		&hCredential,
		&tsExpiry);

	if (stat != SEC_E_OK)
	{
		wprintf(
			L"Credentials function failed with error: %i\n",
			stat);
		return stat;
	}

	//--------------------------------------------------------------------

	CtxtHandle		m_hCtxt;
	SecBufferDesc	outSecBufDesc;
	SecBuffer		outSecBuf;

	unsigned long	fContextAttr;


	// prepare output buffer
	outSecBufDesc.ulVersion = 0;
	outSecBufDesc.cBuffers = 1;
	outSecBufDesc.pBuffers = &outSecBuf;
	outSecBuf.cbBuffer = m_cbMaxToken;
	outSecBuf.BufferType = SECBUFFER_TOKEN;
	outSecBuf.pvBuffer = m_pOutBuf;

	stat = InitializeSecurityContext(
		&hCredential,
		NULL,
		targetName,
		ISC_REQ_CONFIDENTIALITY,
		0,	// reserved1
		SECURITY_NATIVE_DREP,
		NULL,
		0,	// reserved2
		&m_hCtxt,
		&outSecBufDesc,
		&fContextAttr,
		&tsExpiry);

	FreeCredentialsHandle(&hCredential);

	switch (stat)
	{
	case SEC_I_CONTINUE_NEEDED: 
	case SEC_I_COMPLETE_AND_CONTINUE: CompleteAuthToken(&m_hCtxt, &outSecBufDesc); break;
	case SEC_E_OK: break;
	default: return stat;
	}

	DeleteSecurityContext(&m_hCtxt);
	FreeContextBuffer(PackageInfo);

	if (outSecBuf.cbBuffer)
	{
		base64_encode(reinterpret_cast < char* > (m_pOutBuf), outSecBuf.cbBuffer, negotiateToken);
	}
	else
	{
		return -1;
	}

	if (strlen(*negotiateToken) < 500)
	{
		CREDUI_INFO creduiInfo = { 0 };
		creduiInfo.cbSize = sizeof(creduiInfo);
		// Change the message text and caption to the actual text for your dialog.
		SEC_WCHAR message[NI_MAXHOST];

		_snwprintf_s(
			message,
			NI_MAXHOST,
			_TRUNCATE,
			L"Enter your username and password to connect to %s",
			hostName);

		creduiInfo.pszCaptionText = L"Connect to the proxy-server";
		creduiInfo.pszMessageText = message;

		BOOL fSave = TRUE; // Checkmark "Remember user"

		
		stat = SspiPromptForCredentials(
			targetName,
			&creduiInfo,
			0,
			szPackage,
			NULL,
			&pAuthIdentity,
			&fSave,
			0);
	}

	return SEC_E_OK;
}
Exemplo n.º 21
0
static
SECURITY_STATUS
CreateSchannelCredentials(
	LPCTSTR	opt,		/* in */
	LPSTR pszUserName,	/* in */
	PCredHandle phCreds)	/* out */
{
	TimeStamp	tsExpiry;
	SECURITY_STATUS	Status;
	SCHANNEL_CRED	SchannelCred;	

	DWORD		cSupportedAlgs = 0;
	ALG_ID		rgbSupportedAlgs[16];
	DWORD		dwProtocol = SP_PROT_SSL3 | SP_PROT_SSL2;
	DWORD		aiKeyExch = 0;

	PCCERT_CONTEXT  pCertContext = NULL;

	/*
	 * If a user name is specified, then attempt to find a client
	 * certificate. Otherwise, just create a NULL credential.
	 */

	if (pszUserName)
	{
		/* Find client certificate. Note that this sample just searchs for a 
		 * certificate that contains the user name somewhere in the subject name.
		 * A real application should be a bit less casual.
		 */
		pCertContext = CertFindCertificateInStore(hMyCertStore, 
							X509_ASN_ENCODING, 
							0,
							CERT_FIND_SUBJECT_STR_A,
							pszUserName,
							NULL);
		if (pCertContext == NULL)
		{
			mylog("**** Error 0x%p returned by CertFindCertificateInStore\n",
					GetLastError());
			return SEC_E_NO_CREDENTIALS;
		}
	}


	/*
	 * Build Schannel credential structure. Currently, this sample only
	 * specifies the protocol to be used (and optionally the certificate, 
	 * of course). Real applications may wish to specify other parameters 
	 * as well.
	 */

	ZeroMemory(&SchannelCred, sizeof(SchannelCred));

	SchannelCred.dwVersion  = SCHANNEL_CRED_VERSION;
	if (pCertContext)
	{
		SchannelCred.cCreds	= 1;
		SchannelCred.paCred	= &pCertContext;
	}

	SchannelCred.grbitEnabledProtocols = dwProtocol;

	if (aiKeyExch)
	{
		rgbSupportedAlgs[cSupportedAlgs++] = aiKeyExch;
	}

	if (cSupportedAlgs)
	{
		SchannelCred.cSupportedAlgs	= cSupportedAlgs;
		SchannelCred.palgSupportedAlgs	= rgbSupportedAlgs;
	}

	SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;

	/* The SCH_CRED_MANUAL_CRED_VALIDATION flag is specified because
	 * this sample verifies the server certificate manually. 
	 * Applications that expect to run on WinNT, Win9x, or WinME 
	 * should specify this flag and also manually verify the server
	 * certificate. Applications running on newer versions of Windows can
	 * leave off this flag, in which case the InitializeSecurityContext
	 * function will validate the server certificate automatically.
 	 */
	SchannelCred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;

	/*
	 * Create an SSPI credential.
	 */

	Status = AcquireCredentialsHandle(
			NULL,                   /* Name of principal */    
			UNI_SCHANNEL,           /* Name of package */
			SECPKG_CRED_OUTBOUND,   /* Flags indicating use */
			NULL,                   /* Pointer to logon ID */
			&SchannelCred,          /* Package specific data */
			NULL,                   /* Pointer to GetKey() func */
			NULL,                   /* Value to pass to GetKey() */
			phCreds,                /* (out) Cred Handle */
			&tsExpiry);             /* (out) Lifetime (optional) */
	if (Status != SEC_E_OK)
	{
		mylog("**** Error 0x%p returned by AcquireCredentialsHandle\n", Status);
		goto cleanup;
	}

cleanup:

    /*
     * Free the certificate context. Schannel has already made its own copy.
     */

    if(pCertContext)
    {
        CertFreeCertificateContext(pCertContext);
    }


    return Status;
}
Exemplo n.º 22
0
static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT io_open_result)
{
    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
    if (tls_io_instance->tlsio_state != TLSIO_STATE_OPENING_UNDERLYING_IO)
    {
        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
        indicate_error(tls_io_instance);
    }
    else
    {
        SecBuffer init_security_buffers[2];
        ULONG context_attributes;
        SECURITY_STATUS status;
        SCHANNEL_CRED auth_data;

        auth_data.dwVersion = SCHANNEL_CRED_VERSION;
        auth_data.cCreds = 0;
        auth_data.paCred = NULL;
        auth_data.hRootStore = NULL;
        auth_data.cSupportedAlgs = 0;
        auth_data.palgSupportedAlgs = NULL;
        auth_data.grbitEnabledProtocols = 0;
        auth_data.dwMinimumCipherStrength = 0;
        auth_data.dwMaximumCipherStrength = 0;
        auth_data.dwSessionLifespan = 0;
        auth_data.dwFlags = SCH_USE_STRONG_CRYPTO | SCH_CRED_NO_DEFAULT_CREDS;
        auth_data.dwCredFormat = 0;

        status = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL,
            &auth_data, NULL, NULL, &tls_io_instance->credential_handle, NULL);
        if (status != SEC_E_OK)
        {
            tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
            indicate_error(tls_io_instance);
        }
        else
        {
            tls_io_instance->credential_handle_allocated = true;

            init_security_buffers[0].cbBuffer = 0;
            init_security_buffers[0].BufferType = SECBUFFER_TOKEN;
            init_security_buffers[0].pvBuffer = NULL;
            init_security_buffers[1].cbBuffer = 0;
            init_security_buffers[1].BufferType = SECBUFFER_EMPTY;
            init_security_buffers[1].pvBuffer = 0;

            SecBufferDesc security_buffers_desc;
            security_buffers_desc.cBuffers = 2;
            security_buffers_desc.pBuffers = init_security_buffers;
            security_buffers_desc.ulVersion = SECBUFFER_VERSION;

            status = InitializeSecurityContext(&tls_io_instance->credential_handle,
                NULL, (SEC_CHAR*)tls_io_instance->host_name, ISC_REQ_EXTENDED_ERROR | ISC_REQ_STREAM | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, NULL, 0,
                &tls_io_instance->security_context, &security_buffers_desc,
                &context_attributes, NULL);

            if ((status == SEC_I_COMPLETE_NEEDED) || (status == SEC_I_CONTINUE_NEEDED) || (status == SEC_I_COMPLETE_AND_CONTINUE))
            {
                if (xio_send(tls_io_instance->socket_io, init_security_buffers[0].pvBuffer, init_security_buffers[0].cbBuffer, NULL, NULL) != 0)
                {
                    tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
                    indicate_error(tls_io_instance);
                }
                else
                {
                    /* set the needed bytes to 1, to get on the next byte how many we actually need */
                    tls_io_instance->needed_bytes = 1;
                    if (resize_receive_buffer(tls_io_instance, tls_io_instance->needed_bytes + tls_io_instance->received_byte_count) != 0)
                    {
                        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
                        indicate_error(tls_io_instance);
                    }
                    else
                    {
                        tls_io_instance->tlsio_state = TLSIO_STATE_HANDSHAKE_CLIENT_HELLO_SENT;
                    }
                }
            }
        }
    }
}
Exemplo n.º 23
0
NTSTATUS
SrvValidateBlob(
    IN PSESSION Session,
    IN PCONNECTION Connection,
    IN PUNICODE_STRING UserName,
    IN OUT PCHAR Blob,
    IN OUT ULONG *BlobLength
    )

/*++

Routine Description:

    Validates a Kerberos Blob sent from the client

Arguments:

    Session - A pointer to a session block so that this routine can
        insert a user token.

    Connection - A pointer to the connection this user is on.

    UserName - ASCIIZ string corresponding to the user name to validate.

    Blob - The Blob to validate and the place to return the output
    Blob. Note this means that this string space has to be
    long enough to hold the maximum length Blob.

    BlobLength - The length of the aforementioned Blob

Return Value:

    NTSTATUS from the security system.

--*/

{
    NTSTATUS Status;
    ULONG Catts;
    LARGE_INTEGER Expiry;
    PUCHAR AllocateMemory = NULL;
    ULONG AllocateLength = *BlobLength;
    BOOLEAN virtualMemoryAllocated = FALSE;
    SecBufferDesc InputToken;
    SecBuffer InputBuffer;
    SecBufferDesc OutputToken;
    SecBuffer OutputBuffer;
    ULONG oldSessionCount;

    AllocateLength += 16;

    Status = NtAllocateVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                0,
                &AllocateLength,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    if ( !NT_SUCCESS(Status) ) {
        INTERNAL_ERROR( ERROR_LEVEL_UNEXPECTED,
                        "Could not allocate Blob Memory %lC\n",
                        Status,
                        NULL);
        goto get_out;
    }

    virtualMemoryAllocated = TRUE;


    if ( (SrvHaveCreds & HAVEKERBEROS) == 0 ) { // Need to get cred handle first

        UNICODE_STRING Kerb;

        Kerb.Length = Kerb.MaximumLength = 16;
        Kerb.Buffer = (LPWSTR) AllocateMemory;
        RtlCopyMemory( Kerb.Buffer, MICROSOFT_KERBEROS_NAME, 16);

        Status = AcquireCredentialsHandle(
                    NULL,              // Default principal
                    (PSECURITY_STRING) &Kerb,
                    SECPKG_CRED_INBOUND,   // Need to define this
                    NULL,               // No LUID
                    NULL,               // no AuthData
                    NULL,               // no GetKeyFn
                    NULL,               // no GetKeyArg
                    &SrvKerberosLsaHandle,
                    (PTimeStamp)&Expiry
                    );

        if ( !NT_SUCCESS(Status) ) {
            Status = MapSecurityError(Status);
            goto get_out;
        }
        SrvHaveCreds |= HAVEKERBEROS;
    }

    RtlCopyMemory( AllocateMemory, Blob, *BlobLength );
    InputToken.pBuffers = &InputBuffer;
    InputToken.cBuffers = 1;
    InputToken.ulVersion = 0;
    InputBuffer.pvBuffer = AllocateMemory;
    InputBuffer.cbBuffer = *BlobLength;
    InputBuffer.BufferType = SECBUFFER_TOKEN;

    OutputToken.pBuffers = &OutputBuffer;
    OutputToken.cBuffers = 1;
    OutputToken.ulVersion = 0;
    OutputBuffer.pvBuffer = AllocateMemory;
    OutputBuffer.cbBuffer = *BlobLength;
    OutputBuffer.BufferType = SECBUFFER_TOKEN;

    SrvStatistics.SessionLogonAttempts++;

    Status = AcceptSecurityContext(
                &SrvKerberosLsaHandle,
                (PCtxtHandle)NULL,
                &InputToken,
                ASC_REQ_EXTENDED_ERROR,               // fContextReq
                SECURITY_NATIVE_DREP,
                &Session->UserHandle,
                &OutputToken,
                &Catts,
                (PTimeStamp)&Expiry
                );

    Status = MapSecurityError( Status );

    if ( NT_SUCCESS(Status)
              ||
         (Catts & ASC_RET_EXTENDED_ERROR) )
    {
        *BlobLength = OutputBuffer.cbBuffer;
        RtlCopyMemory( Blob, AllocateMemory, *BlobLength );

        //
        // BUGBUG
        // All of the following values need to come from someplace
        // And while we're at it, get the LogonId as well
        //

        if(NT_SUCCESS(Status))
        {

            //
            // Note whether or not this user is an administrator
            //

            Session->IsAdmin = SrvIsAdmin( Session->UserHandle );

            //
            // fiddle with the session structures iff the
            // security context was actually accepted
            //

            Session->HaveHandle = TRUE;
            Session->KickOffTime = Expiry;
            Session->LogOffTime = Expiry;
            Session->GuestLogon = FALSE;   // No guest logon this way
            Session->EncryptedLogon = TRUE;

            //
            // See if the session count is being exceeded.  We'll allow it only
            //   if the new client is an administrator
            //
            oldSessionCount = ExInterlockedAddUlong(
                              &SrvStatistics.CurrentNumberOfSessions,
                              1,
                              &GLOBAL_SPIN_LOCK(Statistics)
                              );

            if ( oldSessionCount >= SrvMaxUsers ) {
                if( oldSessionCount != SrvMaxUsers || !SrvIsAdmin( Session->UserHandle ) ) {

                    ExInterlockedAddUlong(
                        &SrvStatistics.CurrentNumberOfSessions,
                        (ULONG)-1,
                        &GLOBAL_SPIN_LOCK(Statistics)
                        );

                    DeleteSecurityContext( &Session->UserHandle );
                    Session->HaveHandle = FALSE;

                    Status = STATUS_REQUEST_NOT_ACCEPTED;
                    goto get_out;
                }
            }
        }
    }
    else
    {
        *BlobLength = 0;
    }

get_out:

    if (virtualMemoryAllocated) {
        (VOID)NtFreeVirtualMemory(
                NtCurrentProcess(),
                &AllocateMemory,
                &AllocateLength,
                MEM_DECOMMIT
                );
    }

    return Status;

} // SrvValidateBlob
Exemplo n.º 24
0
void SchannelContext::connect() 
{
	ScopedCertContext pCertContext;

	m_state = Connecting;

	// If a user name is specified, then attempt to find a client
	// certificate. Otherwise, just create a NULL credential.
	if (!m_cert_name.empty())
	{
		if (m_my_cert_store == NULL)
		{
			m_my_cert_store = CertOpenSystemStore(0, m_cert_store_name.c_str());
			if (!m_my_cert_store)
			{
/////			printf( "**** Error 0x%x returned by CertOpenSystemStore\n", GetLastError() );
				indicateError();
				return;
			}
		}

		pCertContext = findCertificateInStore( m_my_cert_store, m_cert_name );
		if (pCertContext == NULL)
		{
/////		printf("**** Error 0x%x returned by CertFindCertificateInStore\n", GetLastError());
			indicateError();
			return;
		}
	}

	// We use an empty list for client certificates
	PCCERT_CONTEXT clientCerts[1] = {0};

	SCHANNEL_CRED sc = {0};
	sc.dwVersion = SCHANNEL_CRED_VERSION;

/////SSL3?
	sc.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
	sc.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;

	if (pCertContext)
	{
		sc.cCreds = 1;
		sc.paCred = pCertContext.GetPointer();
		sc.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
	}
	else
	{
		sc.cCreds = 0; // Let Crypto API find the appropriate certificate for us
		sc.paCred = clientCerts;
		sc.dwFlags |= SCH_CRED_USE_DEFAULT_CREDS;
	}

	// Swiften performs the server name check for us
	sc.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;

	SECURITY_STATUS status = AcquireCredentialsHandle(
		NULL,
		UNISP_NAME,
		SECPKG_CRED_OUTBOUND,
		NULL,
		&sc,
		NULL,
		NULL,
		m_credHandle.Reset(),
		NULL);
	
	if (status != SEC_E_OK) 
	{
		// We failed to obtain the credentials handle
		indicateError();
		return;
	}

	SecBuffer outBuffers[2];

	// We let Schannel allocate the output buffer for us
	outBuffers[0].pvBuffer   = NULL;
	outBuffers[0].cbBuffer   = 0;
	outBuffers[0].BufferType = SECBUFFER_TOKEN;

	// Contains alert data if an alert is generated
	outBuffers[1].pvBuffer   = NULL;
	outBuffers[1].cbBuffer   = 0;
	outBuffers[1].BufferType = SECBUFFER_ALERT;

	// Make sure the output buffers are freed
	ScopedSecBuffer scopedOutputData(&outBuffers[0]);
	ScopedSecBuffer scopedOutputAlertData(&outBuffers[1]);

	SecBufferDesc outBufferDesc = {0};
	outBufferDesc.cBuffers   = 2;
	outBufferDesc.pBuffers   = outBuffers;
	outBufferDesc.ulVersion  = SECBUFFER_VERSION;

	// Create the initial security context
	status = InitializeSecurityContext(
		m_credHandle,
		NULL,
		NULL,
		m_ctxtFlags,
		0,
		0,
		NULL,
		0,
		m_ctxtHandle.Reset(),
		&outBufferDesc,
		&m_secContext,
		NULL);

	if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) 
	{
		// We failed to initialize the security context
		handleCertError(status);
		indicateError();
		return;
	}

	// Start the handshake
	sendDataOnNetwork(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer);

	if (status == SEC_E_OK) 
	{
		status = validateServerCertificate();
		if (status != SEC_E_OK)
			handleCertError(status);

		m_state = Connected;
		determineStreamSizes();

		onConnected();
	}
}
Exemplo n.º 25
0
BOOL ServerAuthenticate(const char *hostname)
{
	int rc, rcISC, rcl;
	BOOL haveToken;
	int bytesReceived = 0, bytesSent = 0;
	TimeStamp useBefore;
	// input and output buffers
	SecBufferDesc obd, ibd;
	SecBuffer ob, ib[2];
	BOOL haveContext = FALSE;
	DWORD ctxReq,ctxAttr;
	int n;
	short len;
	SCHANNEL_CRED cred = {0};
	char host[256];
	struct addrinfo *ai=NULL, hints = {0};
	PCCERT_CONTEXT cert;

	HANDLE hMy = CertOpenSystemStore(0,"MY");
	if(!hMy)
	{
		rcISC = SEC_E_NO_CREDENTIALS;
		server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC));
		return FALSE;
	}

	if(!hostname)
	{
		gethostname (host, sizeof host);
		hints.ai_flags=AI_CANONNAME;
		if(getaddrinfo(cvs::idn(host),NULL,&hints,&ai))
			server_error (1, "can't get canonical hostname");
		hostname = ai->ai_canonname;
		cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t*)cvs::wide(cvs::decode_idn(hostname)),	NULL);
	}
	else
		cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t*)cvs::wide(hostname),	NULL);

	if(!cert)
	{
		rcISC = SEC_E_NO_CREDENTIALS;
		server_error(1,"No certificate for '%s': %s\n",hostname,GetErrorString(rcISC));
		return FALSE;
	}

	cred.cCreds     = 1;
	cred.paCred     = &cert;

	if(ai)
		freeaddrinfo(ai);

	cred.dwVersion = SCHANNEL_CRED_VERSION;
	cred.dwFlags = SCH_CRED_USE_DEFAULT_CREDS;

	rc = AcquireCredentialsHandle( NULL, "SChannel", SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credHandle, &useBefore );
	if ( rc == SEC_E_OK )
		haveToken = TRUE;
	else
		haveToken = FALSE;

	CertCloseStore(hMy,0);

	while ( 1 )
	{
		// prepare to get the server's response
		ibd.ulVersion = SECBUFFER_VERSION;
		ibd.cBuffers = 2;
		ibd.pBuffers = ib; // just one buffer
		ib[0].BufferType = SECBUFFER_TOKEN; // preping a token here
		ib[0].cbBuffer = secPackInfo->cbMaxToken;
		ib[0].pvBuffer = malloc(ib[0].cbBuffer);
		ib[1].cbBuffer = 0;
		ib[1].pvBuffer = NULL;
		ib[1].BufferType = SECBUFFER_EMPTY; // Spare stuff

		// receive the client's POD

		rcl = read( current_server()->in_fd, ib[0].pvBuffer, ib[0].cbBuffer);
		if(rcl<=0)
		{
			rc = SEC_E_INTERNAL_ERROR;
			break;
		}

		// by now we have an input buffer

		obd.ulVersion = SECBUFFER_VERSION;
		obd.cBuffers = 1;
		obd.pBuffers = &ob; // just one buffer
		ob.BufferType = SECBUFFER_TOKEN; // preping a token here
		ob.cbBuffer = secPackInfo->cbMaxToken;
		ob.pvBuffer = malloc(secPackInfo->cbMaxToken);

		if(rc<0)
		{
			len=0;
			if((n=write(current_server()->out_fd,&len,sizeof(len)))<=0)
				break;
			break;
		}

		ctxReq = ASC_REQ_INTEGRITY | ASC_REQ_CONFIDENTIALITY | ASC_REQ_REPLAY_DETECT | ASC_REQ_SEQUENCE_DETECT | ASC_REQ_STREAM;

		rc = AcceptSecurityContext( &credHandle, haveContext? &contextHandle: NULL,
				&ibd, ctxReq, SECURITY_NATIVE_DREP, &contextHandle, &obd, &ctxAttr,
				&useBefore );

		if ( ib[0].pvBuffer != NULL )
		{
			free( ib[0].pvBuffer );
			ib[0].pvBuffer = NULL;
		}

		if ( rc == SEC_I_COMPLETE_AND_CONTINUE || rc == SEC_I_COMPLETE_NEEDED )
		{
			CompleteAuthToken( &contextHandle, &obd );
			if ( rc == SEC_I_COMPLETE_NEEDED )
				rc = SEC_E_OK;
			else if ( rc == SEC_I_COMPLETE_AND_CONTINUE )
				rc = SEC_I_CONTINUE_NEEDED;
		}

		// send the output buffer off to the server
		// warning -- this is machine-dependent! FIX IT!
		if ( rc == SEC_E_OK || rc == SEC_I_CONTINUE_NEEDED )
		{
			if ( ob.cbBuffer != 0 )
			{
				if((n=write(current_server()->out_fd,ob.pvBuffer, ob.cbBuffer))<=0)
					break;
				bytesSent += n;
			}
			free(ob.pvBuffer);
			ob.pvBuffer = NULL;
			ob.cbBuffer = 0;
		}
		else
		{
			break;
		}

		if ( rc != SEC_I_CONTINUE_NEEDED )
			break;

		haveContext = TRUE;
	}

	// we arrive here as soon as InitializeSecurityContext()
	// returns != SEC_I_CONTINUE_NEEDED.

	if ( rc != SEC_E_OK )
	{
		haveToken = FALSE;
	}

	if(rc<0)
		server_error(0,"[%08x] %s\n",rc, GetErrorString(rc));

	return haveToken?TRUE:FALSE;
}
Exemplo n.º 26
0
static SSLSTREAM *ssl_start (TCPSTREAM *tstream,char *host,unsigned long flags)
{
  SECURITY_STATUS e;
  ULONG a;
  TimeStamp t;
  SecBuffer ibuf[2],obuf[1];
  SecBufferDesc ibufs,obufs;
  SCHANNEL_CRED tlscred;
  CERT_CONTEXT *cert;
  CERT_CHAIN_PARA chparam;
  CERT_CHAIN_CONTEXT *chain;
  SSL_EXTRA_CERT_CHAIN_POLICY_PARA policy;
  CERT_CHAIN_POLICY_PARA polparam;
  CERT_CHAIN_POLICY_STATUS status;
  char tmp[MAILTMPLEN],certname[256];
  char *reason = NIL;
  ULONG req = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT |
    ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY |
      ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR |
	ISC_REQ_MANUAL_CRED_VALIDATION;
  LPSTR usage[] = {
    szOID_PKIX_KP_SERVER_AUTH,
    szOID_SERVER_GATED_CRYPTO,
    szOID_SGC_NETSCAPE
  };
  PWSTR whost = NIL;
  char *buf = (char *) fs_get (ssltsz);
  unsigned long size = 0;
  sslcertificatequery_t scq =
    (sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL);
  sslfailure_t sf = (sslfailure_t) mail_parameters (NIL,GET_SSLFAILURE,NIL);
  SSLSTREAM *stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0,
					    sizeof (SSLSTREAM));
  stream->tcpstream = tstream;	/* bind TCP stream */
				/* initialize TLS credential */
  memset (&tlscred,0,sizeof (SCHANNEL_CRED));
  tlscred.dwVersion = SCHANNEL_CRED_VERSION;
  tlscred.grbitEnabledProtocols = SP_PROT_TLS1;

				/* acquire credentials */
  if (AcquireCredentialsHandle
      (NIL,UNISP_NAME,SECPKG_CRED_OUTBOUND,NIL,(flags & NET_TLSCLIENT) ?
       &tlscred : NIL,NIL,NIL,&stream->cred,&t)
      != SEC_E_OK) reason = "Acquire credentials handle failed";
  else while (!reason) {	/* negotiate security context */
				/* initialize buffers */
    ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = buf;
    ibuf[1].cbBuffer = 0; ibuf[1].pvBuffer = NIL;
    obuf[0].cbBuffer = 0; obuf[0].pvBuffer = NIL;
    ibuf[0].BufferType = obuf[0].BufferType = SECBUFFER_TOKEN;
    ibuf[1].BufferType = SECBUFFER_EMPTY;
				/* initialize buffer descriptors */
    ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION;
    ibufs.cBuffers = 2; obufs.cBuffers = 1;
    ibufs.pBuffers = ibuf; obufs.pBuffers = obuf;
				/* negotiate security */
    e = InitializeSecurityContext
      (&stream->cred,size ? &stream->context : NIL,host,req,0,
       SECURITY_NETWORK_DREP,size? &ibufs:NIL,0,&stream->context,&obufs,&a,&t);
				/* have an output buffer we need to send? */
    if (obuf[0].pvBuffer && obuf[0].cbBuffer) {
      if (!tcp_sout (stream->tcpstream,obuf[0].pvBuffer,obuf[0].cbBuffer))
	reason = "Unexpected TCP output disconnect";
				/* free the buffer */
      FreeContextBuffer (obuf[0].pvBuffer);
    }
    if (!reason) switch (e) {	/* negotiation state */
    case SEC_I_INCOMPLETE_CREDENTIALS:
      break;			/* server wants client auth */
    case SEC_I_CONTINUE_NEEDED:
      if (size) {		/* continue, read any data? */
				/* yes, anything regurgiated back to us? */
	if (ibuf[1].BufferType == SECBUFFER_EXTRA) {
				/* yes, set this as the new data */
	  memmove (buf,buf + size - ibuf[1].cbBuffer,ibuf[1].cbBuffer);
	  size = ibuf[1].cbBuffer;
	  break;
	}
	size = 0;		/* otherwise, read more stuff from server */
      }
    case SEC_E_INCOMPLETE_MESSAGE:
				/* need to read more data from server */
      if (!tcp_getdata (stream->tcpstream))
	reason = "Unexpected TCP input disconnect";
      else {
	memcpy (buf+size,stream->tcpstream->iptr,stream->tcpstream->ictr);
	size += stream->tcpstream->ictr;
				/* empty it from TCP's buffers */
	stream->tcpstream->iptr += stream->tcpstream->ictr;
	stream->tcpstream->ictr = 0;
      }
      break;

    case SEC_E_OK:		/* success, any data to be regurgitated? */
      if (ibuf[1].BufferType == SECBUFFER_EXTRA) {
				/* yes, set this as the new data */
	memmove (stream->tcpstream->iptr = stream->tcpstream->ibuf,
		 buf + size - ibuf[1].cbBuffer,ibuf[1].cbBuffer);
	stream->tcpstream->ictr = ibuf[1].cbBuffer;
      }
      if (!(flags & NET_NOVALIDATECERT)) {
				/* need validation, make wchar of host */
	if (!((size = MultiByteToWideChar (CP_ACP,0,host,-1,NIL,0)) &&
	      (whost = (PWSTR) fs_get (size*sizeof (WCHAR))) &&
	      MultiByteToWideChar (CP_ACP,0,host,-1,whost,size)))
	  fatal ("Can't make wchar of host name!");
				/* get certificate */
	if ((QueryContextAttributes
	     (&stream->context,SECPKG_ATTR_REMOTE_CERT_CONTEXT,&cert) !=
	     SEC_E_OK) || !cert) {
	  reason = "*Unable to get certificate";
	  strcpy (certname,"<no certificate>");
	}
	else {			/* get certificate subject name */
	  CertNameToStr (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
			 &cert->pCertInfo->Subject,CERT_X500_NAME_STR,
			 certname,255);
				/* build certificate chain */
	  memset (&chparam,0,sizeof (chparam));
	  chparam.cbSize = sizeof (chparam);
	  chparam.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
	  chparam.RequestedUsage.Usage.rgpszUsageIdentifier = usage;
	  chparam.RequestedUsage.Usage.cUsageIdentifier =
	    sizeof (usage) / sizeof (LPSTR);
	  if (!CertGetCertificateChain
	      (NIL,cert,NIL,cert->hCertStore,&chparam,NIL,NIL,&chain))
	    reason = ssl_analyze_status (GetLastError (),tmp);
	  else {		/* validate certificate chain */
	    memset (&policy,0,sizeof (SSL_EXTRA_CERT_CHAIN_POLICY_PARA));
	    policy.cbStruct = sizeof (SSL_EXTRA_CERT_CHAIN_POLICY_PARA);
	    policy.dwAuthType = AUTHTYPE_SERVER;
	    policy.fdwChecks = NIL;
	    policy.pwszServerName = whost;
	    memset (&polparam,0,sizeof (polparam));
	    polparam.cbSize = sizeof (polparam);
	    polparam.pvExtraPolicyPara = &policy;
	    memset (&status,0,sizeof (status));
	    status.cbSize = sizeof (status);
	    if (!CertVerifyCertificateChainPolicy
		(CERT_CHAIN_POLICY_SSL,chain,&polparam,&status))
	      reason = ssl_analyze_status (GetLastError (),tmp);
	    else if (status.dwError)
	      reason = ssl_analyze_status (status.dwError,tmp);
	    CertFreeCertificateChain (chain);
	  }
	}
	if (whost) fs_give ((void **) &whost);

	if (reason) {		/* got an error? */
				/* application callback */
	  if (scq) reason = (*scq) ((*reason == '*') ? reason + 1 : reason,
				    host,certname) ? NIL : "";
	  else if (*certname) {	/* error message to return via mm_log() */
	    sprintf (buf,"*%.128s: %.255s",
		     (*reason == '*') ? reason + 1 : reason,certname);
	    reason = buf;
	  }
	}
      }
      if (reason ||
	  (reason = ssl_analyze_status
	   (QueryContextAttributes
	    (&stream->context,SECPKG_ATTR_STREAM_SIZES,&stream->sizes),buf)))
	break;			/* error in certificate or getting sizes */
      fs_give ((void **) &buf);	/* flush temporary buffer */
				/* make maximum-sized buffers */
      stream->bufsize = stream->sizes.cbHeader +
	stream->sizes.cbMaximumMessage + stream->sizes.cbTrailer;
      if (stream->sizes.cbMaximumMessage < SSLBUFLEN)
	fatal ("cbMaximumMessage is less than SSLBUFLEN!");
      else if (stream->sizes.cbMaximumMessage < 16384) {
	sprintf (tmp,"WINDOWS BUG: cbMaximumMessage = %ld, should be 16384",
		 (long) stream->sizes.cbMaximumMessage);
	mm_log (tmp,NIL);
      }
      stream->ibuf = (char *) fs_get (stream->bufsize);
      stream->obuf = (char *) fs_get (stream->bufsize);
      return stream;
    default:
      reason = ssl_analyze_status (e,buf);
    }
  }
  ssl_close (stream);		/* failed to do SSL */
  stream = NIL;			/* no stream returned */
  switch (*reason) {		/* analyze reason */
  case '*':			/* certificate failure */
    ++reason;			/* skip over certificate failure indication */
				/* pass to error callback */
    if (sf) (*sf) (host,reason,flags);
    else {			/* no error callback, build error message */
      sprintf (tmp,"Certificate failure for %.80s: %.512s",host,reason);
      mm_log (tmp,ERROR);
    }
  case '\0':			/* user answered no to certificate callback */
    if (flags & NET_TRYSSL)	/* return dummy stream to stop tryssl */
      stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0,
				     sizeof (SSLSTREAM));
    break;
  default:			/* non-certificate failure */
    if (flags & NET_TRYSSL);	/* no error output if tryssl */
				/* pass to error callback */
    else if (sf) (*sf) (host,reason,flags);
    else {			/* no error callback, build error message */
      sprintf (tmp,"TLS/SSL failure for %.80s: %.512s",host,reason);
      mm_log (tmp,ERROR);
    }
    break;
  }
  fs_give ((void **) &buf);	/* flush temporary buffer */
  return stream;
}
Exemplo n.º 27
0
static sqInt sqSetupCert(sqSSL *ssl, char *certName, int server) {
	SCHANNEL_CRED sc_cred = { 0 };
	SECURITY_STATUS ret;
	HCERTSTORE hStore;
	PCCERT_CONTEXT pContext = NULL;
	DWORD dwPropSize;
	WCHAR wFriendlyName[MAX_NAME_SIZE];
	char  bFriendlyName[MAX_NAME_SIZE];

	if(certName) {
		hStore = CertOpenSystemStore(0, "MY");
		if(!hStore) {
			if(ssl->loglevel) printf("sqSetupCert: CertOpenSystemStore failed\n");
			return 0;
		}
		pContext = NULL;

		/* Enumerate the certificate store to find the cert with the given friendly name */
		while(pContext = CertEnumCertificatesInStore(hStore, pContext)) {
			if(ssl->loglevel) printf("Checking certificate: ");
			dwPropSize = MAX_NAME_SIZE * sizeof(WCHAR);
			if(!CertGetCertificateContextProperty(pContext, CERT_FRIENDLY_NAME_PROP_ID, wFriendlyName, &dwPropSize)) {
				if(ssl->loglevel) printf("<no friendly name>");
				continue;
			}
			if(!WideCharToMultiByte(CP_UTF8, 0, wFriendlyName, -1, bFriendlyName, MAX_NAME_SIZE, NULL, NULL)) {
				if(ssl->loglevel) printf("<utf-8 conversion failure>");
				continue;
			}
			if(ssl->loglevel) printf("%s\n", bFriendlyName);
			if(strcmp(certName, bFriendlyName) == 0) break;
		}

		if(pContext == 0) {
			/* For compatibility with older versions of SqueakSSL, attempt to match against subject string */
			pContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
												  0, CERT_FIND_SUBJECT_STR_A, certName, NULL);
		}

		if(!pContext) {
			if(ssl->loglevel) printf("sqSetupCert: No suitable certificate  found\n");
			CertCloseStore(hStore, 0);
			return 0;
		}
	}

	sc_cred.dwVersion = SCHANNEL_CRED_VERSION;
	sc_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
	sc_cred.grbitEnabledProtocols = server ? SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER : 0;
	sc_cred.dwMinimumCipherStrength = 0;
	sc_cred.dwMaximumCipherStrength = 0;

	if(pContext) {
		sc_cred.cCreds = 1;
		sc_cred.paCred = &pContext;
	} else {
		sc_cred.cCreds = 0;
	}

	ret = AcquireCredentialsHandle(NULL, UNISP_NAME, 
									server ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, 
									NULL, &sc_cred, NULL, NULL, &ssl->sslCred, NULL);
	if(ssl->loglevel) printf("AquireCredentialsHandle returned: %x\n", ret);

	if(pContext) {
		CertCloseStore(hStore, 0);
	    CertFreeCertificateContext(pContext);
	}

	if (ret != SEC_E_OK) {
		if(ssl->loglevel) printf("AquireCredentialsHandle error: %x\n", ret);
		return 0;
	}
	return 1;
}
Exemplo n.º 28
0
/*
 * Send initial SSPI authentication token.
 * If use_negotiate is 0, use kerberos authentication package which is
 * compatible with Unix. If use_negotiate is 1, use the negotiate package
 * which supports both kerberos and NTLM, but is not compatible with Unix.
 */
static int
pg_SSPI_startup(PGconn *conn, int use_negotiate)
{
	SECURITY_STATUS r;
	TimeStamp	expire;

	conn->sspictx = NULL;

	/*
	 * Retreive credentials handle
	 */
	conn->sspicred = malloc(sizeof(CredHandle));
	if (conn->sspicred == NULL)
	{
		printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
		return STATUS_ERROR;
	}

	r = AcquireCredentialsHandle(NULL,
								 use_negotiate ? "negotiate" : "kerberos",
								 SECPKG_CRED_OUTBOUND,
								 NULL,
								 NULL,
								 NULL,
								 NULL,
								 conn->sspicred,
								 &expire);
	if (r != SEC_E_OK)
	{
		pg_SSPI_error(conn, libpq_gettext("could not acquire SSPI credentials"), r);
		free(conn->sspicred);
		conn->sspicred = NULL;
		return STATUS_ERROR;
	}

	/*
	 * Compute target principal name. SSPI has a different format from GSSAPI,
	 * but not more complex. We can skip the @REALM part, because Windows will
	 * fill that in for us automatically.
	 */
	if (!(conn->pghost && conn->pghost[0] != '\0'))
	{
		printfPQExpBuffer(&conn->errorMessage,
						  libpq_gettext("host name must be specified\n"));
		return STATUS_ERROR;
	}
	conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
	if (!conn->sspitarget)
	{
		printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
		return STATUS_ERROR;
	}
	sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);

	/*
	 * Indicate that we're in SSPI authentication mode to make sure that
	 * pg_SSPI_continue is called next time in the negotiation.
	 */
	conn->usesspi = 1;

	return pg_SSPI_continue(conn);
}
Exemplo n.º 29
0
static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT io_open_result)
{
    TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;

    if (tls_io_instance->tlsio_state != TLS_SERVER_IO_STATE_OPENING_UNDERLYING_IO)
    {
        tls_io_instance->tlsio_state = TLS_SERVER_IO_STATE_ERROR;
        indicate_error(tls_io_instance);
    }
    else
    {
        if (io_open_result != IO_OPEN_OK)
        {
            tls_io_instance->tlsio_state = TLS_SERVER_IO_STATE_NOT_OPEN;
            if (tls_io_instance->on_io_open_complete != NULL)
            {
                tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, IO_OPEN_ERROR);
            }
        }
        else
        {
            SECURITY_STATUS status;
            SCHANNEL_CRED auth_data;
            PCCERT_CONTEXT certContext;
            auth_data.dwVersion = SCHANNEL_CRED_VERSION;
            if (tls_io_instance->x509_schannel_handle != NULL)
            {
                certContext = x509_schannel_get_certificate_context(tls_io_instance->x509_schannel_handle);
                auth_data.cCreds = 1;
                auth_data.paCred = &certContext;
            }
            else
            {

                certContext = tls_io_instance->cert_context;
                auth_data.cCreds = 1;
                auth_data.paCred = &certContext;

            }

            auth_data.hRootStore = NULL;
            auth_data.cSupportedAlgs = 0;
            auth_data.palgSupportedAlgs = NULL;
#if defined(SP_PROT_TLS1_2_SERVER)
            auth_data.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER;
#else
            auth_data.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
#endif
            auth_data.dwMinimumCipherStrength = 0;
            auth_data.dwMaximumCipherStrength = 0;
            auth_data.dwSessionLifespan = 0;
            auth_data.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER;
            auth_data.dwCredFormat = 0;

            status = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_INBOUND, NULL,
                &auth_data, NULL, NULL, &tls_io_instance->credential_handle, NULL);
            if (status != SEC_E_OK)
            {
                tls_io_instance->tlsio_state = TLS_SERVER_IO_STATE_ERROR;
                indicate_error(tls_io_instance);
            }
            else
            {
                tls_io_instance->credential_handle_allocated = true;
                tls_io_instance->needed_bytes = 1;
                tls_io_instance->tlsio_state = TLS_SERVER_IO_STATE_WAITING_FOR_CLIENT_HELLO;
            }
        }
    }
}