Updates resulting from self-code review.
This commit is contained in:
		| @@ -1,362 +1,371 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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, | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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, | ||||
|    IN       void *pCredStoreScope, | ||||
|    INOUT    char **ppUsername, | ||||
|    INOUT    char **ppPassword) | ||||
| // | ||||
| // Arguments:   | ||||
| //    pRealm - | ||||
| //       The realm to which the credentials apply. | ||||
| //    | ||||
| //    pCredStoreScope - | ||||
| //       Pointer to CASA structure for scoping credential store access | ||||
| //       to specific users. This can only be leveraged when running in | ||||
| //       the context of System under Windows. | ||||
| //    | ||||
| //    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; | ||||
|    uint32_t                credtype = SSCS_CRED_TYPE_BASIC_F; | ||||
|    SSCS_BASIC_CREDENTIAL   credential = {0}; | ||||
|    SSCS_SECRET_ID_T        secretId = {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((char*) 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, | ||||
|                                   (SSCS_EXT_T*) pCredStoreScope); | ||||
|       if (rcode != NSSCS_SUCCESS) | ||||
|       { | ||||
|          // There were no credentials for the realm, now try to obtain the | ||||
|          // desktop credentials. | ||||
|          secretId.len = sscs_Utf8Strlen("Desktop") + 1; | ||||
|          if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN) | ||||
|          { | ||||
|             sscs_Utf8Strcpy((char*) secretId.id, "Desktop"); | ||||
|             rcode = miCASAGetCredential(0, | ||||
|                                         &secretId, | ||||
|                                         NULL, | ||||
|                                         &credtype, | ||||
|                                         &credential, | ||||
|                                         (SSCS_EXT_T*) pCredStoreScope); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-GetUserCredentials- Desktop name too long\n", 0); | ||||
|             retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                         CASA_FACILITY_PWTOKEN, | ||||
|                                         CASA_STATUS_UNSUCCESSFUL); | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|    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((char*) credential.username) + 1); | ||||
|       if (pUsername) | ||||
|       { | ||||
|          // Copy the username into the buffer that we will be returning | ||||
|          strcpy(pUsername, (char*) credential.username); | ||||
|  | ||||
|          // Allocate a buffer to return the password | ||||
|          pPassword = (char*) malloc(strlen((char*) credential.password) + 1); | ||||
|          if (pPassword) | ||||
|          { | ||||
|             // Copy the password into the buffer that we will be returning | ||||
|             strcpy(pPassword, (char*) credential.password); | ||||
|  | ||||
|             DbgTrace(1, "-GetUserCredentials- Username = %s\n", pUsername); | ||||
|  | ||||
|             // 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); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-GetUserCredentials- Failed to obtain credentials for pw authentication\n", 0); | ||||
|    } | ||||
|  | ||||
|    // Return the buffers to the caller if successful | ||||
|    if (CASA_SUCCESS(retStatus)) | ||||
|    { | ||||
|       *ppUsername = pUsername; | ||||
|       *ppPassword = pPassword; | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-GetUserCredentials- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus SSCS_CALL | ||||
| AuthTokenIf_GetAuthToken( | ||||
|    IN       const void  *pIfInstance, | ||||
|    IN       const char  *pContext, | ||||
|    IN       const char  *pMechInfo, | ||||
|    IN       const char  *pHostName, | ||||
|    INOUT    char **ppUsername, | ||||
|    INOUT    char **ppPassword) | ||||
| // | ||||
| // Arguments:   | ||||
| //    pRealm - | ||||
| //       The realm to which the credentials apply. | ||||
| //    | ||||
| //    pCredStoreScope - | ||||
| //       Pointer to CASA structure for scoping credential store access | ||||
| //       to specific users. This can only be leveraged when running in | ||||
| //       the context of System under Windows. | ||||
| //    | ||||
| //    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; | ||||
|    uint32_t                credtype = SSCS_CRED_TYPE_BASIC_F; | ||||
|    SSCS_BASIC_CREDENTIAL   credential = {0}; | ||||
|    SSCS_SECRET_ID_T        secretId = {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((char*) 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, | ||||
|                                   (SSCS_EXT_T*) pCredStoreScope); | ||||
|       if (rcode != NSSCS_SUCCESS) | ||||
|       { | ||||
|          // There were no credentials for the realm, now try to obtain the | ||||
|          // desktop credentials. | ||||
|          secretId.len = sscs_Utf8Strlen("Desktop") + 1; | ||||
|          if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN) | ||||
|          { | ||||
|             sscs_Utf8Strcpy((char*) secretId.id, "Desktop"); | ||||
|             rcode = miCASAGetCredential(0, | ||||
|                                         &secretId, | ||||
|                                         NULL, | ||||
|                                         &credtype, | ||||
|                                         &credential, | ||||
|                                         (SSCS_EXT_T*) pCredStoreScope); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-GetUserCredentials- Desktop name too long\n", 0); | ||||
|             retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                         CASA_FACILITY_PWTOKEN, | ||||
|                                         CASA_STATUS_UNSUCCESSFUL); | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|    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((char*) credential.username) + 1); | ||||
|       if (pUsername) | ||||
|       { | ||||
|          // Copy the username into the buffer that we will be returning | ||||
|          strcpy(pUsername, (char*) credential.username); | ||||
|  | ||||
|          // Allocate a buffer to return the password | ||||
|          pPassword = (char*) malloc(strlen((char*) credential.password) + 1); | ||||
|          if (pPassword) | ||||
|          { | ||||
|             // Copy the password into the buffer that we will be returning | ||||
|             strcpy(pPassword, (char*) credential.password); | ||||
|  | ||||
|             DbgTrace(1, "-GetUserCredentials- Username = %s\n", pUsername); | ||||
|  | ||||
|             // 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); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-GetUserCredentials- Failed to obtain credentials for pw authentication\n", 0); | ||||
|    } | ||||
|  | ||||
|    // Clear out the credential structure to make sure that we are not leaving sensitive | ||||
|    // information on the stack. | ||||
|    memset(&credential, 0, sizeof(credential)); | ||||
|  | ||||
|    // Return the buffers to the caller if successful | ||||
|    if (CASA_SUCCESS(retStatus)) | ||||
|    { | ||||
|       *ppUsername = pUsername; | ||||
|       *ppPassword = pPassword; | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-GetUserCredentials- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus SSCS_CALL | ||||
| AuthTokenIf_GetAuthToken( | ||||
|    IN       const void  *pIfInstance, | ||||
|    IN       const char  *pContext, | ||||
|    IN       const char  *pMechInfo, | ||||
|    IN       const char  *pHostName, | ||||
|    IN       void        *pCredStoreScope, | ||||
|    INOUT    char        *pTokenBuf, | ||||
|    INOUT    int         *pTokenBufLen) | ||||
| // | ||||
| // Arguments:   | ||||
| //    pIfInstance - | ||||
| //       Pointer to interface object. | ||||
| //    | ||||
| //    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. | ||||
| //                | ||||
| //    pHostName - | ||||
| //       Pointer to null terminated string containing the name of the | ||||
| //       host where the ATS resides. | ||||
| //    | ||||
| //    pCredStoreScope - | ||||
| //       Pointer to CASA structure for scoping credential store access | ||||
| //       to specific users. This can only be leveraged when running in | ||||
| //       the context of System under Windows. | ||||
| //    | ||||
| //    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 | ||||
|        || pHostName == 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, | ||||
|                                   pCredStoreScope, | ||||
|                                   &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; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
|  | ||||
|    INOUT    char        *pTokenBuf, | ||||
|    INOUT    int         *pTokenBufLen) | ||||
| // | ||||
| // Arguments:   | ||||
| //    pIfInstance - | ||||
| //       Pointer to interface object. | ||||
| //    | ||||
| //    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. | ||||
| //                | ||||
| //    pHostName - | ||||
| //       Pointer to null terminated string containing the name of the | ||||
| //       host where the ATS resides. | ||||
| //    | ||||
| //    pCredStoreScope - | ||||
| //       Pointer to CASA structure for scoping credential store access | ||||
| //       to specific users. This can only be leveraged when running in | ||||
| //       the context of System under Windows. | ||||
| //    | ||||
| //    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 | ||||
|        || pHostName == 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, | ||||
|                                   pCredStoreScope, | ||||
|                                   &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 after clearing | ||||
|             // it to avoid leaking sensitive information. | ||||
|             memset(pEncodedToken, 0, strlen(pEncodedToken)); | ||||
|             free(pEncodedToken); | ||||
|          } | ||||
|  | ||||
|          // Free the buffer allocated for the token after clearing it | ||||
|          // to avoid leaving sensitive information behind. | ||||
|          memset(pToken, 0, strlen(pToken)); | ||||
|          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 after clearing memory holding the password | ||||
|       free(pUsername); | ||||
|       memset(pPassword, 0, strlen(pPassword)); | ||||
|       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; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
|  | ||||
|   | ||||
| @@ -28,5 +28,5 @@ LibraryName		\Program Files\novell\casa\lib\pwmech.dll | ||||
| #              tools such as DbgView. Under Linux, debug statements are logged | ||||
| #              to /var/log/messages. | ||||
| # | ||||
| #DebugLevel	0 | ||||
| #DebugLevel 0 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user