mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
* src/tls/: Library for TLS support (not completed)
* src/ejabberd_auth.erl: Now uses two LDAP connections * src/ejabberd_c2s.erl: Return resource on get_presence request (thanks to Mickael Remond) * src/mod_configure2.erl: Bugfix (thanks to Sergei Golovan) * src/msgs/ua.msg: New Ukrainian translation (thanks to usercard) * src/msgs/nl.msg: Updated (thanks to Sander Devrieze) SVN Revision: 247
This commit is contained in:
parent
96cfe08558
commit
4b2919c207
17
ChangeLog
17
ChangeLog
@ -1,9 +1,26 @@
|
|||||||
|
2004-07-25 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/tls/: Library for TLS support (not completed)
|
||||||
|
|
||||||
|
* src/ejabberd_auth.erl: Now uses two LDAP connections
|
||||||
|
|
||||||
|
* src/ejabberd_c2s.erl: Return resource on get_presence request
|
||||||
|
(thanks to Mickael Remond)
|
||||||
|
|
||||||
|
* src/mod_configure2.erl: Bugfix (thanks to Sergei Golovan)
|
||||||
|
|
||||||
|
* src/msgs/ua.msg: New Ukrainian translation (thanks to usercard)
|
||||||
|
|
||||||
|
* src/msgs/nl.msg: Updated (thanks to Sander Devrieze)
|
||||||
|
|
||||||
2004-07-23 Alexey Shchepin <alexey@sevcom.net>
|
2004-07-23 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/eldap/eldap.erl: Bugfix
|
* src/eldap/eldap.erl: Bugfix
|
||||||
|
|
||||||
2004-07-13 Alexey Shchepin <alexey@sevcom.net>
|
2004-07-13 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* (all): ejabberd-0.7 released
|
||||||
|
|
||||||
* src/web/ejabberd_web_admin.erl: Better i18n support (thanks to
|
* src/web/ejabberd_web_admin.erl: Better i18n support (thanks to
|
||||||
Sergei Golovan)
|
Sergei Golovan)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
-define(VERSION, "0.6-alpha").
|
-define(VERSION, "0.8-alpha").
|
||||||
|
|
||||||
%-define(ejabberd_debug, true).
|
%-define(ejabberd_debug, true).
|
||||||
%-define(DBGFSM, true).
|
%-define(DBGFSM, true).
|
||||||
|
@ -70,7 +70,8 @@ init([]) ->
|
|||||||
ok;
|
ok;
|
||||||
ldap ->
|
ldap ->
|
||||||
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
||||||
eldap:start_link("ejabberd", LDAPServers, 389, "", "")
|
eldap:start_link("ejabberd", LDAPServers, 389, "", ""),
|
||||||
|
eldap:start_link("ejabberd_bind", LDAPServers, 389, "", "")
|
||||||
end,
|
end,
|
||||||
{ok, #state{}}.
|
{ok, #state{}}.
|
||||||
|
|
||||||
@ -326,7 +327,7 @@ check_password_ldap(User, Password) ->
|
|||||||
false ->
|
false ->
|
||||||
false;
|
false;
|
||||||
DN ->
|
DN ->
|
||||||
case eldap:bind("ejabberd", DN, Password) of
|
case eldap:bind("ejabberd_bind", DN, Password) of
|
||||||
ok ->
|
ok ->
|
||||||
true;
|
true;
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -686,8 +686,9 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
|
|||||||
|
|
||||||
Show = get_showtag(PresLast),
|
Show = get_showtag(PresLast),
|
||||||
Status = get_statustag(PresLast),
|
Status = get_statustag(PresLast),
|
||||||
|
Resource = StateData#state.resource,
|
||||||
|
|
||||||
Reply = {User, Show, Status},
|
Reply = {User, Resource, Show, Status},
|
||||||
{reply, Reply, StateName, StateData};
|
{reply, Reply, StateName, StateData};
|
||||||
|
|
||||||
handle_sync_event(_Event, _From, StateName, StateData) ->
|
handle_sync_event(_Event, _From, StateName, StateData) ->
|
||||||
|
@ -135,7 +135,7 @@ process_get({xmlelement, "access", Attrs, _SubEls}) ->
|
|||||||
{result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}};
|
{result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}};
|
||||||
process_get({xmlelement, "last", Attrs, _SubEls}) ->
|
process_get({xmlelement, "last", Attrs, _SubEls}) ->
|
||||||
case catch mnesia:dirty_select(
|
case catch mnesia:dirty_select(
|
||||||
last_activity, [{{last_activity, '_', '$1'}, [], ['$1']}]) of
|
last_activity, [{{last_activity, '_', '$1', '_'}, [], ['$1']}]) of
|
||||||
{'EXIT', _Reason} ->
|
{'EXIT', _Reason} ->
|
||||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||||
Vals ->
|
Vals ->
|
||||||
|
250
src/msgs/ua.msg
Normal file
250
src/msgs/ua.msg
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
% $Id$
|
||||||
|
|
||||||
|
% mod_configure.erl
|
||||||
|
{"DB Tables Configuration at ", "Конфігурація таблиць БД на "}.
|
||||||
|
{"Choose storage type of tables", "Оберіть тип збереження таблиць"}.
|
||||||
|
{"RAM copy", "ОЗУ"}.
|
||||||
|
{"RAM and disc copy", "ОЗУ та диск"}.
|
||||||
|
{"Disc only copy", "тільки диск"}.
|
||||||
|
{"Remote copy", "не зберігаеться локально"}.
|
||||||
|
{"Stop Modules at ", "Зупинка модулів на "}.
|
||||||
|
{"Choose modules to stop", "Оберіть модулі, які необхідно зупинити"}.
|
||||||
|
{"Start Modules at ", "Запуск модулів на "}.
|
||||||
|
{"Enter list of {Module, [Options]}", "Введіть список такого виду {Module, [Options]}"}.
|
||||||
|
{"List of modules to start", "Список завантажуваних модулів"}.
|
||||||
|
{"Backup to File at ", "Резервне копіювання в файл на "}.
|
||||||
|
{"Enter path to backup file", "Введіть шлях до резервного файла"}.
|
||||||
|
{"Path to File", "Шлях до файла"}.
|
||||||
|
{"Restore Backup from File at ", "Відновлення з резервної копії на "}.
|
||||||
|
{"Dump Backup to Text File at ", "Копіювання в текстовий файл на "}.
|
||||||
|
{"Enter path to text file", "Введіть шлях до текстового файла"}.
|
||||||
|
{"Import User from File at ", "Імпортування користувача з файла на "}.
|
||||||
|
{"Enter path to jabberd1.4 spool file", "Введіть шлях до файла зі спула jabberd1.4"}.
|
||||||
|
{"Import Users from Dir at ", "Імпортування користувача з директорії на "}.
|
||||||
|
{"Enter path to jabberd1.4 spool dir", "Введіть шлях до директорії спула jabberd1.4"}.
|
||||||
|
{"Path to Dir", "шлях до директорії"}.
|
||||||
|
{"Hostname Configuration", "Конфігурація назви хоста"}.
|
||||||
|
{"Choose host name", "Оберіть назву хоста"}.
|
||||||
|
{"Host name", "Назва хоста"}.
|
||||||
|
{"Access Control List Configuration", "Конфігурація списків управління доступом"}.
|
||||||
|
{"Access control lists", "Списки управління доступом"}.
|
||||||
|
{"Access Configuration", "Конфігурація доступа"}.
|
||||||
|
{"Access rules", "Правила доступу"}.
|
||||||
|
{"Remove Users", "Видалення користувачів"}.
|
||||||
|
{"Choose users to remove", "Оберіть користувачів, яких необхідно видалити"}.
|
||||||
|
{"Administration of ", "Адміністрування "}.
|
||||||
|
{"Action on user", "Дія над користувачем"}.
|
||||||
|
{"Edit Properties", "Змінити параметри"}.
|
||||||
|
{"Remove User", "Видалити коростувача"}.
|
||||||
|
|
||||||
|
% mod_disco.erl
|
||||||
|
{"Configuration", "Конфігурація"}.
|
||||||
|
{"Online Users", "Підключені користувачі"}.
|
||||||
|
{"All Users", "Всі коритстувачі"}.
|
||||||
|
{"Outgoing S2S connections", "Вихідні S2S-з`єднання"}.
|
||||||
|
{"To ~s", "До ~s"}.
|
||||||
|
{"From ~s", "Від ~s"}.
|
||||||
|
{"Running Nodes", "Рабочі вузли"}.
|
||||||
|
{"Stopped Nodes", "Зупинені вузли"}.
|
||||||
|
{"Host Name", "Назва хоста"}.
|
||||||
|
{"Access Control Lists", "Списки управління доступом"}.
|
||||||
|
{"Access Rules", "Правила доступу"}.
|
||||||
|
{"Remove Users", "Видалення користувачів"}.
|
||||||
|
{"DB", "БД"}.
|
||||||
|
{"Modules", "Модулі"}.
|
||||||
|
{"Start Modules", "Запуск модулів"}.
|
||||||
|
{"Stop Modules", "Зупинка модулів"}.
|
||||||
|
{"Backup Management", "Управління резервним копіюванням"}.
|
||||||
|
{"Import users from jabberd1.4 spool files", "Імпортування користувачів зі спулу jabberd1.4"}.
|
||||||
|
{"Backup", "Резервне копіювання"}.
|
||||||
|
{"Restore", "Відновлення з резервної копії"}.
|
||||||
|
{"Dump to Text File", "Копіювання в текстовий файл"}.
|
||||||
|
{"Import File", "Імпорт з файла"}.
|
||||||
|
{"Import Directory", "Імпорт з директорії"}.
|
||||||
|
|
||||||
|
% mod_register.erl
|
||||||
|
{"Choose a username and password to register with this server",
|
||||||
|
"Оберіь назву користувача та пароль для реєстрації на цьому сервері"}.
|
||||||
|
|
||||||
|
% mod_vcard.erl
|
||||||
|
{"Erlang Jabber Server\nCopyright (c) 2002-2004 Alexey Shchepin",
|
||||||
|
"Erlang Jabber Server\nCopyright (c) 2002-2004 Алексей Щепин"}.
|
||||||
|
{"ejabberd vCard module\nCopyright (c) 2003-2004 Alexey Shchepin",
|
||||||
|
"ejabberd vCard модуль\nCopyright (c) 2003-2004 Алексей Щепин"}.
|
||||||
|
{"You need an x:data capable client to search",
|
||||||
|
"Для пошуку необхідний x:data-сумісний кліент"}.
|
||||||
|
{"Search users in ", "Пошук користувачів в "}.
|
||||||
|
{"Fill in fields to search for any matching Jabber User",
|
||||||
|
"Заповніть поля для пошуку користувача Jabber"}.
|
||||||
|
{"Results of search in ", "Результати пошуку в "}.
|
||||||
|
|
||||||
|
{"User", "Користувач"}.
|
||||||
|
{"Full Name", "Повне ім`я"}.
|
||||||
|
{"Name", "Ім`я"}.
|
||||||
|
{"Middle Name", "По-батькові"}.
|
||||||
|
{"Family Name", "Фамілія"}.
|
||||||
|
{"Nickname", "Псевдонім"}.
|
||||||
|
{"Birthday", "День нарождення"}.
|
||||||
|
{"Country", "Країна"}.
|
||||||
|
{"City", "Місто"}.
|
||||||
|
{"email", "email"}.
|
||||||
|
{"Organization Name", "Назва организації"}.
|
||||||
|
{"Organization Unit", "Відділ организації"}.
|
||||||
|
|
||||||
|
% mod_pubsub/mod_pubsub.erl
|
||||||
|
{"ejabberd pub/sub module\nCopyright (c) 2003-2004 Alexey Shchepin",
|
||||||
|
"ejabberd pub/sub модуль\nCopyright (c) 2003-2004 Алексей Щепин"}.
|
||||||
|
|
||||||
|
% mod_muc/mod_muc.erl
|
||||||
|
{"You need an x:data capable client to register nickname",
|
||||||
|
"Для реєстрації псевдоніму необхідний x:data-сумісний кліент"}.
|
||||||
|
{"Nickname Registration at ", "Реєстрація псевдоніма на "}.
|
||||||
|
{"Enter nickname you want to register", "Введіть псевдонім, який ви хочете зареєструвати"}.
|
||||||
|
{"ejabberd MUC module\nCopyright (c) 2003-2004 Alexey Shchepin",
|
||||||
|
"ejabberd MUC модуль\nCopyright (c) 2003-2004 Алексей Щепин"}.
|
||||||
|
{"Only service administrators are allowed to send service messages",
|
||||||
|
"Тільки адміністратор сервісу може надсилати службові повідомлення"}.
|
||||||
|
{"Room creation is not allowed by service policy",
|
||||||
|
"Створювати конференцію не дозволяється політикою сервіса"}.
|
||||||
|
{"Conference room does not exist", "Конференція не існує"}.
|
||||||
|
{"Access denied by service policy", "Доступ зоборонений політикою сервіса"}.
|
||||||
|
{"You must fill in field \"nick\" in the form",
|
||||||
|
"Вам необхідно заповнити поле \"nick\" у формі"}.
|
||||||
|
{"Specified nickname is already registered", "Вказаний псевдонім вже зареєстрований"}.
|
||||||
|
|
||||||
|
% mod_muc/mod_muc_room.erl
|
||||||
|
{" has set the subject to: ", " встановив(ла) тему: "}.
|
||||||
|
{"You need an x:data capable client to configure room",
|
||||||
|
"Для конфігурування кімнати необхідний x:data-сумісний кліент"}.
|
||||||
|
{"Configuration for ", "Конфігурація "}.
|
||||||
|
{"Room title", "Назва кімнати"}.
|
||||||
|
{"Allow users to change subject?", "Дозволити користувачам змінювати тему?"}.
|
||||||
|
{"Allow users to query other users?",
|
||||||
|
"Дозволити iq-запити до користувачів?"}.
|
||||||
|
{"Allow users to send private messages?",
|
||||||
|
"Дозволити приватні повідомлення?"}.
|
||||||
|
{"Make room public searchable?", "Зробити кімнату видимою всім?"}.
|
||||||
|
{"Make participants list public?", "Зробити список участників видимим всім?"}.
|
||||||
|
{"Make room persistent?", "Зробити кімнату постійною?"}.
|
||||||
|
{"Make room moderated?", "Зробити кімнату модерованою?"}.
|
||||||
|
{"Default users as members?",
|
||||||
|
"Зробити користувачів участниками за замовчуванням?"}.
|
||||||
|
{"Make room members only?",
|
||||||
|
"Кімната тільки для зареєтрованых участників?"}.
|
||||||
|
{"Allow users to send invites?",
|
||||||
|
"Дозволити користувачам посилати запрошення?"}.
|
||||||
|
{"Make room password protected?", "Зробити кімнату захищеною паролем?"}.
|
||||||
|
{"Password", "Пароль"}.
|
||||||
|
{"Make room anonymous?", "Зробити кімнату анонімною?"}.
|
||||||
|
{"Enable logging?", "Включити журнал роботи?"}.
|
||||||
|
{"Only moderators and participants are allowed to change subject in this room",
|
||||||
|
"Тільки модератори та участники можуть змінювати тему в цій комнаті"}.
|
||||||
|
{"Only moderators are allowed to change subject in this room",
|
||||||
|
"Тільки модератори можуть змінювати тему в цій комнаті"}.
|
||||||
|
{"Visitors are not allowed to send messages to all occupants",
|
||||||
|
"Відвідувачам не дозволяється посилати повідомлення всім присутнім"}.
|
||||||
|
{"Only occupants are allowed to send messages to the conference",
|
||||||
|
"Тільки присутнім дозволяється посилати повідомленняя в конференцію"}.
|
||||||
|
{"It is not allowed to send normal messages to the conference",
|
||||||
|
"Не дозволяється посилати звичайні повідомленняя в конференцію"}.
|
||||||
|
{"It is not allowed to send private messages to the conference",
|
||||||
|
"Не дозволяється посилати приватні повідомлення в конференцію"}.
|
||||||
|
{"Improper message type", "Неправильний тип повідомлення"}.
|
||||||
|
{"Nickname is already in use by another occupant", "Псевдонім зайнятий кимось з присутніх"}.
|
||||||
|
{"Nickname is registered by another person", "Псевдонім зайнятий кимось іншим"}.
|
||||||
|
{"It is not allowed to send private messages of type \"groupchat\"",
|
||||||
|
"Не дозволяється посилати приватні повідомлення типу \"groupchat\""}.
|
||||||
|
{"Recipient is not in the conference room", "Адресата немає в конференції"}.
|
||||||
|
{"Only occupants are allowed to send queries to the conference",
|
||||||
|
"Тільки присутнім дозволяється відправляти запити в конференцію"}.
|
||||||
|
{"Queries to the conference members are not allowed in this room",
|
||||||
|
"Запити до користувачів в цій конференції зоборонені"}.
|
||||||
|
{"You have been banned from this room", "Вам заборонено входити в цю конференцію"}.
|
||||||
|
{"Membership required to enter this room", "В цю конференціию можуть входити тільки її члени"}.
|
||||||
|
{"Password required to enter this room", "Щоб зайти в цю конференцію, необхідний пароль"}.
|
||||||
|
{"Incorrect password", "Неправильний пароль"}.
|
||||||
|
{"Administrator privileges required", "Необхідні права адміністратора"}.
|
||||||
|
{"Moderator privileges required", "Необхідні права модератора"}.
|
||||||
|
{"JID ~s is invalid", "JID ~s недопустимий"}.
|
||||||
|
{"Nickname ~s does not exist in the room", "Псевдонім ~s в кімнаті відсутній"}.
|
||||||
|
{"Invalid affiliation: ~s", "Недопустимий ранг: ~s"}.
|
||||||
|
{"Invalid role: ~s", "Недопустима роль: ~s"}.
|
||||||
|
{"Owner privileges required", "Необхідні права власника"}.
|
||||||
|
{"private, ", "приватна, "}.
|
||||||
|
|
||||||
|
% mod_irc/mod_irc.erl
|
||||||
|
{"ejabberd IRC module\nCopyright (c) 2003-2004 Alexey Shchepin",
|
||||||
|
"ejabberd IRC модуль\nCopyright (c) 2003-2004 Алексей Щепин"}.
|
||||||
|
{"You need an x:data capable client to configure mod_irc settings",
|
||||||
|
"Для налагодження параметрів mod_irc необхідний x:data-сумісний кліент"}.
|
||||||
|
{"Registration in mod_irc for ", "Реєстрація в mod_irc для "}.
|
||||||
|
{"Enter username and encodings you wish to use for connecting to IRC servers",
|
||||||
|
"Введіть ім`я користувача та кодування, які будуть використовуватися при підключенні до IRC-серверів"}.
|
||||||
|
{"IRC Username", "Ім`я користувача IRC"}.
|
||||||
|
{"If you want to specify different encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\"}'. By default this service use \"~s\" encoding.", "Щоб вказати різні кодування для різних серверів IRC, заповніть список значеннями в форматі '{\"irc server\", \"encoding\"}'. За замовчуванням ця служба використовує кодування \"~s\"."}.
|
||||||
|
{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Приклад: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
|
||||||
|
{"Encodings", "Кодування"}.
|
||||||
|
|
||||||
|
% web/ejabberd_web_admin.erl
|
||||||
|
{"ejabberd administration", "Адміністрування ejabberd"}.
|
||||||
|
{"Users", "Користувачі"}.
|
||||||
|
{"Nodes", "Вузли"}.
|
||||||
|
{"Statistics", "Статистика"}.
|
||||||
|
{"ejabberd (c) 2002-2004 Alexey Shchepin", "ejabberd (c) 2002-2004 Алексей Щепин"}.
|
||||||
|
{"(raw)", "(необроблений формат)"}.
|
||||||
|
{"submitted", "відправлено"}.
|
||||||
|
{"bad format", "неправильний формат"}.
|
||||||
|
{"raw", "необроблений формат"}.
|
||||||
|
{"ejabberd access control lists configuration", "Конфігурація списків управління доступом ejabberd"}.
|
||||||
|
{"Delete Selected", "Видалити виділені"}.
|
||||||
|
{"Submit", "Відправити"}.
|
||||||
|
{"ejabberd access rules configuration", "Конфігурація правил доступу ejabberd"}.
|
||||||
|
{"~s access rule configuration", "Конфігурація правила доступу ~s"}.
|
||||||
|
{"ejabberd users", "Користувачі ejabberd"}.
|
||||||
|
{"ejabberd stats", "Статистика ejabberd"}.
|
||||||
|
{"Node not found", "Вузол не знайдено"}.
|
||||||
|
{"Add New", "Добавити"}.
|
||||||
|
{"Registered users", "Зареєстровані користувачі"}.
|
||||||
|
{"Authentificated users", "Аутентифіковані користувачі"}.
|
||||||
|
{"Online users", "Підключені користувачі"}.
|
||||||
|
{"Outgoing S2S servers", "Вихідні S2S-сервери"}.
|
||||||
|
{"Change Password", "Змінити пароль"}.
|
||||||
|
{"Connected Resources:", "Підключені ресурси:"}.
|
||||||
|
{"Password:", "Пароль:"}.
|
||||||
|
{"None", "Ні"}.
|
||||||
|
{"Node ", "Вузол "}.
|
||||||
|
{"DB Management", "Управління БД"}.
|
||||||
|
{"Listened Ports Management", "Управління відкритими портами"}.
|
||||||
|
{"Restart", "Перезапустити"}.
|
||||||
|
{"Stop", "Зупинити"}.
|
||||||
|
{"RPC call error", "Помилка визову RPC"}.
|
||||||
|
{"DB Tables at ", "Таблиці БД на "}.
|
||||||
|
{"Name", "Назва"}.
|
||||||
|
{"Storage Type", "Тип таблиці"}.
|
||||||
|
{"Size", "Розмір"}.
|
||||||
|
{"Memory", "Пам`ять"}.
|
||||||
|
{"Backup Management at ", "Управління резервним копіюванням на "}.
|
||||||
|
{"Store a backup in a file", "Зберігти резервну копію в файл"}.
|
||||||
|
{"OK", "Продовжити"}.
|
||||||
|
{"Restore a backup from a file", "Відновити резервну копію з файла"}.
|
||||||
|
{"Install a database fallback from a file", "Встановити базу даних для відновлення при слідуючому запуску"}.
|
||||||
|
{"Dump a database in a text file", "Копіювати базу даних в текстовий файл"}.
|
||||||
|
{"Restore a database from a text file", "Відновити базу даних з текстового файла"}.
|
||||||
|
{"Listened Ports at ", "Відкриті порти на "}.
|
||||||
|
{"~p statistics", "статистика вузла ~p"}.
|
||||||
|
{"Uptime", "Час роботи сервера"}.
|
||||||
|
{"CPU Time", "Процесорний час"}.
|
||||||
|
{"Transactions commited", "Транзакції завершені"}.
|
||||||
|
{"Transactions aborted", "Транзакції відмінені"}.
|
||||||
|
{"Transactions restarted", "Транзакції перезапущені"}.
|
||||||
|
{"Transactions logged", "Транзакції запротокольовані"}.
|
||||||
|
{"Port", "Порт"}.
|
||||||
|
{"Module", "Модуль"}.
|
||||||
|
{"Options", "Параметри"}.
|
||||||
|
{"Update", "Обновити"}.
|
||||||
|
{"Delete", "Видалити"}.
|
||||||
|
{"", ""}.
|
||||||
|
|
||||||
|
% Local Variables:
|
||||||
|
% mode: erlang
|
||||||
|
% End:
|
138
src/tls/tls.erl
Normal file
138
src/tls/tls.erl
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : tls.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose : Interface to openssl
|
||||||
|
%%% Created : 24 Jul 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(tls).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
-export([start/0, start_link/0, convert/3, test/0]).
|
||||||
|
|
||||||
|
%% Internal exports, call-back functions.
|
||||||
|
-export([init/1,
|
||||||
|
handle_call/3,
|
||||||
|
handle_cast/2,
|
||||||
|
handle_info/2,
|
||||||
|
code_change/3,
|
||||||
|
terminate/2]).
|
||||||
|
|
||||||
|
-define(SET_CERTIFICATE_FILE, 1).
|
||||||
|
-define(SET_ENCRYPTED_INPUT, 2).
|
||||||
|
-define(SET_DECRYPTED_OUTPUT, 3).
|
||||||
|
-define(GET_ENCRYPTED_OUTPUT, 4).
|
||||||
|
-define(GET_DECRYPTED_INPUT, 5).
|
||||||
|
|
||||||
|
-define(DECRYPTED_INPUT, 1).
|
||||||
|
-define(ENCRYPTED_OUTPUT, 2).
|
||||||
|
|
||||||
|
|
||||||
|
start() ->
|
||||||
|
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
ok = erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
|
||||||
|
Port = open_port({spawn, tls_drv}, [binary]),
|
||||||
|
Res = port_control(Port, ?SET_CERTIFICATE_FILE, "./ssl.pem" ++ [0]),
|
||||||
|
case Res of
|
||||||
|
[0] ->
|
||||||
|
%ets:new(iconv_table, [set, public, named_table]),
|
||||||
|
%ets:insert(iconv_table, {port, Port}),
|
||||||
|
{ok, Port};
|
||||||
|
[1 | Error] ->
|
||||||
|
{error, Error}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%%% --------------------------------------------------------
|
||||||
|
%%% The call-back functions.
|
||||||
|
%%% --------------------------------------------------------
|
||||||
|
|
||||||
|
handle_call(_, _, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_cast(_, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info({'EXIT', Pid, Reason}, Port) ->
|
||||||
|
{noreply, Port};
|
||||||
|
|
||||||
|
handle_info({'EXIT', Port, Reason}, Port) ->
|
||||||
|
{stop, {port_died, Reason}, Port};
|
||||||
|
handle_info(_, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
code_change(OldVsn, State, Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
terminate(_Reason, Port) ->
|
||||||
|
Port ! {self, close},
|
||||||
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
convert(From, To, String) ->
|
||||||
|
[{port, Port} | _] = ets:lookup(iconv_table, port),
|
||||||
|
Bin = term_to_binary({From, To, String}),
|
||||||
|
BRes = port_control(Port, 1, Bin),
|
||||||
|
binary_to_list(BRes).
|
||||||
|
|
||||||
|
|
||||||
|
test() ->
|
||||||
|
ok = erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
|
||||||
|
Port = open_port({spawn, tls_drv}, [binary]),
|
||||||
|
io:format("open_port: ~p~n", [Port]),
|
||||||
|
PCRes = port_control(Port, ?SET_CERTIFICATE_FILE, "./ssl.pem" ++ [0]),
|
||||||
|
io:format("port_control: ~p~n", [PCRes]),
|
||||||
|
{ok, ListenSocket} = gen_tcp:listen(1234, [binary,
|
||||||
|
{packet, 0},
|
||||||
|
{active, true},
|
||||||
|
{reuseaddr, true},
|
||||||
|
{nodelay, true}]),
|
||||||
|
io:format("listen: ~p~n", [ListenSocket]),
|
||||||
|
{ok, Socket} = gen_tcp:accept(ListenSocket),
|
||||||
|
io:format("accept: ~p~n", [Socket]),
|
||||||
|
loop(Port, Socket).
|
||||||
|
|
||||||
|
|
||||||
|
loop(Port, Socket) ->
|
||||||
|
receive
|
||||||
|
{tcp, Socket, Data} ->
|
||||||
|
%io:format("read: ~p~n", [Data]),
|
||||||
|
Res = port_control(Port, ?SET_ENCRYPTED_INPUT, Data),
|
||||||
|
%io:format("SET_ENCRYPTED_INPUT: ~p~n", [Res]),
|
||||||
|
|
||||||
|
DIRes = port_control(Port, ?GET_DECRYPTED_INPUT, Data),
|
||||||
|
%io:format("GET_DECRYPTED_INPUT: ~p~n", [DIRes]),
|
||||||
|
case DIRes of
|
||||||
|
[0 | In] ->
|
||||||
|
io:format("input: ~s~n", [In]);
|
||||||
|
[1 | DIError] ->
|
||||||
|
io:format("GET_DECRYPTED_INPUT error: ~p~n", [DIError])
|
||||||
|
end,
|
||||||
|
|
||||||
|
EORes = port_control(Port, ?GET_ENCRYPTED_OUTPUT, Data),
|
||||||
|
%io:format("GET_ENCRYPTED_OUTPUT: ~p~n", [EORes]),
|
||||||
|
case EORes of
|
||||||
|
[0 | Out] ->
|
||||||
|
gen_tcp:send(Socket, Out);
|
||||||
|
[1 | EOError] ->
|
||||||
|
io:format("GET_ENCRYPTED_OUTPUT error: ~p~n", [EOError])
|
||||||
|
end,
|
||||||
|
|
||||||
|
|
||||||
|
loop(Port, Socket);
|
||||||
|
Msg ->
|
||||||
|
io:format("receive: ~p~n", [Msg]),
|
||||||
|
loop(Port, Socket)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
188
src/tls/tls_drv.c
Normal file
188
src/tls/tls_drv.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <erl_driver.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define BUF_SIZE 1024
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ErlDrvPort port;
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
BIO *bio_read;
|
||||||
|
BIO *bio_write;
|
||||||
|
SSL *ssl;
|
||||||
|
} tls_data;
|
||||||
|
|
||||||
|
|
||||||
|
static ErlDrvData tls_drv_start(ErlDrvPort port, char *buff)
|
||||||
|
{
|
||||||
|
tls_data *d = (tls_data *)driver_alloc(sizeof(tls_data));
|
||||||
|
d->port = port;
|
||||||
|
d->ctx = NULL;
|
||||||
|
d->bio_read = NULL;
|
||||||
|
d->bio_write = NULL;
|
||||||
|
d->ssl = NULL;
|
||||||
|
|
||||||
|
return (ErlDrvData)d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tls_drv_stop(ErlDrvData handle)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
//XML_ParserFree(((tls_data *)handle)->parser);
|
||||||
|
driver_free((char *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SET_CERTIFICATE_FILE 1
|
||||||
|
#define SET_ENCRYPTED_INPUT 2
|
||||||
|
#define SET_DECRYPTED_OUTPUT 3
|
||||||
|
#define GET_ENCRYPTED_OUTPUT 4
|
||||||
|
#define GET_DECRYPTED_INPUT 5
|
||||||
|
|
||||||
|
#define DECRYPTED_INPUT 1
|
||||||
|
#define ENCRYPTED_OUTPUT 2
|
||||||
|
|
||||||
|
#define die_unless(cond, errstr) \
|
||||||
|
if (!(cond)) \
|
||||||
|
{ \
|
||||||
|
rlen = strlen(errstr) + 1; \
|
||||||
|
*rbuf = driver_alloc(rlen); \
|
||||||
|
*rbuf[0] = 1; \
|
||||||
|
strncpy(*rbuf + 1, errstr, rlen - 1); \
|
||||||
|
return rlen; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int tls_drv_control(ErlDrvData handle,
|
||||||
|
unsigned int command,
|
||||||
|
char *buf, int len,
|
||||||
|
char **rbuf, int rlen)
|
||||||
|
{
|
||||||
|
tls_data *d = (tls_data *)handle;
|
||||||
|
int res;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case SET_CERTIFICATE_FILE:
|
||||||
|
d->ctx = SSL_CTX_new(SSLv23_server_method());
|
||||||
|
die_unless(d->ctx, "SSL_CTX_new failed");
|
||||||
|
|
||||||
|
res = SSL_CTX_use_certificate_file(d->ctx, buf, SSL_FILETYPE_PEM);
|
||||||
|
die_unless(res > 0, "SSL_CTX_use_certificate_file failed");
|
||||||
|
|
||||||
|
res = SSL_CTX_use_PrivateKey_file(d->ctx, buf, SSL_FILETYPE_PEM);
|
||||||
|
die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed");
|
||||||
|
|
||||||
|
res = SSL_CTX_check_private_key(d->ctx);
|
||||||
|
die_unless(res > 0, "SSL_CTX_check_private_key failed");
|
||||||
|
|
||||||
|
d->ssl = SSL_new(d->ctx);
|
||||||
|
die_unless(d->ssl, "SSL_new failed");
|
||||||
|
|
||||||
|
d->bio_read = BIO_new(BIO_s_mem());
|
||||||
|
d->bio_write = BIO_new(BIO_s_mem());
|
||||||
|
|
||||||
|
SSL_set_bio(d->ssl, d->bio_read, d->bio_write);
|
||||||
|
|
||||||
|
SSL_set_accept_state(d->ssl);
|
||||||
|
break;
|
||||||
|
case SET_ENCRYPTED_INPUT:
|
||||||
|
BIO_write(d->bio_read, buf, len);
|
||||||
|
break;
|
||||||
|
case SET_DECRYPTED_OUTPUT:
|
||||||
|
res = SSL_write(d->ssl, buf, len);
|
||||||
|
break;
|
||||||
|
case GET_ENCRYPTED_OUTPUT:
|
||||||
|
size = BUF_SIZE + 1;
|
||||||
|
rlen = 1;
|
||||||
|
*rbuf = driver_alloc(size);
|
||||||
|
*rbuf[0] = 0;
|
||||||
|
while ((res = BIO_read(d->bio_write, *rbuf + rlen, BUF_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
printf("%d bytes of encrypted data read from state machine\r\n", res);
|
||||||
|
|
||||||
|
rlen += res;
|
||||||
|
size += BUF_SIZE;
|
||||||
|
*rbuf = driver_realloc(*rbuf, size);
|
||||||
|
}
|
||||||
|
return rlen;
|
||||||
|
case GET_DECRYPTED_INPUT:
|
||||||
|
if (!SSL_is_init_finished(d->ssl))
|
||||||
|
{
|
||||||
|
printf("Doing SSL_accept\r\n");
|
||||||
|
res = SSL_accept(d->ssl);
|
||||||
|
if (res == 0)
|
||||||
|
printf("SSL_accept returned zero\r\n");
|
||||||
|
if (res < 0)
|
||||||
|
die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
|
||||||
|
"SSL_accept failed");
|
||||||
|
} else {
|
||||||
|
size = BUF_SIZE + 1;
|
||||||
|
rlen = 1;
|
||||||
|
*rbuf = driver_alloc(size);
|
||||||
|
*rbuf[0] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while ((res = SSL_read(d->ssl, *rbuf + rlen, BUF_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
printf("%d bytes of decrypted data read from state machine\r\n",res);
|
||||||
|
rlen += res;
|
||||||
|
size += BUF_SIZE;
|
||||||
|
*rbuf = driver_realloc(*rbuf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res < 0)
|
||||||
|
{
|
||||||
|
int err = SSL_get_error(d->ssl, res);
|
||||||
|
|
||||||
|
if (err == SSL_ERROR_WANT_READ)
|
||||||
|
{
|
||||||
|
printf("SSL_read wants more data\r\n");
|
||||||
|
//return 0;
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
return rlen;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == SET_ENCRYPTED_INPUT || command == SET_DECRYPTED_OUTPUT)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*rbuf = driver_alloc(1);
|
||||||
|
*rbuf[0] = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ErlDrvEntry tls_driver_entry = {
|
||||||
|
NULL, /* F_PTR init, N/A */
|
||||||
|
tls_drv_start, /* L_PTR start, called when port is opened */
|
||||||
|
tls_drv_stop, /* F_PTR stop, called when port is closed */
|
||||||
|
NULL, /* F_PTR output, called when erlang has sent */
|
||||||
|
NULL, /* F_PTR ready_input, called when input descriptor ready */
|
||||||
|
NULL, /* F_PTR ready_output, called when output descriptor ready */
|
||||||
|
"tls_drv", /* char *driver_name, the argument to open_port */
|
||||||
|
NULL, /* F_PTR finish, called when unloaded */
|
||||||
|
NULL, /* handle */
|
||||||
|
tls_drv_control, /* F_PTR control, port_command callback */
|
||||||
|
NULL, /* F_PTR timeout, reserved */
|
||||||
|
NULL /* F_PTR outputv, reserved */
|
||||||
|
};
|
||||||
|
|
||||||
|
DRIVER_INIT(tls_drv) /* must match name in driver_entry */
|
||||||
|
{
|
||||||
|
OpenSSL_add_ssl_algorithms();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
return &tls_driver_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user