Опубликован: 04.07.2008 | Доступ: свободный | Студентов: 637 / 33 | Оценка: 4.83 / 5.00 | Длительность: 42:11:00
Тема: Безопасность
Специальности: Администратор информационных систем, Специалист по безопасности
Теги:
Дополнительный материал 2:
Пример программы DSAPI
Пример исходного кода
В последующих трех примерах приведен исходный код для примера DSAPI-фильтра.
/****************************************************************** ПРОГРАММА: SECDOM ФАЙЛ: SECDOM.C (основная программа) 618 Приложение B НАЗНАЧЕНИЕ: Пример программы C API, демонстрирующей создание библиотеки, выполняющей аутентификацию пользователя Domino через Web с использованием учетной записи пользователя в операционной системе через DSAPI. ******************************************************************/ /* Включаемые файлы ввода-вывода */ #include <stdlib.h> #include <stdio.h> #include <string.h> /* Включаемые файлы Notes SDK */ #include "global.h" #include "osmem.h" #include "lookup.h" #include "dsapi.h" #include "addin.h" #define MAX_BUF_LEN 512 #define USER_DOMAIN_SEPARATOR "@" /*--- * прототипы локальных процедур */ /* Точка входа общей библиотеки Notes SDK для Unix */ STATUS FAR PASCAL MainEntryPoint (void); /* Процедуры с синтаксисом, требуемым интерфейсом DSAPI */ unsigned int Authenticate(FilterContext* context, FilterAuthenticate* authData); /* Извлечение имен из адресной книги Notes */ int getUserNames (FilterContext* context, char *userName, char **pUserFullName, int *pUserFullNameLen, char **pUserShortName, int *pUserShortNameLen); int getLookupInfo (FilterContext* context, char *pMatch, unsigned short itemNumber, char **pInfo, int *pInfoLen); int doAuthenticate(char *userName, char *domain, char *password); #ifdef UNIX int unixAuthenticate(char *userName, char *password); #else int separateUsernameAndDomainname(char *userName,char *separator,char **user,char**domain); int winAuthenticate(char *userName, char *domain, char *password); #endif /*--- * далее приведены локальные процедуры */ STATUS FAR PASCAL MainEntryPoint (void) {/ * * Описание: Обеспечение основной точки входа Notes API для * инициализации в этой общей библиотеке. Нам нужна эта точка входа, * потому что мы хотим иметь возможность просматривать информацию * пользователей в адресной книге через * Notes SDK API. ** Ввод: нет * Вывод: нет * Возврат: NOERROR */ return NOERROR; }/ *--- * инициализация фильтра */ unsigned int FilterInit(FilterInitData* filterInitData) {/ * * Описание: Инициализация фильтра выполняется при динамической загрузке * общей библиотеки файльтра. ** Ввод: спецификация filterInitData dsapi контролирует формат * данных * Вывод: заполняются некоторые поля filterInitData ** Возврат: kFilterHandledEvent */ printf("\nFilterInitData() is getting called.\n"); /*Обязательно*/ filterInitData->appFilterVersion = kInterfaceVersion; /* Измените следующий код, установив требуемые флаги */ filterInitData->eventFlags = kFilterAuthenticate; /* Задайте короткое описание своего фильтра */ strcpy(filterInitData->filterDesc, "Operating System Authentication Filter"); /* здесь можно вставить код глобальной инициализации... */ /* Выходные данные, направляемые в stdout и stderr, выводятся в * консоли сервера, но не записываются в файл журнала сервера. */ printf("\nDSAPI Authentication filter initialized\n"); return kFilterHandledEvent; }/ *--- * завершение работы фильтра */ unsigned int TerminateFilter(unsigned int reserved) {/ * * Описание: Завершение работы фильтра выполняется при выгрузке * общей библиотеки фильтра. ** Ввод: зарезервирован, не используется (спецификация dsapi контролирует * формат данных) * Вывод: нет ** Возврат: kFilterHandledEvent */ /* здесь можно вставить код глобальной очистки... */ return kFilterHandledEvent; }/ *--- * обработка уведомлений фильтра */ unsigned int HttpFilterProc(FilterContext* context, unsigned int eventType, void* eventData) {/ * * Описание: Эта процедура вызывается для обработки всех событий dsapi-фильтра. ** Ввод: зарезервирован, не используется (спецификация dsapi контролирует * формат данных) * Вывод: нет ** Возврат: kFilterNotHandled для всех ненастроенных событий, * в противном случае позволяет процедуре фильтра задать возвращаемое * значение. */ /* Нужно включить только те события, которые требуется обрабатывать */ switch (eventType) { case kFilterAuthenticate: return Authenticate(context, (FilterAuthenticate *)eventData); default: break; }r eturn kFilterNotHandled; }/ *--- * обработка аутентификации пользователей */ unsigned int Authenticate(FilterContext* context, FilterAuthenticate* authData) {/ * * Описание: Эта процедура вызывается при возникновении * события dsapi kFilterAuthUser. ** Ввод: контекстная спецификация dsapi контролирует формат данных ** поле пароля authData содержит пароль, предназначенный для использования * при аутентификации * поле userName содержит имя * для аутентификации * поле foundInCache = TRUE, если * пользователь был найден в кeше и можно провести * его аутентификацию. ** Вывод: в поле authType authName вводится отличительное имя * пользователя * в поле authType filed вводится * kNotAuthentic - если нельзя выполнить аутентификацию пользователя * kAuthenticBasic - если можно выполнить аутентификацию * пользователя. ** Возврат: kFilterNotHandled - если входные данные непонятны, * или если пользователь был найден в кeше, или * если обнаружилось, что аутентифицируемый пользователь * не задан в операционной системе. * kFilterHandledEvent - если пользователь задан в операционной системе. */ /* Если пользователь найден в кeше, выполнение дополнительных действий * не требуется. */ if (!authData || authData->foundInCache) { AddInLogMessageText ("\n user is found in the cache \n", NOERROR); return kFilterNotHandled; }/ * Попытка проверить пароль пользователя. */ if (authData->userName && authData->password) { char *fullName = NULL; int fullNameLen = 0; char *shortName = NULL; int shortNameLen = 0; char *user = NULL; char *domain = NULL; #if defined SOLARIS || AIX user=(char*)authData->userName; #else separateUsernameAndDomainname(authData->userName,USER_DOMAIN_SEPARA TOR,&user,&domain); #endif /* Просмотр пользователя в адресной книге. Получение * короткого имени пользователя (ожидается, что оно соответствует * имени пользователя в ОС) и получение полного имени пользователя * (ожидается, что оно будет иметь формат, подлежащий передаче обратно в * dsapi). */ if (NOERROR == getUserNames (context, user, &fullName, &fullNameLen, &shortName, &shortNameLen) ) {/ * Аутентификация имени пользователя/пароля в ОС */ if (NOERROR != doAuthenticate(shortName, domain, Пример программы DSAPI 623 (char *)authData->password)) {r eturn kFilterNotHandled; }e lse {/ * Копирование канонического имени этого пользователя, * требуемого dsapi. */ strncpy ((char *)authData->authName, fullName, authData->authNameSize); authData->authType = kAuthenticBasic; authData->foundInCache = TRUE; }r eturn kFilterHandledEvent; }}r eturn kFilterNotHandled; }i nt getUserNames (FilterContext* context, char *userName, char **pUserFullName, int *pUserFullNameLen, char **pUserShortName, int *pUserShortNameLen) { /* * Описание: Просмотр пользователя и возврат полного и короткого * имени пользователя. ** Ввод: context - контекст, используемый для выделения памяти * userName - имя пользователя, для которого выполняется просмотр * Вывод: pUserFullName - расположение полного имени пользователя * pUserFullNameLen - расположение для хранения длины полного имени * pUserShortName – расположение короткого имени пользователя * pUserShortNameLen - расположение для хранения длины короткого имени ** Возврат: -1 - ошибка, 0 - успех */ STATUS error = NOERROR; HANDLE hLookup = NULLHANDLE; DWORD Matches = 0; char *pLookup; char *pName = NULL; char *pMatch = NULL; int rc = -1; /* Инициализация вывода */ *pUserFullName = NULL; *pUserFullNameLen = 0; *pUserShortName = NULL; *pUserShortNameLen = 0; /* do the name lookup */ error = NAMELookup2(NULL, /* NULL означает локальный просмотр */ 0, /* флаги */ 1, /* количество пространств имен */ "$Users", /* список пространств имен */ 1, /* количество имен, для которых требуется выполнить просмотр */ userName, /* список имен, для которых требуется выполнить просмотр */ 2, /* количество возвращаемых элементов */ "FullName\0ShortName", /* список возвращаемых * элементов */ &hLookup); /* место для получения дескриптора * буфера возврата */ if (error || (NULLHANDLE == hLookup)) goto NoUnlockExit; pLookup = (char *) OSLockObject(hLookup); /* Получение указателя нашей записи. */ pName = (char *)NAMELocateNextName2(pLookup, /* буфер просмотра * имени */ NULL, /* начинать в начале * буфера просмотра */ &Matches); /* Получает количество * найденных записей * (должно быть равно 1) */ /* Если запись не найдена - выход */ if ((pName == NULL) || (Matches <= 0)) { goto Exit; }p Match = (char *)NAMELocateNextMatch2(pLookup, /* буфер просмотра * имени */ pName, /* найденная нами запись */ NULL); /* предыдущих соответствий нет */ if (NULL == pMatch) { goto Exit; } /* Извлечение полного имени из полученной информации */ if ( getLookupInfo (context, pMatch, 0, pUserFullName, pUserFullNameLen) ) goto Exit; AddInLogMessageText ("full name=%s,length=%d\n", 0,*pUserFullName,* pUserFullNameLen); /* Извлечение короткого имени из полученной информации */ if ( getLookupInfo (context, pMatch, 1, pUserShortName, pUserShortNameLen) ) goto Exit; else rc = 0; AddInLogMessageText ("short name=%s,length=%d\n", 0,*pUserShortName ,*pUserShortNameLen); Exit: if ( pLookup && hLookup ) OSUnlock(hLookup); NoUnlockExit: if (NULLHANDLE != hLookup) OSMemFree(hLookup); return rc; }i nt getLookupInfo (FilterContext* context, char *pMatch, unsigned short itemNumber, char **pInfo, int *pInfoLen) { /* * Описание: Извлечение информации из буфера просмотра * * Ввод: context - контекст, используемый для выделения памяти * pMatch – имя буфера просмотра * itemNumber – место хранения информации в буфере просмотра * Вывод: pInfo – расположение буфера информации * pInfoLen – место хранения длины информации * * Возврат: -1 - ошибка, 0 - успех */ unsigned int reserved = 0; unsigned int errID; char *ValuePtr = NULL; WORD ValueLength, DataType; STATUS error; void *newSpace = NULL; /* Инициализация вывода */ *pInfo = NULL; *pInfoLen = 0; /* Проверка типа и длины информации */ ValuePtr = (char *)NAMELocateItem2(pMatch, itemNumber, &DataType, &ValueLength); if (NULL == ValuePtr || ValueLength == 0) { return -1; }V alueLength -= sizeof(WORD); /* проверка значения DataType */ switch (DataType) { case TYPE_TEXT_LIST: break; case TYPE_TEXT: break; default: return -1; }/ * Выделение пространства для информации. Эта память освобождается * автоматически при завершении работы потока. */ newSpace = (context->AllocMem)(context, ValueLength+1, reserved, &errID); *pInfo = (char *) newSpace; if (NULL == *pInfo) { printf ("Out of memory\n"); return -1; }/ * Получение информации */ error = NAMEGetTextItem2(pMatch, /* найденное соответствие */ itemNumber, /* номер элемента в порядке * просмотра элементов */ 0, /* Номер элемента в текстовых * списках */ *pInfo, /* буфер для копирования * результата */ MAX_BUF_LEN); /* Длина буфера */ if (!error) { *pInfoLen = strlen(*pInfo)+1; return 0; }r eturn -1; } int doAuthenticate(char *userName, char *domain, char *password) { /* * Описание: Проверяет, существует ли пользователь в операционной системе * Если существует, определяет, можно ли проверить пароль. ** Ввод: userName - имя пользователя * domain - имя домена (NULL - UNIX) * password - пароль ** Возврат: -1 - ошибка, 0 - успех */ if (!userName) { AddInLogMessageText ("\nERROR: User must be specified\n", NOERROR); return -1; }# if defined SOLARIS || AIX printf("\nin doAuthenticate()\n"); return(unixAuthenticate(userName, password)); #else if (!domain) { AddInLogMessageText ("\nERROR: Domain must be specified. Use username@ domainname format\n", NOERROR); return -1; }r eturn(winAuthenticate(userName, domain, password)); #endif }/ * ----- конец secdom.c */Пример B.1. Основная программа