2006-01-19 00:34:21 +01:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
2006-01-31 23:01:47 +01:00
|
|
|
* Copyright (C) 2005-2006 Novell, Inc. Inc. All Rights Reserved.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* 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
|
2006-01-31 23:01:47 +01:00
|
|
|
* Library Lesser General Public License for more details.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2006-01-31 23:01:47 +01:00
|
|
|
* License along with this library; if not, Novell, Inc.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
|
|
* you may find current contact information at www.novell.com.
|
|
|
|
*
|
|
|
|
***********************************************************************/
|
2005-12-14 18:18:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
//===[ Include files ]=====================================================
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <security/pam_appl.h>
|
|
|
|
|
|
|
|
#include <auth_token.h>
|
|
|
|
|
|
|
|
//===[ 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() --*/
|
|
|
|
|