]> granicus.if.org Git - ejabberd/commitdiff
* src/tls/: Library for TLS support (not completed)
authorAlexey Shchepin <alexey@process-one.net>
Sun, 25 Jul 2004 21:27:56 +0000 (21:27 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Sun, 25 Jul 2004 21:27:56 +0000 (21:27 +0000)
* 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

ChangeLog
src/ejabberd.hrl
src/ejabberd_auth.erl
src/ejabberd_c2s.erl
src/mod_configure2.erl
src/msgs/ua.msg [new file with mode: 0644]
src/tls/tls.erl [new file with mode: 0644]
src/tls/tls_drv.c [new file with mode: 0644]

index 2ae320d3b08bc7cb3e971ceb8b39074f3dd65f1a..2e5465fb5fad98b88f72cbd0e500a9fc11adcdf2 100644 (file)
--- a/ChangeLog
+++ b/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>
 
        * src/eldap/eldap.erl: Bugfix
 
 2004-07-13  Alexey Shchepin  <alexey@sevcom.net>
 
+       * (all): ejabberd-0.7 released
+
        * src/web/ejabberd_web_admin.erl: Better i18n support (thanks to
        Sergei Golovan)
 
index 5a6d391f989db1e3960831bb788356ea0ed5a2ca..249818d60a9a5039ceb7bf2f02cc047fa7fb8c88 100644 (file)
@@ -6,7 +6,7 @@
 %%% Id      : $Id$
 %%%----------------------------------------------------------------------
 
--define(VERSION, "0.6-alpha").
+-define(VERSION, "0.8-alpha").
 
 %-define(ejabberd_debug, true).
 %-define(DBGFSM, true).
index fc239680ba8f53d126e189f5eb9125447a3312cf..c697e8b73c9cccc170ea78313fdb614ced8eda4d 100644 (file)
@@ -70,7 +70,8 @@ init([]) ->
            ok;
        ldap ->
            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,
     {ok, #state{}}.
 
@@ -326,7 +327,7 @@ check_password_ldap(User, Password) ->
        false ->
            false;
        DN ->
-           case eldap:bind("ejabberd", DN, Password) of
+           case eldap:bind("ejabberd_bind", DN, Password) of
                ok ->
                    true;
                _ ->
index 8b10d064d6bd5cdba4098d2a5707336993a769c2..25de839e9a4c3ddeb6220a68222b557637374349 100644 (file)
@@ -686,8 +686,9 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
 
     Show = get_showtag(PresLast),
     Status = get_statustag(PresLast),
+    Resource = StateData#state.resource,
 
-    Reply  = {User, Show, Status},
+    Reply = {User, Resource, Show, Status},
     {reply, Reply, StateName, StateData};
 
 handle_sync_event(_Event, _From, StateName, StateData) ->
index 58eb387a44634512e561543c3f90823bdc6739e3..d22d344e4e6883eb147116c65adf9a81f52a7238 100644 (file)
@@ -135,7 +135,7 @@ process_get({xmlelement, "access", Attrs, _SubEls}) ->
     {result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}};
 process_get({xmlelement, "last", Attrs, _SubEls}) ->
     case catch mnesia:dirty_select(
-                last_activity, [{{last_activity, '_', '$1'}, [], ['$1']}]) of
+                last_activity, [{{last_activity, '_', '$1', '_'}, [], ['$1']}]) of
        {'EXIT', _Reason} ->
            {error, ?ERR_INTERNAL_SERVER_ERROR};
        Vals ->
diff --git a/src/msgs/ua.msg b/src/msgs/ua.msg
new file mode 100644 (file)
index 0000000..2837071
--- /dev/null
@@ -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:
\ No newline at end of file
diff --git a/src/tls/tls.erl b/src/tls/tls.erl
new file mode 100644 (file)
index 0000000..d444bb7
--- /dev/null
@@ -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.
+
+
diff --git a/src/tls/tls_drv.c b/src/tls/tls_drv.c
new file mode 100644 (file)
index 0000000..23d42b4
--- /dev/null
@@ -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;
+}
+
+