360 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***********************************************************************
 | |
|  * 
 | |
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 | |
|  *
 | |
|  *  This library is free software; you can redistribute it and/or
 | |
|  *  modify it under the terms of the GNU Lesser General Public
 | |
|  *  License as published by the Free Software Foundation; version 2.1
 | |
|  *  of the License.
 | |
|  *
 | |
|  *  This library is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  *  Library Lesser General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU Lesser General Public
 | |
|  *  License along with this library; if not, Novell, Inc.
 | |
|  * 
 | |
|  *  To contact Novell about this file by physical or electronic mail, 
 | |
|  *  you may find current contact information at www.novell.com.
 | |
|  * 
 | |
|  *  Author: Juan Carlos Luciani <jluciani@novell.com>
 | |
|  *
 | |
|  ***********************************************************************/
 | |
| 
 | |
| 
 | |
| //===[ Include files ]=====================================================
 | |
| 
 | |
| #include "internal.h"
 | |
| 
 | |
| //===[ Type definitions ]==================================================
 | |
| 
 | |
| //===[ Function prototypes ]===============================================
 | |
| 
 | |
| //===[ Global variables ]==================================================
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| static
 | |
| CasaStatus
 | |
| GetUserCredentials(
 | |
|    IN       const char *pRealm,
 | |
|    INOUT    char **ppUsername,
 | |
|    INOUT    char **ppPassword)
 | |
| //
 | |
| // Arguments:  
 | |
| //    pRealm -
 | |
| //       The realm to which the credentials apply.
 | |
| //   
 | |
| //    ppUsername -
 | |
| //       Pointer to variable that will receive buffer with the username.
 | |
| //               
 | |
| //    ppPassword -
 | |
| //       Pointer to variable that will receive buffer with the password.
 | |
| //   
 | |
| // Returns:
 | |
| //    Casa Status
 | |
| //                           
 | |
| // Description:
 | |
| //    Get authentication credentials for the specified realm.
 | |
| //
 | |
| // L2
 | |
| //=======================================================================--
 | |
| {
 | |
|    CasaStatus              retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                                        CASA_FACILITY_PWTOKEN,
 | |
|                                                        CASA_STATUS_UNSUCCESSFUL);
 | |
|    char                    *pUsername;
 | |
|    char                    *pPassword;
 | |
|    int                     rcode = NSSCS_E_OBJECT_NOT_FOUND;
 | |
|    int32_t                 credtype = SSCS_CRED_TYPE_BASIC_F;
 | |
|    SSCS_BASIC_CREDENTIAL   credential = {0};
 | |
|    SSCS_SECRET_ID_T        secretId = {0};
 | |
|    SSCS_SECRET_ID_T        sharedSecretId = {0};
 | |
|    
 | |
|    
 | |
|    DbgTrace(1, "-GetUserCredentials- Start\n", 0);
 | |
| 
 | |
|    // Initialize output parameters
 | |
|    *ppUsername = NULL;
 | |
|    *ppPassword = NULL;
 | |
| 
 | |
|    // Get the length of the realm string into the secret id structure
 | |
|    // and verify thatr it is not too long.
 | |
|    secretId.len = sscs_Utf8Strlen(pRealm) + 1;
 | |
|    if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
 | |
|    {
 | |
|       // Set the secret id in the structure
 | |
|       sscs_Utf8Strcpy(secretId.id, pRealm);
 | |
| 
 | |
|       // Specify that we want the common name
 | |
|       credential.unFlags = USERNAME_TYPE_CN_F;
 | |
| 
 | |
|       // Now try to get the credentials
 | |
|       rcode = miCASAGetCredential(0,
 | |
|                                   &secretId,
 | |
|                                   NULL,
 | |
|                                   &credtype,
 | |
|                                   &credential,
 | |
|                                   NULL);
 | |
|       if (rcode != NSSCS_SUCCESS)
 | |
|       {
 | |
|          // There were no credentials for the realm, now try to obtain the
 | |
|          // desktop credentials.
 | |
|          secretId.len = sscs_Utf8Strlen("Desktop") + 1;
 | |
|          sscs_Utf8Strcpy(secretId.id, "Desktop");
 | |
|          rcode = miCASAGetCredential(0,
 | |
|                                      &secretId,
 | |
|                                      NULL,
 | |
|                                      &credtype,
 | |
|                                      &credential,
 | |
|                                      NULL);
 | |
|       }
 | |
|    }
 | |
