- Распределенная авторизация или не только авторизация, XMan, 01:30 , 30-Июл-03 (1)
Отправка данных по TCP:send(сокет, ссылка_на_данные, размер_данных_в_байтах, флаги); Прием данных по TCP: recv(сокет, ссылка_на_память_для_данных, размер_принимаемых_данных_в_байтах, флаги); Вместо флагов обычно используется "0". Рекомендуется обратить внимание еще и на функции poll и select. А так же почитать умную книжку "Программирование TCP/IP". Автор, кажись, некто Стивенсон. Точно не скажу - под рукой сейчас нет :) Короче, man : socket, fcntl, bind, listen, accept, connect, send, recv, sendto, recvfrom, poll, select, shutdown, close - Распределенная авторизация или не только авторизация, asso, 12:03 , 30-Июл-03 (2)
Посылать и получать - send и recv или sendto и recvfrom. В манах они хорошо описаны, в книгах не хуже. Внимательно смотри на все что касается сигналов, это пригодится в будущем.Теперь определимся с терминами. Авторизация - это проверка полномочий (прав доступа). Судя по вопросу, до проблем авторизации тебе еще далеко, тебе надо реализовать протокол обмена данными. Рассматривай сетевое соединение как трубу, через которую передаются данные. В один конец трубы запихали байт, из другой трубы он вылез. Конечно, пихать данные по одному байту крайне не эффективно, лучше посылать данные блоками. Тут подстерегает коварная ошибка: при использовании TCP если ты отправил блок, скажем, из 100 байт, это не значит что на другой стороне recv() получит сразу 100 байт. Он может получить, например, сначала 10, а потом остальные 90, а может сразу 200 (если захватит кусок от предыдущей или последующей порции данных). Тебе надо изобрести протокол, по которому будут общаться клиент и сервер. Например, сервер B может послать строку "DATA BEGIN" с переводом строки на конце, затем послать данные в текстовом виде, так же разделенные символом перевода строки, потом "DATA END" как знак того, что данные окончились. Сервер A после приема всех данных может ответить, например, строчкой "RESULT: 47", передав таким способом результат. Протокол полностью зависит от твоих целей и задач. Есть ошибка, которую любят совершать новички: НЕЛЬЗЯ передавать по сети структуры. Структуры могут по-разному выравниваться разными компиляторами, на разных компьютерах могут быть разные размеры слов и разный порядок слов в байте. Передавать любые бинарные данные по сети надо с большой остороностью. Если все это кажется сложным, используй более высокоуровневые библиотеки, которые возьмут все заботы на себя. Например, какой-нибудь RPC или CORBA. Последняя не так сложна, как это может сначала показаться. Простые вещи в CORBA реализуются достаточно просто, но нет предела усложнению.
- Распределенная авторизация или не только авторизация, ziben, 12:41 , 30-Июл-03 (3)
Спасибо за ответ. > Судя по вопросу, до проблем авторизации тебе еще далеко, тебе >надо реализовать протокол обмена данными. Именно так. Я уже сделал авторизацию, но потом оказалось что база пользователей лежит на другом сервере. Теперь вот думаю как это реализовать. >Тебе надо изобрести протокол, по которому будут общаться клиент и сервер. Например, >сервер B может послать строку "DATA BEGIN" с переводом строки на >конце, затем послать данные в текстовом виде, так же разделенные символом >перевода строки, потом "DATA END" как знак того, что данные окончились. > Сервер A после приема всех данных может ответить, например, строчкой >"RESULT: 47", передав таким способом результат. Протокол полностью зависит от >твоих целей и задач. Мне то в принципе нужно что бы так: в одну сторону $login + $passwd, обратно "да-нет"+$users_alias+$email... и все, но похоже в реализации это выглядит гораздо сложнее :)>Если все это кажется сложным, используй более высокоуровневые библиотеки, которые возьмут все >заботы на себя. Например, какой-нибудь RPC или CORBA. Последняя не >так сложна, как это может сначала показаться. Простые вещи в CORBA >реализуются достаточно просто, но нет предела усложнению. Хм... нужно поглядеть что за Корба такая... может действительно с ее помощью что-то придумается
- Распределенная авторизация или не только авторизация, ziben, 13:26 , 30-Июл-03 (4)
>>Если все это кажется сложным, используй более высокоуровневые библиотеки, которые возьмут все >>заботы на себя. Например, какой-нибудь RPC или CORBA. Последняя не >>так сложна, как это может сначала показаться. Простые вещи в CORBA >>реализуются достаточно просто, но нет предела усложнению. >Хм... нужно поглядеть что за Корба такая... может действительно с ее помощью >что-то придумается Поглядел... похоже это типа из Агромной пушки по мелкому воробью :)
- Распределенная авторизация или не только авторизация, asso, 14:12 , 30-Июл-03 (5)
>Именно так. Я уже сделал авторизацию, но потом оказалось что база пользователей >лежит на другом сервере. Теперь вот думаю как это реализовать. Если нужно сделать правильно, то надо что-то вроде Kerberos. Популярно о принципах лежащих в его основе рассказывается здесь: http://web.mit.edu/kerberos/www/dialogue.html >Мне то в принципе нужно что бы так: в одну сторону $login >+ $passwd, обратно "да-нет"+$users_alias+$email... и все, но похоже в реализации это >выглядит гораздо сложнее :)
Лущше $password не посылать. Логинящийся посылает $login, ему в ответ $random_string. Логинящийся посылает MD5($random_string . $password). Сервер проделывает то же самое, и если результат совпал то продолжает диалог иначе разрывает соединение.
- Распределенная авторизация или не только авторизация, ziben, 14:28 , 30-Июл-03 (6)
>Лущше $password не посылать. Логинящийся посылает $login, ему в ответ $random_string. > Логинящийся посылает MD5($random_string . $password). Сервер проделывает то же самое, >и если результат совпал то продолжает диалог иначе разрывает соединение. вот именно в этом и есть загвоздка - пока я не пойму КАК организовать вот это "передал строку - получил строку". А насчет передавать пароль или его крипт - это уже детали. причем не шибко важные, ибо все это вертится во внутренней сети, и хаккеров пока не предвидится, юзеры MS Word с трудом осилили, им не до взлома :)
- Распределенная авторизация или не только авторизация, konst, 19:09 , 30-Июл-03 (7)
>>Лущше $password не посылать. Логинящийся посылает $login, ему в ответ $random_string. >> Логинящийся посылает MD5($random_string . $password). Сервер проделывает то же самое, >>и если результат совпал то продолжает диалог иначе разрывает соединение. >вот именно в этом и есть загвоздка - пока я не пойму >КАК организовать вот это "передал строку - получил строку". >А насчет передавать пароль или его крипт - это уже детали. причем >не шибко важные, ибо все это вертится во внутренней сети, и >хаккеров пока не предвидится, юзеры MS Word с трудом осилили, им >не до взлома :) Не проще ли вместо текстовой БД пользовать нормальную (e.g. Postgres,MySQL). С ней не будет проблем соединится по IP-host,login,password
- Распределенная авторизация или не только авторизация, ziben, 20:06 , 30-Июл-03 (8)
>Не проще ли вместо текстовой БД пользовать нормальную (e.g. Postgres,MySQL). С ней >не будет проблем соединится по IP-host,login,password Нет, не проще: база уже давно работает, переписывать базу - это жуткое дело, ибо она используется еще рядом других задач. Эх, если б можно было MySQL базу заюзать, разве весь этот сыр-бор я поднимал? :(
- Распределенная авторизация или не только авторизация, XMan, 21:42 , 30-Июл-03 (9)
Короче. Делается всё элементарно - ищется модуль для системной библиотеки с названием, типа nss-mysql (для постгреса такой есть), ставится в систему, строится на предмет сервера и таблиц и вообще забывается про то, как кто где авторизуется.Серьезный минус только один - нужно заставить PAM при создании пользователя шифровать пароль и засылать его на SQL-сервер. Ручной метод "втупую" - "adduser xxx; passwd xxx", заглядываем в /etc/shadow, берем оттуда пароль, сами запросом втыкаем его в нужную таблицу, "userdel xxx; rm -rf /home/xxx". Плюсы: a) в /etc/passwd, /etc/group и /etc/shadow никаких ссылок на пользователей нет - всё лежит в базе; б) пароли от запрашивающей программы никуда не передаются - от сервера поступает пароль в зашифрованном виде в соответствии с системой, в которой его шифровали (в линухе в последнее время обычно MD5). То есть открытые пароли по сети вообще не бегают; в) данные по соответствию uid/gid символьным именам пользователей и групп доступны любой программе. Если не использовать nss, то половина серверных программ вообще работать не будет. Например, почтовые сервисы; г) имеется масса потенциальных возможностей, которых нет в стандартных средствах *nix. Я пол-года назад почти дописал сетевую авторизации со своим протоколом (дабы отвязать клиента от конкретной SQL-базы вообще - к ней привязана только серверная часть) с использованием механизма NSS и базы PostgreSQL. Отлично работал. За основу клинетской части был взят тот самый nss-pgsql и капитально переписан. Сейчас потихоньку переделываю всё это хозяйство - сервер перевел на потоки с порционным созданием в зависимости от нагрузки (аля NetWare), наворотил конфигурацию (в принципе, можно создавать группы в группах, чего нельзя делать стандартными средствами *nix), имеется возможность раздавать свои данные разным сервисам (например, зачем команде "ls -l" посылать пароль, если ей нужно только имя пользователя и группы узнать) на разных машинах, имеется возможность кеширования на стороне клиента и на стороне сервера (на случай частых запросов одного и того же; например, "ls -l ~/"). Есть некоторые мысли по поводу защиты от DoS-атак. Еще некоторые улучшения будут. Планирую в ближашие пару месяцев таки добить это дело и пустить в работу на офисе, если времени будет достаточно. А то совсем загрузили фигней всякой :)
- Распределенная авторизация или не только авторизация, ziben, 11:12 , 31-Июл-03 (11)
>Серьезный минус только один - нужно заставить PAM при создании пользователя шифровать >пароль и засылать его на SQL-сервер. Ручной метод "втупую" - "adduser >xxx; passwd xxx", заглядываем в /etc/shadow, берем оттуда пароль, сами Еще раз уточняю: _без_ SQL нужно, база хранится на втором сервере в текстовом формате! Вот я хотел написать на перле некую двойку: одна часть на веб-сервере из формы получает имя-пароль, обращается ко второй части (на другой сервер) и каким-то макаром (вопрос безопасности пока не рассматриваю) вторая часть сравнивает с текстовой базой. Собственно сам процесс авторизации - это отлажено для случая, если база юзеров лежит на одной машине с веб-сервером. Теперь нужно изобрести как это разнести на разные машины. Причем, средства ограничены - на веб-сервере провайдер никаких наворотов ставить не согласится (поэтому все прийдется делать обычным перловым скриптом), да и на втором сервере тоже ничего в принципе воротить нельзя, тоже максимум перловый скрипт, или может сишная программа небольшая. Буду очень признателен если у кого-то найдется пример типа: две простенькие программки: (1) слушает непрерывно и в случает получения строки отвечает отправкой другой строки, (2) отправила строку и получила ответную. И все. Да, желательно все это на Perl. Или крайний случай: программа (1) - Си, (2) - перл Заранее признателен, Константин
- а что тебе мешает посмотреть на исходники того же апача?, йцукенг, 04:46 , 05-Авг-03 (12)
или thttpd? да и на перле много демонов написано, webmin, например
- а что тебе мешает посмотреть на исходники того же апача?, ziben, 11:46 , 05-Авг-03 (13)
>да и на перле много демонов написано, webmin, например хм, webmin нужно поглядеть, ща займусь. Хотя уже частично решил проблему, теперь другие грабли: отправляю строку, сервер ее получает (могу ее в переменную загнать и обрабатывать), сервер отвечает что-то, клиентский скрипт получает, могу вывести на print, а вот в переменную - не могу, не вижу ее снаружи: #!/usr/bin/perl use Socket; $port = 4000; $them = '192.168.1.100'; $SIG{'Int'} = 'dokill'; sub dokill { kill 9, $child if $child; } #Нужно отправить функции строку, в ответ получить другую. $zapros = "test\n"; $otvet=autoriz($zapros); print "Otvet = $otvet\n\n"; sub autoriz {
chop($hostname = `hostname`); ($name, $aliases, $proto) = getprotobyname('tcp'); ($name, $aliases, $port) = getservbyname($port,'tcp') unless $port =~ /^\d+$/; print "Using port $port to connect to server on host $them...\n\n\n"; ($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname); ($name, $aliases,$type,$len,$thataddr) = gethostbyname($them); if (socket(S,AF_INET, SOCK_STREAM, $proto)) { # print "Socket creation succeeded.\n"; } else { die $!; } $sockaddr = 'S n a4 x8'; $this = pack($sockaddr, AF_INET, 0, $thisaddr); $that = pack($sockaddr, AF_INET, $port, $thataddr); if (bind(S, $this)) { # print "Bind succeeded.\n"; } else { die $!; } # This is similar to the 'accept' in the server, except the server is # waiting for a call and we're actively initiating the conversation. # 'connect' connects our socket to the server's socket on the other end. if (connect(S, $that)) { # print "Connect succeeded.\n"; } else { die $!; }
# Force our socket to flush output immediately after a print select(S); $| = 1; select(STDOUT); if ($child = fork) { #Отправляю серверу строку - он ее получает send (S, $_[0], 0); # Sleep for 3 seconds then... sleep 3; } else { # Вот тут планирую ответ сервера в переменную запихнуть while (<S>) { #сервер получил строку "test" и ответил "OK" print "Server: $_"; # на экране вижу Server: OK $tempper="$_\n\n"; } } return "Repl: $tempper\n"; #А получаю в ответ из функции только "Repl:", т.е. $tempper = "" } и где ж тут грабли то?
- ошибка тута, йцукенг, 11:01 , 08-Авг-03 (20)
ошибка здесь: $tempper="$_\n\n"; делай, например, так: $tempper=$tempper."$_\n\n"; а то у тебя в цикле результат не накапливается
- ошибка тута, ziben, 11:11 , 08-Авг-03 (21)
>ошибка здесь: >$tempper="$_\n\n"; >делай, например, так: >$tempper=$tempper."$_\n\n"; >а то у тебя в цикле результат не накапливается беда не в том, что не накапливался, а в том, что он принципиально не возвращался из процедуры :) но уже найден простой вариант#!/usr/bin/perl -w # gethttp.pl use Socket; use strict; @main::otvet=autoriz(); print @main::otvet; sub autoriz { my $serveraddr="127.0.0.1"; my $sock_name = GetSockName($serveraddr,4000) or die "Couldn't convert $serveraddr into an Internet address: $!\n"; socket(CONN,PF_INET,SOCK_STREAM,getprotobyname('tcp')); connect(CONN,$sock_name) or die "Couldn't' connect to $serveraddr: $!\n"; select(CONN); $|=1; select(STDOUT); print CONN "1\n\n"; my @body = <CONN>; close(CONN); return @body; } sub GetSockName{ my ($nm,$pt) = @_; return undef unless defined($nm); return undef unless defined($pt); return undef unless $nm = gethostbyname($nm); return sockaddr_in($pt,$nm); }
- Распределенная авторизация или не только авторизация, Bah, 03:53 , 08-Авг-03 (18)
> перловый скрипт, или может сишная программа небольшая. >Буду очень признателен если у кого-то найдется пример типа: две простенькие программки: >(1) слушает непрерывно и в случает получения строки отвечает отправкой другой строки, >(2) отправила строку и получила ответную. И все. Попробую вырезать из своего демона... use IO::Socket; use strict; my $client = ""; my $bindaddr = "127.0.0.1"; my $serverport = 12345; while (1) { get_input(); } sub startsrv { my $server=IO::Socket::INET->new(LocalAddr=>$bindaddr, LocalPort=>$serverport, Type=>SOCK_STREAM, Reuse=>1, Listen=>10) or die "Couldn't be a TCP server on port $serverport"; return $server; } sub getinput { while ($client = $server->accept()) { die "Can't fork!: $@" if (!defined (my $child=fork())); if ($child == 0) { # find client ip address my $haddr = getpeername($client); my ($port,$iaddr) = unpack_sockaddr_in($haddr); my $in_ip = inet_ntoa($iaddr); # Send "wellcome banner" to CLIENT $client->print("Wellcome to example TCP server (Your ip: <$in_ip>)\n"); my $cmd = $client->getline; # Recive incoming string from CLIENT # Do something with recieved string ..... # Send some datas to CLIENT $client->print("....\n"); close $client; exit 0; } else { close $client; } } } читай perldoc IO:Socket; для клиента все с точностью до наоборот. Ну и форкаться не надо, сомо собой... :-)
- Распределенная авторизация или не только авторизация, Gelin, 07:16 , 08-Авг-03 (19)
Насчет шифрования паролей: RFC 2138 - Radius
- Распределенная авторизация или не только авторизация, chepil, 07:13 , 31-Июл-03 (10)
Смотри сюда https://www.opennet.ru/openforum/vsluhforumID9/1913.html Тут то что тебе нужно слева оракл, справа pam (это тебе не надо) а посередине сокет сервер и сокет клиент которые пароль шифрованный гоняют туда сюда. Реализация с ошибками, есть у меня без ошибок, уже исправил. Попробуй эту, если понравится, скину новую версию
|