Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС_Шеховцов_1.docx
Скачиваний:
73
Добавлен:
09.11.2019
Размер:
14.73 Mб
Скачать

20.2.2. Використання Sun rpc

Однією із найрозповсюдженіших реалізацій RPC-технології для UNIX-систем є Sun RPC [37, 52]. До її особливостей належить реалізація на основі TCP/IP, не­залежність від відображення даних на клієнті та сервері (за перетворення між ти­пами відповідає бібліотека часу виконання RPC).

Розробка файла специфікацій RPC

У документації Sun RPC не вживають терміна IDL, однак аналоги IDL-файлів і IDL-компілятора є. IDL-файлами виступають файли специфікацій RPC (із роз­ширенням .х), які обробляє спеціальна утиліта грсдеп.

Насамперед у файлі специфікацій RPC задають типи даних, які використо­вують як параметри. Частина типів відповідає стандартним типам мови С, на­приклад, int або long, рядковий тип визначають як string, максимальну довжину рядка задають у кутових дужках. Складні типи даних задають структурами (теж визначеними за правилами мови С). Часто простим типам ставлять у відповід­ність структури, що містять єдине поле.

Крім того, у цьому файлі задають специфікацію RPC-застосування. Вона ба­гато в чому подібна до опису інтерфейсу (набір оголошень процедур, об'єднаних спільним іменем). Кожній процедурі присвоюють номер, унікальний у межах спе­цифікації, всьому застосуванню відповідає номер версії та номер застосування (program number), що є 32-бітним числом, яке унікально ідентифікує RPC-cep-вер у рамках системи. Для серверів користувача цей номер має бути в діапазоні 0x20000000- 0x3FFFFFFF.

Наведемо приклад файла специфікацій RPC для задання однієї процедури з одним параметром (припустимо, що цей файл має назву myrpc.x).

/* тип даних для параметра процедури */

struct msg {

string text ;

}:

/* специфікація застосування */

program HELL0PR0G { /* ім'я застосування */

version HELL0_VER { /* ім'я версії */

/* оголошення процедури із заданням номера */

void SAYHELLO(msg) - 1:

} = 1; /* номер версії */

} - 20000010; /* номер застосування */

Ім'я застосування і версії, а також імена процедур прийнято задавати у верх­ньому регістрі. Під час генерації заглушок ім'я процедури переводиться до ниж­нього регістра.

Файл специфікацій RPC має оброблятися утилітою rpcgen:

$ rpcgen myrpc.x

Унаслідок цього на основі myrpc.x утворяться такі файли:

♦ myrpc.h - оголошення віддалених процедур і типів, які будуть використані у застосуваннях;

♦ myrpc_clnt.c, myrpc_svc.c - коди клієнтської та серверної заглушок;

♦ myrpc_xdr.c - код перетворення типів у формат зовнішнього відображення (XDR), придатний для пересилання мережею (цей файл компонується разом із клієнтом і сервером).

Служба відображення портів Sun RPC

Ця служба є деяким аналогом служби іменування. Вона відповідає за відобра­ження між номерами застосувань і TCP або UDP-портами та реалізована як фо­новий процес, який звичайно називають portmapper.

Реєструють застосування із використанням його номера (це зазвичай відбува­ється під час запуску застосування). Під час реєстрації також задають номер пор­ту; у більшості випадків автоматично вибирають деякий вільний порт, який далі використовуватиме це серверне застосування.

Перед викликом віддаленої процедури клієнт має зв'язатися зі службою ві­дображення портів на відповідному хості (із використанням наперед відомого порту з номером 111), передати їй номер застосування і отримати у відповідь но­мер порту, через який можна обмінюватися даними із цим застосуванням.

Отримати інформацію про зареєстровані застосування можна за допомогою утиліти rpcinfo.

$ rpcinfo -р ім'я_хоста

Розробка віддалених процедур

Прототип реалізації віддаленої процедури відрізняється від її прототипу, оголо­шеного у файлі специфікації:

♦ до імені процедури додають суфікс номер-Bepciïsvc, наприклад, процедура sayhelloO має бути реалізована як sayhel 1 o_l_svc( );

♦ усі параметри і повернене значення замінюють відповідними покажчиками (string при цьому відповідає char *);

♦ як додатковий останній параметр задають покажчик на структуру svcreq, яку передає у процедуру бібліотека часу виконання і яка містить інформацію про контекст виклику.

Наведемо приклад коду віддаленої процедури:

finclude "myrpc.h"

void * sayhello_l_svc(msg *argp, struct svc_req *rqstp) { static char *result = { 0 }; printfC'eifl клієнта: ïs\n", argp->text); return (void *) result:

}

Розробка сервера

Особливістю Sun RPC є те, що у разі використання утиліти rpcgen жодних додат­кових кроків для розробки сервера, крім створення коду віддалених процедур, робити не потрібно. Код функції maiп{ ) для сервера, поряд із кодом серверної за­глушки, генерує rpcgen і поміщає у файл myhello_svc.c. Цей код автоматично реєст­рує сервер у службі відображення портів, переводить його у фоновий режим і пе­реходить до очікування з'єднань.

Під час компіляції та компонування сервера потрібно використовувати файли із визначеннями збережених процедур, файл серверної заглушки myhello_svc.c і файл XDR-перетворень myhello_xdr.c.

Розробка клієнта

Перед викликом процедури на віддаленому сервері в коді клієнта необхідно от­римати клієнтський дескриптор, що буде використаний далі для виклику збере­жених процедур із сервера. Цей дескриптор є покажчиком на спеціальну структу­ру CLIENT. Для його отримання використовують функцію clnt_create()

#finclude <rpc/rpc.h>

CLIENT *clnt_create(const char *host. unsigned long pnum.

unsigned long ver. const char *protocol);

де: host — ім'я або IP-адреса віддаленого хоста;

pnum - номер застосування (у заголовному файлі, згенерованому rpcgen, для нього визначають відповідну константу, наприклад HELL0PR0G);

ver - номер версії (для нього визначають аналогічну константу, наприклад

HELL0_VER);

protocol — рядок із назвою протоколу ("tcp", "udp").

Заголовний файл <rpc/rpc.h> буде автоматично підключений у myrpc.h, тому явно підключати його не обов'язково.

#include "myrpc.h" CLIENT *cl;

cl = clnt_create("myserver". HELL0_PR0G. HELLCM/ER. "tcp");

Після отримання клієнтського дескриптора можна викликати віддалену про­цедуру. Для цього викликають процедуру і м ' я_номер_версіі ( ): для процедури say­hel 1о() треба викликати sayhel 1о_1(). Усі аргументи передають у цю функцію як покажчики, останнім аргументом додатково задають клієнтський дескриптор.

struct msg hello - { "hello world" };

void *res = sayhello_l(&hello. cl);

Виклик віддаленої процедури може повернути NULL: це означає, що сталася по­милка. Рядок з інформацією про помилку в цьому разі повертає функція clntsper-гогО, що першим параметром приймає клієнтський дескриптор, а другим — ім'я віддаленого хоста:

if (res == NULL)

printfCTloMHflKa: %s\n". clnt_sperror(cl, "myserver")) :

Забезпечення безпеки даних у разі використання Sun RPC

Для забезпечення безпеки даних у разі використання RPC застосовують аутенти-фікацію RPC-клієнтів перед доступом до сервера. Є кілька рівнів такої аутенти-фікації.

Рівень AUTH NONE (використовуваний за замовчуванням) означає, що аутенти­фікації не виконують зовсім. Відповідно до нього будь-який клієнт у мережі, що може відсилати пакети RPC-серверу, має змогу викликати будь-яку реалізовану ним процедуру. Цей рівень не забезпечує ніякого захисту і не рекомендований до використання.

Рівень AUTHUNIX означає, що кожний RPC-запит супроводжується ідентифіка­тором користувача (uid) і набором ідентифікаторів груп (gid). Мається на увазі, що ці ідентифікатори відповідають користувачу, який запустив клієнтське засто­сування, і що сервер довіряє цьому користувачу.

Для використання такої аутентифікації на клієнті після виклику clnt_create( ) необхідно виконати код

// CLIENT *cl = clntcreate(...)

authdestroy(cl ->cl_auth) ;

cl->cl_auth = authsyscreatedefaultO ; // задання AUTHJJNIX

Цей рівень теж не зовсім відповідає сучасним уявленням про мережну безпе­ку, оскільки зловмисник може створювати і відсилати RPC-пакети із довільними значеннями uid і gid, і їхнє авторство не може бути перевірене сервером. Наприк­лад, коли відомо, який користувач потрібен для виконання необхідних процедур, і в мережі є комп'ютер, на якому зловмисник має права root, він може створити користувача із необхідним uid і виконувати RPC-запити клієнтським процесом, запущеним під цим користувачем. Такі запити будуть успішно виконані, хоча па­роль потрібного користувача RPC-сервера зловмисникові невідомий.

Рівень AUTH_DES використовує гібридну криптосистему для організації захище­ного каналу зв'язку для RPC-виклику. Реалізація такого рівня аутентифікації ві­дома як Secure RPC.

]