|    else
 | |
|    {
 | |
|       DbgTrace(0, "-GetUserCredentials- Realm name too long\n", 0);
 | |
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                   CASA_FACILITY_PWTOKEN,
 | |
|                                   CASA_STATUS_UNSUCCESSFUL);
 | |
|    }
 | |
| 
 | |
|    // Proceed based on the result of the operatiosn above
 | |
|    if (rcode == NSSCS_SUCCESS
 | |
|        && credential.username != NULL
 | |
|        && credential.password != NULL)
 | |
|    {
 | |
|       // Allocate a buffer to return the username
 | |
|       pUsername = (char*) malloc(strlen(credential.username) + 1);
 | |
|       if (pUsername)
 | |
|       {
 | |
|          // Copy the username into the buffer that we will be returning
 | |
|          strcpy(pUsername, credential.username);
 | |
| 
 | |
|          // Allocate a buffer to return the password
 | |
|          pPassword = (char*) malloc(strlen(credential.password) + 1);
 | |
|          if (pPassword)
 | |
|          {
 | |
|             // Copy the password into the buffer that we will be returning
 | |
|             strcpy(pPassword, credential.password);
 | |
| 
 | |
|             // Success
 | |
|             retStatus = CASA_STATUS_SUCCESS;
 | |
|          }
 | |
|          else
 | |
|          {
 | |
|             DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
 | |
|             retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                         CASA_FACILITY_PWTOKEN,
 | |
|                                         CASA_STATUS_INSUFFICIENT_RESOURCES);
 | |
| 
 | |
|             // Free the buffer allocated for the username
 | |
|             free(pUsername);
 | |
|          }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|          DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0);
 | |
|          retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                      CASA_FACILITY_PWTOKEN,
 | |
|                                      CASA_STATUS_INSUFFICIENT_RESOURCES);
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    // Return the buffers to the caller if successful
 | |
|    if (CASA_SUCCESS(retStatus))
 | |
|    {
 | |
|       *ppUsername = pUsername;
 | |
|       *ppPassword = pPassword;
 | |
|    }
 | |
| 
 | |
|    DbgTrace(1, "-GetUserCredentials- End, retStatus = %08X\n", retStatus);
 | |
| 
 | |
|    return retStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| CasaStatus SSCS_CALL
 | |
| AuthTokenIf_GetAuthToken(
 | |
|    IN       const void  *pIfInstance,
 | |
|    IN       const char  *pContext,
 | |
|    IN       const char  *pMechInfo,
 | |
|    INOUT    char        *pTokenBuf,
 | |
|    INOUT    int         *pTokenBufLen)
 | |
| //
 | |
| // Arguments:  
 | |
| //    pIfInstance -
 | |
| //       Pointer to interface object.
 | |
| //   
 | |
| //    pServiceConfigIf -
 | |
| //       Pointer to service config object to which the client is trying to
 | |
| //       authenticate.
 | |
| //               
 | |
| //    pContext -
 | |
| //       Pointer to null terminated string containing mechanism specific
 | |
| //       context information. Another name for context is Authentication
 | |
| //       Realm.
 | |
| //
 | |
| //    pMechInfo -
 | |
| //       Pointer to null terminated string containing mechanism specific
 | |
| //       information. This is information is provided by the server to
 | |
| //       aid the mechanism to generate an authentication token. For
 | |
| //       example, the mechanism information for a Kerberos mechanism
 | |
| //       may be the service principal name to which the user will be
 | |
| //       authenticating.
 | |
| //               
 | |
| //    pTokenBuf -
 | |
| //       Pointer to buffer that will receive the authentication
 | |
| //       token. The length of this buffer is specified by the
 | |
| //       pTokenBufLen parameter. Note that the the authentication
 | |
| //       token will be in the form of a NULL terminated string.
 | |
| //
 | |
| //    pTokenBufLen -
 | |
| //       Pointer to integer that contains the length of the
 | |
| //       buffer pointed at by pTokenBuf. Upon return of the
 | |
| //       function, the integer will contain the actual length
 | |
| //       of the authentication token if the function successfully
 | |
| //       completes or the buffer length required if the function
 | |
| //       fails because the buffer pointed at by pUserNameBuf is
 | |
| //       not large enough.
 | |
