VGAuthError VGAuth_GenerateSSPIChallenge(VGAuthContext *ctx, size_t requestLen, const unsigned char *request, int numExtraParams, const VGAuthExtraParams *extraParams, unsigned int *id, size_t *challengeLen, unsigned char **challenge) { VGAuthError err; if ((NULL == ctx) || (NULL == request) || (NULL == challengeLen) || (NULL == challenge) || (NULL == id)) { return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } return VGAuthGenerateSSPIChallengeImpl(ctx, requestLen, request, id, challengeLen, challenge); }
VGAuthError VGAuth_SetLogHandler(VGAuthLogFunc logFunc, void *userData, int numExtraParams, const VGAuthExtraParams *extraParams) { VGAuthError err; if (NULL == logFunc) { return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } /* * This makes everything using glib, no matter what log domain is * used, go through logFunc. */ (void) g_log_set_default_handler((GLogFunc) logFunc, userData); return VGAUTH_E_OK; }
VGAuthError VGAuth_RevokeTicket(VGAuthContext *ctx, const char *ticket, int numExtraParams, const VGAuthExtraParams *extraParams) { VGAuthError err; if ((NULL == ctx) || (NULL == ticket)) { return VGAUTH_E_INVALID_ARGUMENT; } if (!g_utf8_validate(ticket, -1, NULL)) { Warning("%s: invalid ticket\n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } err = VGAuth_SendRevokeTicketRequest(ctx, ticket); return err; }
VGAuthError VGAuth_ValidateTicket(VGAuthContext *ctx, const char *ticket, int numExtraParams, const VGAuthExtraParams *extraParams, VGAuthUserHandle **handle) { VGAuthError err; if ((NULL == ctx) || (NULL == ticket) || (NULL == handle)) { return VGAUTH_E_INVALID_ARGUMENT; } if (!g_utf8_validate(ticket, -1, NULL)) { Warning("%s: invalid ticket\n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } err = VGAuth_SendValidateTicketRequest(ctx, ticket, handle); if (err != VGAUTH_E_OK) { goto done; } done: return err; }
VGAuthError VGAuth_CreateTicket(VGAuthContext *ctx, VGAuthUserHandle *handle, int numExtraParams, const VGAuthExtraParams *extraParams, char **newTicket) { VGAuthError err; if ((NULL == ctx) || (NULL == handle) || (NULL == newTicket)) { return VGAUTH_E_INVALID_ARGUMENT; } if (!(handle->flags & VGAUTH_HANDLE_FLAG_CAN_CREATE_TICKET)) { Warning("%s: called on handle that doesn't not support operation \n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } err = VGAuth_SendCreateTicketRequest(ctx, handle, newTicket); return err; }
VGAuthError VGAuth_ValidateUsernamePassword(VGAuthContext *ctx, const char *userName, const char *password, int numExtraParams, const VGAuthExtraParams *extraParams, VGAuthUserHandle **handle) { VGAuthError err; if ((NULL == ctx) || (NULL == userName) || (NULL == password) || (NULL == handle)) { return VGAUTH_E_INVALID_ARGUMENT; } if (!g_utf8_validate(userName, -1, NULL)) { Warning("User not in UTF-8\n"); return VGAUTH_E_INVALID_ARGUMENT; } if (!g_utf8_validate(password, -1, NULL)) { Warning("Password not in UTF-8\n"); return VGAUTH_E_INVALID_ARGUMENT; } if (userName[0] == '\0') { Warning("Empty Username\n"); return VGAUTH_E_INVALID_ARGUMENT; } if (!Usercheck_UsernameIsLegal(userName)) { Warning("Username '%s' contains invalid characters\n", userName); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } err = VGAuthValidateUsernamePasswordImpl(ctx, userName, password, handle); if (VGAUTH_E_OK == err) { VGAuth_AuditEvent(ctx, TRUE, SU_(auth.password.valid, "Username and password successfully validated for '%s'"), userName); } else { VGAuth_AuditEvent(ctx, FALSE, SU_(auth.password.invalid, "Username and password mismatch for '%s'"), userName); } return err; }
VGAuthError VGAuth_UninstallClient(VGAuthContext *ctx, int numExtraParams, const VGAuthExtraParams *extraParams) { VGAuthError err; if (NULL == ctx) { return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } #ifdef _WIN32 return VGAUTH_E_OK; #elif defined(__linux__) { gchar *fileName; gchar *lowAppName; if (!VGAuth_IsRunningAsRoot()) { return VGAUTH_E_PERMISSION_DENIED; } /* * PAM will convert a mixed-case application name into all lower case, * so make the lowercase version of the file. */ lowAppName = g_ascii_strdown(ctx->applicationName, -1); fileName = g_strdup_printf(PAM_DIRECTORY"/%s", lowAppName); if (g_unlink(fileName) != 0) { VGAUTH_ERROR_SET_SYSTEM_ERRNO(err, errno); Warning("%s: Unable to remove PAM config file '%s'\n", __FUNCTION__, fileName); goto done; } err = VGAUTH_E_OK; done: g_free(fileName); g_free(lowAppName); return err; } #elif defined(sun) return VGAUTH_E_OK; #else #error VGAuth_UninstallClient unsupported on this platform. #endif // linux }
VGAuthError VGAuth_ValidateSSPIResponse(VGAuthContext *ctx, unsigned int id, size_t responseLen, const unsigned char *response, int numExtraParams, const VGAuthExtraParams *extraParams, VGAuthUserHandle **handle) { VGAuthError err; if ((NULL == ctx) || (NULL == response) || (NULL == handle)) { return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } return VGAuthValdiateSSPIResponseImpl(ctx, id, responseLen, response, handle); }
VGAuthError VGAuth_InstallClient(VGAuthContext *ctx, int numExtraParams, const VGAuthExtraParams *extraParams) { VGAuthError err; if (NULL == ctx) { return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } #ifdef _WIN32 return VGAUTH_E_OK; #elif defined(__linux__) { gchar *fileName; gchar *lowAppName; FILE *fp; /* * XXX * * This has worked for currently tested distros, but could * be improved. I stole it from the tools installer, but they've * since improved it further to use 'include' statements, and do different * things depending on the distro. It'd also be nice to somehow * share code with the installer. See bug 889444. */ static char *fileContents = "#%PAM-1.0\n" "# \n" "# This file was generated by vgauth\n" "# \n" "auth sufficient pam_unix2.so shadow\n" "auth sufficient pam_unix.so shadow\n" "auth required pam_unix_auth.so shadow\n" "account sufficient pam_unix2.so\n" "account sufficient pam_unix.so\n" "account required pam_unix_auth.so\n"; if (!VGAuth_IsRunningAsRoot()) { return VGAUTH_E_PERMISSION_DENIED; } /* * PAM will convert a mixed-case application name into all lower case, * so make the lowercase version of the appName. */ lowAppName = g_ascii_strdown(ctx->applicationName, -1); fileName = g_strdup_printf(PAM_DIRECTORY"/%s", lowAppName); /* * XXX add NO_CLOBBER check to catch some app that already has the same name? * Some concern that we can't do anything about it on Windows. */ fp = g_fopen(fileName, "w+"); if (NULL == fp) { VGAUTH_ERROR_SET_SYSTEM_ERRNO(err, errno); Warning("%s: Unable to open PAM config file %s for creation\n", __FUNCTION__, fileName); goto done; } if (g_fprintf(fp, "%s", fileContents) < 0) { VGAUTH_ERROR_SET_SYSTEM_ERRNO(err, errno); Warning("%s: Unable to fprintf() PAM config file contents\n", __FUNCTION__); goto done; } err = VGAUTH_E_OK; done: if (fp != NULL) { if (fclose(fp) != 0) { if (err == VGAUTH_E_OK) { VGAUTH_ERROR_SET_SYSTEM_ERRNO(err, errno); } Warning("%s: Unable to close PAM config file\n", __FUNCTION__); } } g_free(fileName); g_free(lowAppName); return err; } #elif defined(sun) return VGAUTH_E_OK; #else #error VGAuth_InstallClient unsupported on this platform. #endif }
VGAuthError VGAuth_Init(const char *applicationName, int numExtraParams, const VGAuthExtraParams *extraParams, VGAuthContext **ctx) { VGAuthContext *newCtx = NULL; VGAuthError err = VGAUTH_E_OK; static gboolean firstTime = TRUE; int i; /* * The application name cannot be an empty string. */ if ((NULL == applicationName) || ('\0' == *applicationName) || (NULL == ctx)) { return VGAUTH_E_INVALID_ARGUMENT; } *ctx = NULL; /* XXX process any options */ if (!g_utf8_validate(applicationName, -1, NULL)) { Warning("%s: invalid applicationName\n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } newCtx = g_malloc0(sizeof(VGAuthContext)); if (NULL == newCtx) { return VGAUTH_E_OUT_OF_MEMORY; } newCtx->applicationName = g_strdup(applicationName); newCtx->isImpersonating = FALSE; newCtx->impersonatedUser = NULL; /* * Only init prefs, i18n and auditing once. */ if (firstTime) { gboolean logSuccessAudits; gchar *msgCatalog; gPrefs = Pref_Init(VGAUTH_PREF_CONFIG_FILENAME); logSuccessAudits = Pref_GetBool(gPrefs, VGAUTH_PREF_AUDIT_SUCCESS, VGAUTH_PREF_GROUP_NAME_AUDIT, TRUE); msgCatalog = Pref_GetString(gPrefs, VGAUTH_PREF_LOCALIZATION_DIR, VGAUTH_PREF_GROUP_NAME_LOCALIZATION, VGAUTH_PREF_DEFAULT_LOCALIZATION_CATALOG); I18n_BindTextDomain(VMW_TEXT_DOMAIN, NULL, msgCatalog); g_free(msgCatalog); Audit_Init("VGAuth", logSuccessAudits); firstTime = FALSE; } newCtx->numExtraParams = numExtraParams; newCtx->extraParams = g_malloc0(sizeof(*newCtx->extraParams) * numExtraParams); for (i = 0; i < numExtraParams; i++) { newCtx->extraParams[i].name = g_strdup(extraParams[i].name); newCtx->extraParams[i].value = g_strdup(extraParams[i].value); } err = VGAuth_InitConnection(newCtx); if (VGAUTH_E_OK != err) { return err; } err = VGAuthInitAuthentication(newCtx); if (VGAUTH_E_OK != err) { return err; } *ctx = newCtx; Log("VGAuth '%s' initialized for application '%s'. Context created at %p\n", BUILD_NUMBER, newCtx->applicationName, newCtx); return err; }
VGAuthError VGAuth_ValidateSamlBearerToken(VGAuthContext *ctx, const char *samlToken, const char *userName, int numExtraParams, const VGAuthExtraParams *extraParams, VGAuthUserHandle **handle) { VGAuthError err; VGAuthUserHandle *newHandle = NULL; int validateOnly = -1; int i; /* * arg check */ if ((NULL == ctx) || (NULL == samlToken) || (NULL == handle)) { return VGAUTH_E_INVALID_ARGUMENT; } *handle = NULL; if (!g_utf8_validate(samlToken, -1, NULL)) { Warning("%s: SAML token is not valid UTF-8.\n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } if ((NULL != userName) && !g_utf8_validate(userName, -1, NULL)) { Warning("%s: Username is not valid UTF-8.\n", __FUNCTION__); return VGAUTH_E_INVALID_ARGUMENT; } if ((NULL != userName) && !Usercheck_UsernameIsLegal(userName)) { Warning("Username '%s' contains invalid characters\n", userName); return VGAUTH_E_INVALID_ARGUMENT; } err = VGAuthValidateExtraParams(numExtraParams, extraParams); if (VGAUTH_E_OK != err) { return err; } /* * XXX * * Should be generalized once we have more use cases. */ for (i = 0; i < numExtraParams; i++) { if (g_strcmp0(extraParams[i].name, VGAUTH_PARAM_VALIDATE_INFO_ONLY) == 0) { // only allow it to be set once if (validateOnly != -1) { Warning("%s: extraParam '%s' passed multiple times\n", __FUNCTION__, extraParams[i].name); return VGAUTH_E_INVALID_ARGUMENT; } if (extraParams[i].value) { if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_TRUE, extraParams[i].value) == 0) { validateOnly = 1; } else if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_FALSE, extraParams[i].value) == 0) { validateOnly = 0; } else { Warning("%s: Unrecognized value '%s' for boolean param %s\n", __FUNCTION__, extraParams[i].value, extraParams[i].name); return VGAUTH_E_INVALID_ARGUMENT; } } else { return VGAUTH_E_INVALID_ARGUMENT; } } } err = VGAuth_SendValidateSamlBearerTokenRequest(ctx, (validateOnly == 1) ? TRUE : FALSE, samlToken, userName, &newHandle); if (err != VGAUTH_E_OK) { goto done; } *handle = newHandle; done: return err; }