/*********************************************************************** * * Copyright (C) 2005-2006 Novell, Inc. * * 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 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, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * ***********************************************************************/ //===[ Include files ]===================================================== #include #include #include #include #include #include #include #include //===[ Type definitions ]================================================== typedef struct _AppUserData { char *pUserName; char *pAuthToken; } AppUserData, *PAppUserData; // // DbgTrace macro define // #define DbgTrace(LEVEL, X, Y) { \ if (LEVEL == 0) \ printf(X, Y); \ else if (DebugLevel >= LEVEL) \ printf(X, Y); \ } //===[ Function prototypes ]=============================================== //===[ Global variables ]================================================== // Usage string char usage[] = "\ntest: usage: [-p ConnectPort] [-D DebugLevel]\n"; // Debug Level int DebugLevel = 3; //++======================================================================= int Converse(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) // // Arguments: // // Returns: // // Abstract: // // Notes: // // Environment: // //=======================================================================-- { int retStatus = PAM_SUCCESS; int replies = 0; struct pam_response *reply = NULL; AppUserData *pAppUserData = (PAppUserData) appdata_ptr; // Initialize output parameters *resp = NULL; // Check input parameters if (num_msg <= 0 || appdata_ptr == NULL) return PAM_CONV_ERR; // Allocate enough space for the replies reply = malloc(sizeof(struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; // Zero the reply buffer memset(reply, 0, sizeof(struct pam_response) * num_msg); for (replies = 0; replies < num_msg && retStatus == PAM_SUCCESS; replies++) { switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: // The caller wants the username reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = malloc(strlen(pAppUserData->pUserName) + 1); if (reply[replies].resp) strcpy(reply[replies].resp, pAppUserData->pUserName); else { DbgTrace(0, "Converse- Buffer allocation failure\n", 0); retStatus = PAM_CONV_ERR; } break; case PAM_PROMPT_ECHO_OFF: // The caller wants the authentication token reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = malloc(strlen(pAppUserData->pAuthToken) + 1); if (reply[replies].resp) strcpy(reply[replies].resp, pAppUserData->pAuthToken); else { DbgTrace(0, "Converse- Buffer allocation failure\n", 0); retStatus = PAM_CONV_ERR; } break; case PAM_TEXT_INFO: case PAM_ERROR_MSG: // Just return success reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = NULL; break; default: // Un-expected retStatus = PAM_CONV_ERR; } } // Proceed based on the status if (retStatus == PAM_SUCCESS) { *resp = reply; } else { // Free buffers allocated for the reply for (replies = 0; replies < num_msg && retStatus == PAM_SUCCESS; replies++) { if (reply[replies].resp != NULL) free(reply[replies].resp); } free(reply); } return retStatus; } //++======================================================================= void ExecuteTests(void) // // Arguments: // // Returns: // // Abstract: // // Notes: // // Environment: // //=======================================================================-- { CasaStatus status; char userName[100]; int userNameBufLen = sizeof(userName); char token[1000]; int tokenBufLen = sizeof(token); DbgTrace(1, "ExecuteTests- Start\n", 0); status = GetAuthTokenCredentials("krb-test-service", userName, &userNameBufLen, token, &tokenBufLen); if (CASA_SUCCESS(status) && CasaStatusCode(status) != CASA_STATUS_OBJECT_NOT_FOUND) { AppUserData appUserData = {userName, token}; struct pam_conv conv = {Converse, &appUserData}; pam_handle_t *pamh; int pam_status; // We obtained authentication token credentials to authenticate // to the service, now verify the credentials using PAM_Authenticate.. printf("userName = %s\n", userName); printf("userNameBufLen = %d\n", userNameBufLen); printf("token = %s\n", token); printf("tokenBufLen = %d\n", tokenBufLen); // Open a PAM Handle pam_status = pam_start("krb-test-service", userName, &conv, &pamh); if (pam_status == PAM_SUCCESS) { // Now authenticate the user pam_status = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK); if (pam_status == PAM_SUCCESS) { DbgTrace(1, "ExecuteTests- pam_authenticate success\n", 0); } else { DbgTrace(0, "ExecuteTests- pam_authenticate failure, error = %s\n", pam_strerror(pamh, pam_status)); } // Close the PAM Handle pam_end(pamh, pam_status | PAM_DATA_SILENT); } else { DbgTrace(0, "ExecuteTests- pam_start failure, status = %08X\n", pam_status); } } else { DbgTrace(0, "ExecuteTests- GetAuthTokenCredentials failure, status = %08X\n", status); } DbgTrace(1, "ExecuteTests- End\n", 0); } //++======================================================================= int main( int argc, char* argv[]) // // Arguments: // // Returns: // // Abstract: // // Notes: // // L2 //=======================================================================-- { int optionsSpecified = 0; bool doneScanning = false; bool invalidOption = false; int option; printf("**** auth-token-test ****\n"); // Scan through the options specified while (!doneScanning) { opterr = 0; option = getopt(argc, argv, "D"); // Proceed based on the result switch (option) { case 'D': // Set the debug level DebugLevel = atoi(optarg); optionsSpecified++; break; case '?': // Invalid option detected doneScanning = true; invalidOption = true; break; default: // Done scanning doneScanning = true; break; } } // Do some sanity checking if (!invalidOption) { int i; for (i = 0; i < 1; i++) ExecuteTests(); } else { // Invalid option detected or the user failed to // specify the listening port number. printf(usage, argv[0]); } return 0; } /*-- main() --*/