| //   
 | |
| // Returns:
 | |
| //    Casa Status
 | |
| //                           
 | |
| // Description:
 | |
| //    Get authentication token to authenticate user to specified service.
 | |
| //
 | |
| // L2
 | |
| //=======================================================================--
 | |
| {
 | |
|    CasaStatus  retStatus;
 | |
|    char        *pUsername = NULL;
 | |
|    char        *pPassword = NULL;
 | |
|    char        *pToken;
 | |
| 
 | |
|    DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0);
 | |
| 
 | |
|    // Validate input parameters
 | |
|    if (pIfInstance == NULL
 | |
|        || pContext == NULL
 | |
|        || pMechInfo == NULL
 | |
|        || pTokenBufLen == NULL
 | |
|        || (pTokenBuf == NULL && *pTokenBufLen != 0))
 | |
|    {
 | |
|       DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0);
 | |
| 
 | |
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                   CASA_FACILITY_PWTOKEN,
 | |
|                                   CASA_STATUS_INVALID_PARAMETER);
 | |
|       goto exit;
 | |
|    }
 | |
| 
 | |
|    // Get the user credentials
 | |
|    retStatus = GetUserCredentials(pContext, &pUsername, &pPassword);
 | |
|    if (CASA_SUCCESS(retStatus))
 | |
|    {
 | |
|       // Now construct the PW token with the following format:
 | |
|       // "username\r\n" + "password\r\n"
 | |
|       //
 | |
|       // First allocate a buffer large enough to hold the token
 | |
|       pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
 | |
|       if (pToken)
 | |
|       {
 | |
|          char  *pEncodedToken;
 | |
|          int   encodedTokenLen;
 | |
| 
 | |
|          // Now assemble the token
 | |
|          sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
 | |
| 
 | |
|          // The token has been assembled, now encode it.
 | |
|          retStatus = EncodeData(pToken,
 | |
|                                 (const int) strlen(pToken),
 | |
|                                 &pEncodedToken,
 | |
|                                 &encodedTokenLen);
 | |
|          if (CASA_SUCCESS(retStatus))
 | |
|          {
 | |
|             // Verify that the caller provided a buffer that is big enough
 | |
|             if (encodedTokenLen > *pTokenBufLen)
 | |
|             {
 | |
|                // The buffer is not big enough
 | |
|                retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                            CASA_FACILITY_PWTOKEN,
 | |
|                                            CASA_STATUS_BUFFER_OVERFLOW);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                // The buffer provided is large enough, copy the data.
 | |
|                memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
 | |
| 
 | |
|                // Success
 | |
|                retStatus = CASA_STATUS_SUCCESS;
 | |
|             }
 | |
| 
 | |
|             // Return the actual size or the size required
 | |
|             *pTokenBufLen = encodedTokenLen;
 | |
| 
 | |
|             // Free the buffer containing the encoded token
 | |
|             free(pEncodedToken);
 | |
|          }
 | |
| 
 | |
|          // Free the buffer allocated for the token
 | |
|          free(pToken);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|          DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
 | |
|          retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                      CASA_FACILITY_PWTOKEN,
 | |
|                                      CASA_STATUS_INSUFFICIENT_RESOURCES);
 | |
|       }
 | |
| 
 | |
|       // Free allocated buffers
 | |
|       free(pUsername);
 | |
|       free(pPassword);
 | |
|    }
 | |
|    else
 | |
|    {
 | |
|       DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the user credentials\n", 0);
 | |
|    }
 | |
| 
 | |
| exit:
 | |
| 
 | |
|    DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus);
 | |
| 
 | |
|    return retStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| int
 | |
| InitializeLibrary(void)
 | |
| //
 | |
| //  Arguments: 
 | |
| //
 | |
| //  Returns:   
 | |
| //
 | |
| //  Abstract:  
 | |
| //
 | |
| //  Notes:
 | |
| //
 | |
| // L2
 | |
| //=======================================================================--
 | |
| {
 | |
|    int   retStatus = 0;
 | |
| 
 | |
|    DbgTrace(1, "-InitializeLibrary- Start\n", 0);
 | |
| 
 | |
|    // Nothing to do at this time.
 | |
| 
 | |
|    DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
 | |
| 
 | |
|    return retStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| //++=======================================================================
 | |
| //++=======================================================================
 | |
| 
 |