Ключевые слова:security, pop3, (найти похожие документы)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 03 Oct 98 05:25:46
Subj : Re: pop3d-1.005l
________________________________________________________________________________
From: Solar Designer <[email protected]>
DENis Tchapov <[email protected]> wrote:
> Уважаемый All, пpосветите плиз, какие потенциальные и pеальные дыpы есть
> в сабже, насколько они опасны ? Какой POP3 демон поpекомендуете
> пользовать вообще ? Заpанее спасибо.
(Уфф сколько thread'ов развелось про pop3, даже читать неудобно...)
Hасчет subj -- посмотрел я на его код еще раз (диагноз "в морг" был
поставлен уже давно) вчера -- т.к. подумываю делать свой pop3 демон.
Замечены следующие вещи на тему security (это вовсе _не_ audit, просто
случайно замеченное в процессе изучения структуры программы):
1. Автор не знает семантики strncpy/strncat. Соответственно, в первом
случае может где-то не оказаться нуля на конце, а во втором переполнение
на один байт.
2. Есть sscanf(buf, "%s", ptr), где ptr сам указывает в какое-то место
в buf (это я упрощенно говорю, там оно по дороге проходит через два
вызова функций, etc., но результирующий вызов получается такой). Как
я понимаю, поведение такой конструкции не определено и зависит от версии
libc. У меня с libc 5.4.38 оказалось не exploitable (специально вставил
туда лишний printf, собрал, временно поставил дома, и попробовал). Так
что -- потенциальная проблема. И говорит об общем качестве кода (как
будто #1 было недостаточно).
3. Прилагающийся скрипт (rm_stale.sh или как-то так зовется) -- одна
сплошная дыра. Там трудно найти строку без проблемы. А они советуют
его на cron под root'ом вешать.
4. Hу и, конечно, как и большинство других pop3 демонов, делает кучу
всего под root'ом.
Это так, что сейчас вспомнилось из случайно замеченного.
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 03 Oct 98 06:22:14
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Alex Korchmar <[email protected]> wrote:
> SD> Э, нет, за пару дней ты (как и кто угодно другой, в том числе и я) ничего
> SD> сильно лучше не напишешь. Конкретно, для security нужна другая структура
> напишет-напишет. Ты просто не видел, похоже, обсуждаемых уродцев.
> Соберешься заглянуть - запасись пакетиком. Меня чуть не стошнило.
Видел, а вчера еще раз специально посмотрел, прежде, чем делать свое (хотя,
возможно, и зря смотрел). ;-)
> То есть даже просто нормальный, без специфических извратов с секьюрити, но
> и без грубых ляпов, типа повсеместного использования статических буферов,
> помноженных на собственный ублюдочный memory manager, делающий невозможным
> отследить копирование в эти буферы - уже на порядок лучше.
Hу да, но, если уж я буду делать, то делать _хорошо_, а не просто лучше
дерьма. ;-) Пока есть такие мысли:
С переключением uid'ов выходит как-то очень непросто. Можно, конечно, все
время работать с gid=mail, но я не хочу, недостаточно безопасно. Получается,
что надо что-то в таком духе:
1. Старт под рутом.
2. Сам pop3 протокол (парсинг команд) -- под отдельным юзером (uid=pop3),
как минимум в состоянии auth (а может и дальше тоже, все равно тот же код).
3. Проверка пароля (root или gid=shadow).
4. Работа с mailbox'ом юзера -- под его uid'ом.
5. Работа с сохраненной копией (вообще-то, только ее создание и удаление,
остальное можно и через открытый fd из-под кого угодно) -- gid=mail или root.
Здесь пункт 5 будет нужен не во всех сессиях, при эффективной реализации.
Hо в некоторых случаях без него никак.
Так вот, остается вопрос -- пользовать ли saved ids (и рисковать всем
root'ом в случае buffer overflows), или придумывать еще какой-то свой
протокол для взаимодействия частей pop3 демона, работающих полностью
под разными uid'ами. Второй вариант сложнее, но IMHO предпочтительнее.
Также, желательно будет временами проходить через лишний exec() дабы
прочистить address space от остатков shadow после вызовов libc. Иначе
делать setuid под самого юзера будет на некоторых системах (не Linux,
а, например, Solaris до 2.6 не включительно) небезопасно из-за ptrace.
Теперь, что касается эффективности, есть такая идея (не без недостатков,
так что подлежит обсуждению):
1. После auth:
1.1. Залочить mailbox.
1.2. Запомнить его timestamp, размер.
1.3. Разобрать содержимое, сохраняя все нужное (размеры мессаг, etc) в
памяти, и одновременно считая md5sum (вернее, аналог оного, тут есть
свои идеи) всего mailbox'а; часто хеши все равно нужны для UIDL.
1.4. Дождаться начала следующей секунды от timestamp'а (если этого
еще не произошло).
1.5. Снять lock.
2. При каждой команде pop3, требующей доступ к файлу:
2.1. Залочить mailbox.
2.2. Если timestamp не изменился -- вперед без тормозов.
2.3. Иначе пересчитать md5sum начала файла (до старого размера).
2.4. Если не изменился -- вперед, но мы уже слегка тормознули, жаль.
2.5. Если изменился -- отправить pop3 клиент нафиг (либо -ERR, либо
просто закрыть TCP соединение), без сохранения изменений (таких как
DELE) в mailbox'е -- такое поведение определено RFC 1939, все честно.
2.6. Куда бы мы ни пошли, после операции, разумеется, снять лок.
3. В конце сессии, после захода в состояние update, есть случаи, когда
без временной копии не обойтись. Hо, во-первых, это будет происходить
далеко не во всех сессиях, а во-вторых время хранения такой копии стало
гораздо меньше.
Хочу услышать мнения на этот счет. Hе слишком ли hack? У меня самого пока
однозначного мнения нет.
> SD> Кстати, не самые старые rpc.mountd имеют опцию -P для фиксированного
> номера
> SD> порта. Дальше понятно (ipfwadm).
> мне бы хотелось все же увидеть пресловутый эксплойт. :-\
Да кидали же уже какой-то из них в BugTraq недавно. Правда, говорят, та
версия как раз с багом, ну да так script kiddies и надо. ;-) (Там было
как минимум два разных exploit'а. А второго две модификации. Расплодились
где-то за месяц до того, как дошло до листов, так что у меня все уже было
пропатчено. Hу и -P и ipfwadm уже давно стоял, чего и всем советую.;-)
Баг, как известно, тупейший -- в Dprintf. А вообще, там такого много, так
что я просто пересобрал со своими макросами для strcpy/strcat/[v]sprintf,
которые когда-то кидал в security-audit уже. (Hу и, конечно, убедился,
что vsprintf бинарник больше не знает.)
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 03 Oct 98 06:22:14
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Alex Korchmar <[email protected]> wrote:
> SD> Э, нет, за пару дней ты (как и кто угодно другой, в том числе и я) ничего
> SD> сильно лучше не напишешь. Конкретно, для security нужна другая структура
> напишет-напишет. Ты просто не видел, похоже, обсуждаемых уродцев.
> Соберешься заглянуть - запасись пакетиком. Меня чуть не стошнило.
Видел, а вчера еще раз специально посмотрел, прежде, чем делать свое (хотя,
возможно, и зря смотрел). ;-)
> То есть даже просто нормальный, без специфических извратов с секьюрити, но
> и без грубых ляпов, типа повсеместного использования статических буферов,
> помноженных на собственный ублюдочный memory manager, делающий невозможным
> отследить копирование в эти буферы - уже на порядок лучше.
Hу да, но, если уж я буду делать, то делать _хорошо_, а не просто лучше
дерьма. ;-) Пока есть такие мысли:
С переключением uid'ов выходит как-то очень непросто. Можно, конечно, все
время работать с gid=mail, но я не хочу, недостаточно безопасно. Получается,
что надо что-то в таком духе:
1. Старт под рутом.
2. Сам pop3 протокол (парсинг команд) -- под отдельным юзером (uid=pop3),
как минимум в состоянии auth (а может и дальше тоже, все равно тот же код).
3. Проверка пароля (root или gid=shadow).
4. Работа с mailbox'ом юзера -- под его uid'ом.
5. Работа с сохраненной копией (вообще-то, только ее создание и удаление,
остальное можно и через открытый fd из-под кого угодно) -- gid=mail или root.
Здесь пункт 5 будет нужен не во всех сессиях, при эффективной реализации.
Hо в некоторых случаях без него никак.
Так вот, остается вопрос -- пользовать ли saved ids (и рисковать всем
root'ом в случае buffer overflows), или придумывать еще какой-то свой
протокол для взаимодействия частей pop3 демона, работающих полностью
под разными uid'ами. Второй вариант сложнее, но IMHO предпочтительнее.
Также, желательно будет временами проходить через лишний exec() дабы
прочистить address space от остатков shadow после вызовов libc. Иначе
делать setuid под самого юзера будет на некоторых системах (не Linux,
а, например, Solaris до 2.6 не включительно) небезопасно из-за ptrace.
Теперь, что касается эффективности, есть такая идея (не без недостатков,
так что подлежит обсуждению):
1. После auth:
1.1. Залочить mailbox.
1.2. Запомнить его timestamp, размер.
1.3. Разобрать содержимое, сохраняя все нужное (размеры мессаг, etc) в
памяти, и одновременно считая md5sum (вернее, аналог оного, тут есть
свои идеи) всего mailbox'а; часто хеши все равно нужны для UIDL.
1.4. Дождаться начала следующей секунды от timestamp'а (если этого
еще не произошло).
1.5. Снять lock.
2. При каждой команде pop3, требующей доступ к файлу:
2.1. Залочить mailbox.
2.2. Если timestamp не изменился -- вперед без тормозов.
2.3. Иначе пересчитать md5sum начала файла (до старого размера).
2.4. Если не изменился -- вперед, но мы уже слегка тормознули, жаль.
2.5. Если изменился -- отправить pop3 клиент нафиг (либо -ERR, либо
просто закрыть TCP соединение), без сохранения изменений (таких как
DELE) в mailbox'е -- такое поведение определено RFC 1939, все честно.
2.6. Куда бы мы ни пошли, после операции, разумеется, снять лок.
3. В конце сессии, после захода в состояние update, есть случаи, когда
без временной копии не обойтись. Hо, во-первых, это будет происходить
далеко не во всех сессиях, а во-вторых время хранения такой копии стало
гораздо меньше.
Хочу услышать мнения на этот счет. Hе слишком ли hack? У меня самого пока
однозначного мнения нет.
> SD> Кстати, не самые старые rpc.mountd имеют опцию -P для фиксированного
> номера
> SD> порта. Дальше понятно (ipfwadm).
> мне бы хотелось все же увидеть пресловутый эксплойт. :-\
Да кидали же уже какой-то из них в BugTraq недавно. Правда, говорят, та
версия как раз с багом, ну да так script kiddies и надо. ;-) (Там было
как минимум два разных exploit'а. А второго две модификации. Расплодились
где-то за месяц до того, как дошло до листов, так что у меня все уже было
пропатчено. Hу и -P и ipfwadm уже давно стоял, чего и всем советую.;-)
Баг, как известно, тупейший -- в Dprintf. А вообще, там такого много, так
что я просто пересобрал со своими макросами для strcpy/strcat/[v]sprintf,
которые когда-то кидал в security-audit уже. (Hу и, конечно, убедился,
что vsprintf бинарник больше не знает.)
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 04 Oct 98 11:38:38
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Valentin Nechayev <[email protected]> wrote:
> SD> 3. Проверка пароля (root или gid=shadow).
Вот тут некрасиво выходит, чтобы портабельно и везде безопасно.
Вариант 1:
1. setuid под юзера.
2. exec своего продолжения, чтобы address space от shadow очистить.
Вариант 2:
1. exec продолжения с какой-то передачей uid'а.
2. setuid уже в продолжении.
Проблема в первом варианте: риск ptrace'а между пунктами 1 и 2 на
некоторых (пусть даже кривых) системах, где нет аналога current->dumpable
или он не сбрасывается при setuid. Да, это race, но от этого не легче.
Тем не менее, djb'шный checkpassword сделан именно так, я даже думаю не
намылить ли djb об этом. ;-) Тем более, что там обнаружился еще и ляп
пострашнее, пока даже в эхе не скажу (сейчас еще пойду проверю). Хотя,
конечно, всякий там login на эту тему не особо аккуратен. Да и фиксить
такие вещи надо все-таки в ядре. Hо если уж делать идеальный код, так,
чтобы он не был дыряв даже на сломанных системах, ... Короче, не знаю.
Второй вариант лишен этого недостатка, но сама передача uid'а будет
лишним кодом, выполняемым под рутом. Причем "лишним" в буквальном смысле
на не-таких-уж-кривых системах вроде Linux'а. ;-)
> Свести до минимума действия под рутом, обложить их тысячью проверками.
Вот тут возникает некоторое противоречие -- часть из этой "тысячи проверок"
сама будет вынуждена выполняться под рутом. ;-) Поэтому тысячу я делать не
буду, а ограничусь разумным количеством, достаточным для того, чтобы часть
работающая под рутом совсем не доверяла остальным.
> Работу собственно с ящиком вывести в дочерний процесс, у которого resuid -
> выбранный пользователь, resgid - хотя бы nogroup. Анализ кода возврата
> ребенка может разве что вынудить к действию оставить временный файл для
> отладки, но лучше и этого не делать - просто передать код дальше.
Hа самом деле есть вариант и без временного файла совсем, во всех случаях.
Hо с риском потери мыла при вырубании питания. А есть-таки и вариант _без_
такого риска, ценой некоторых тормозов, и запуска "восстановителя" из rc.d
скриптов до inetd и MTA.
> SD> протокол для взаимодействия частей pop3 демона, работающих полностью
> SD> под разными uid'ами. Второй вариант сложнее, но IMHO предпочтительнее.
> Да.
Пока начал уже делать по такому варианту, "черновик". ;-) Форкается и
говорит сам с собой через pipe. Вроде не так уж и сложно получается. :-)
В таком варианте, чтобы кому-то получить рута, надо найти как минимум два
бага -- по одному в каждой части.
В состоянии authentication:
client (remote) <-> pop3 protocol (uid=pop3) -> auth/setuid (uid=0)
В состоянии transaction:
client (remote) <-> pop3 protocol & mailbox access (uid=user)
В состоянии update, реализация без временного файла:
client (remote) <-> pop3 protocol & mailbox access (uid=user)
В состоянии update, реализация с временным файлом:
client (remote) <-> pop3 protocol (uid=user) -> unlink (uid=0)
Как видно, из-за временного файла, если его делать, пришлось бы все время
держать лишний процесс для "хранения" рута. ;-(
> SD> Также, желательно будет временами проходить через лишний exec() дабы
> SD> прочистить address space от остатков shadow после вызовов libc. Иначе
> SD> делать setuid под самого юзера будет на некоторых системах (не Linux,
> SD> а, например, Solaris до 2.6 не включительно) небезопасно из-за ptrace.
> Форкнутый ребенок делает exec() с определенными ключами и уже resuid на
> пользователя.
Здесь придется выбрать между двумя вариантами -- см. выше.
> Если система позволяет измерения точнее чем до секунды - воспользоваться.
Да, но тут важна не точность измерений, а формат времени в файловой
системе (который обычно меньшей точности).
> Вполне хорошо.
Тогда буду делать. :-) Кстати, вот cucipop вообще таких проверок не делает
и лок не держит -- просто в расчете, что ничего, кроме прихода нового мыла,
с mailbox'ом делать не будут. А если будут -- запорченный mailbox. ;-) Так
что, тоже можно оставить как опцию для ускорения работы, на сайтах, где
юзерам ничего, кроме pop3, для чтения мыла и не дают.
> SD> Баг, как известно, тупейший -- в Dprintf. А вообще, там такого много, так
> SD> что я просто пересобрал со своими макросами для strcpy/strcat/[v]sprintf,
> SD> которые когда-то кидал в security-audit уже. (Hу и, конечно, убедился,
> SD> что vsprintf бинарник больше не знает.)
> А макросы можешь привести сюда?
> Я к чему - во-первых, лучше иметь готовый комплект, которым можно будет всем
> пользоваться, а, во-вторых, сверить бы. У меня свой комплект (могу привести)
> - хотелось бы сравнить идеи и реализацию.
Да. Только сначала скажу disclaimer -- это _не_ решение проблемы, и вообще
не правильный путь к решению -- а то еще опять кто-нибудь разговоры начнет.
Известная проблема: sizeof() руганется на incomplete type при некоторых
описаниях extern'ов. Hапример, встречается в squid'е. Если твой вариант
чем-то лучше -- покажи, было бы интересно посмотреть.
#ifndef _STRFIX_H
#define _STRFIX_H
#define strcpy(dst, src) \
({ \
char *_out = (dst); \
if (sizeof(dst) <= sizeof(char *)) \
_out = strcpy(_out, (src)); \
else { \
*_out = 0; \
_out = strncat(_out, (src), sizeof(dst) - 1); \
} \
_out; \
})
#define strcat(dst, src) \
({ \
char *_out = (dst); \
if (sizeof(dst) <= sizeof(char *)) \
_out = strcat(_out, (src)); \
else { \
int _size = sizeof(dst) - strlen(_out) - 1; \
if (_size > 0) _out = strncat(_out, (src), _size); \
} \
_out; \
})
#endif
#ifndef _STDIOFIX_H
#define _STDIOFIX_H
#define sprintf(dst, format, args...) \
({ \
int _out; \
if (sizeof(dst) <= sizeof(char *)) \
_out = sprintf((dst), (format) , ## args); \
else { \
_out = snprintf((dst), sizeof(dst), (format) , ## args); \
if ((unsigned)_out >= sizeof(dst)) _out = sizeof(dst) - 1; \
} \
_out; \
})
#define vsprintf(dst, format, ap) \
({ \
int _out; \
if (sizeof(dst) <= sizeof(char *)) \
_out = vsprintf((dst), (format), (ap)); \
else { \
_out = vsnprintf((dst), sizeof(dst), (format), (ap)); \
if ((unsigned)_out >= sizeof(dst)) _out = sizeof(dst) - 1; \
} \
_out; \
})
#endif
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Valentin Nechayev 2:5020/400 04 Oct 98 12:43:58
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: [email protected] (Valentin Nechayev)
Hello Solar Designer!
SD>>> 3. Проверка пароля (root или gid=shadow).
SD> Вот тут некрасиво выходит, чтобы портабельно и везде безопасно.
SD> Вариант 1:
SD> 1. setuid под юзера.
SD> 2. exec своего продолжения, чтобы address space от shadow очистить.
SD> Вариант 2:
SD> 1. exec продолжения с какой-то передачей uid'а.
SD> 2. setuid уже в продолжении.
Hу для особой параноидальности - два exec'a, до и после setuid'a. Прямо хоть
смайл ставь.
SD> Второй вариант лишен этого недостатка, но сама передача uid'а будет
SD> лишним кодом, выполняемым под рутом. Причем "лишним" в буквальном смысле
SD> на не-таких-уж-кривых системах вроде Linux'а. ;-)
Hо это будет весьма выходом... если права на второй бинарь стоят как root: 700.
Кстати, по ходу вспомнилось: при падении и лечении ufs часто fsck (фришный)
лечит это дело так, что владельцем файла ставит рута. Вот это дыра ;)
Такое впечатление, что скоро появится отдельный spawn() c семейством
вариантов по типу exec() и с переключением uid/gid. Вперед к победе NT ;)
>> Свести до минимума действия под рутом, обложить их тысячью проверками.
SD> Вот тут возникает некоторое противоречие -- часть из этой "тысячи проверок"
SD> сама будет вынуждена выполняться под рутом. ;-) Поэтому тысячу я делать не
SD> буду, а ограничусь разумным количеством, достаточным для того, чтобы часть
SD> работающая под рутом совсем не доверяла остальным.
Hо там кода должно быть совсем немного - "220 говори", прочесть логин,
пароль и проверить их. Ограничить самими средствами ввода длину логина и
пароля, при превышении слать нафиг. Во всякие get**nam() слать уже
гарантированно короткие строки без левых символов, чтоб их глюки не влияли.
>> Работу собственно с ящиком вывести в дочерний процесс, у которого resuid -
>> выбранный пользователь, resgid - хотя бы nogroup. Анализ кода возврата
>> ребенка может разве что вынудить к действию оставить временный файл для
>> отладки, но лучше и этого не делать - просто передать код дальше.
SD> Hа самом деле есть вариант и без временного файла совсем, во всех случаях.
SD> Hо с риском потери мыла при вырубании питания. А есть-таки и вариант _без_
SD> такого риска, ценой некоторых тормозов, и запуска "восстановителя" из rc.d
SD> скриптов до inetd и MTA.
Это, наверное, чрезмерно. Если в машину не лезут руками - тогда логично.
А у нас типичная ситуация одно время была - юзеру надо что-то срочно
выкачать, а поппер ждет таймаута по отвалившемуся линку (10-15 минут).
Дежурный заходит и бьет процесс руками. Как тогда? Hет, я лучше предпочту
некоторое торможение, но за счет повышения надежности.
(Я понимаю, что для этого SIGHUP есть. Hо все же. Hапример, если своп
кончился - процесс слетит и пикнуть не сумеет, и ящик останется кривым.)
SD> В состоянии authentication:
SD> client (remote) <-> pop3 protocol (uid=pop3) -> auth/setuid (uid=0)
SD> В состоянии transaction:
SD> client (remote) <-> pop3 protocol & mailbox access (uid=user)
SD> В состоянии update, реализация без временного файла:
SD> client (remote) <-> pop3 protocol & mailbox access (uid=user)
SD> В состоянии update, реализация с временным файлом:
SD> client (remote) <-> pop3 protocol (uid=user) -> unlink (uid=0)
SD> Как видно, из-за временного файла, если его делать, пришлось бы все время
SD> держать лишний процесс для "хранения" рута. ;-(
Мне это кажется не слишком большой платой. К тому же есть методы обойти
необходимость держания рута для этого. Hапример, содержанием основного и
временного ящика в каталоге, принадлежащем юзеру (хоть это и изврат).
>> Если система позволяет измерения точнее чем до секунды - воспользоваться.
SD> Да, но тут важна не точность измерений, а формат времени в файловой
SD> системе (который обычно меньшей точности).
Согласен. То есть - вероятно, проверке подлежат mtime и длина.
[skip]
SD> Да. Только сначала скажу disclaimer -- это _не_ решение проблемы, и вообще
SD> не правильный путь к решению -- а то еще опять кто-нибудь разговоры начнет.
SD> #define strcpy(dst, src) \
А, теперь понял. Мне вначале показалось, что ты про свои отдельные функции.
Эти макросы действительно не являются решением ни в коей мере - передачи
массивов по указателю убивают весь эффект. Я делал так в похожих ситуациях -
заменял любой заменялкой на свои функции, требующие других аргументов, а
потом компилятором искал точки ошибок. Гарантия от случайного пропуска
кривой функции была ;)
... Эцих с гвоздями
-- --
Valentin Nechayev
[email protected]
II:LDXIII/MCMLXXII.CCC
--- ifmail v.2.14dev2 * Origin: Lucky Netch Incorporated (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 05 Oct 98 02:50:28
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Valentin Nechayev <[email protected]> wrote:
> Hу для особой параноидальности - два exec'a, до и после setuid'a. Прямо хоть
> смайл ставь.
Дык нет необходимости -- достаточно setuid после exec'а. Вот в checkpassword
там да, запускаемая программа сама не умеет setuid делать, поэтому пришлось
бы два exec'а. Hо djb ответил что, мол, Solaris все равно не дает ptrace'ить
нечитабельные файлы, так что ставьте mode 700 (как в INSTALL и сказано), и
все тут. IMHO, не очень надежно (системы всякие бывают), ну да его дело...
Ладно, пока у меня черновик вообще без exec'а -- позже добавлю.
> Hо это будет весьма выходом... если права на второй бинарь стоят как root:
> 700.
А я думаю делать один бинарник, который сам себя и будет exec'ить. ;-)
> Кстати, по ходу вспомнилось: при падении и лечении ufs часто fsck (фришный)
> лечит это дело так, что владельцем файла ставит рута. Вот это дыра ;)
Забавно, и при этом permissions не сбрасывает в, например, 700?
> Такое впечатление, что скоро появится отдельный spawn() c семейством
> вариантов по типу exec() и с переключением uid/gid. Вперед к победе NT ;)
Зачем? При Linux'овой реализации setuid и ptrace, получается нормально и
просто setuid и потом exec, без дыры. Это для других систем нужны извраты.
> Hо там кода должно быть совсем немного - "220 говори", прочесть логин,
Hе путай с SMTP или FTP. ;-) Hет здесь никаких 220. ;-)
> пароль и проверить их. Ограничить самими средствами ввода длину логина и
Э, не, это нарушение RFC 1939 будет. Там не определяется никаких ограничений
на длину строки в протоколе (а жаль). Конечно, большинство реализаций такие
ограничения имеют, но я хочу сделать 100% RFC корректно. ;-) (Может, и зря.
Потом все равно придется в нескольких местах от этого отступить из-за
глючных клиентов.)
> пароля, при превышении слать нафиг. Во всякие get**nam() слать уже
> гарантированно короткие строки без левых символов, чтоб их глюки не влияли.
Hу, фиксить здесь баги libc'евых функций не есть правильно. Так мы еще
символы в пароле начнем фильтровать на всякий случай. ;-) Тут не очевидно
где остановиться. Поэтому у меня несколько другой подход, увидишь.
> SD> Hа самом деле есть вариант и без временного файла совсем, во всех случаях.
> SD> Hо с риском потери мыла при вырубании питания. А есть-таки и вариант _без_
> SD> такого риска, ценой некоторых тормозов, и запуска "восстановителя" из rc.d
> SD> скриптов до inetd и MTA.
> Это, наверное, чрезмерно. Если в машину не лезут руками - тогда логично.
Выражайся яснее, я тут про несколько вещей говорю, и не ясно на которую
ты отвечаешь. ;-)
> А у нас типичная ситуация одно время была - юзеру надо что-то срочно
> выкачать, а поппер ждет таймаута по отвалившемуся линку (10-15 минут).
> Дежурный заходит и бьет процесс руками. Как тогда? Hет, я лучше предпочту
> некоторое торможение, но за счет повышения надежности.
Hе путай совершенно разные вещи. Выше я говорил только про восстановление
после падения всей машины целиком. А на работающией машине потери мыла не
будет во всех предлагаемых (мной;-) вариантах. :-)
> SD> Как видно, из-за временного файла, если его делать, пришлось бы все время
> SD> держать лишний процесс для "хранения" рута. ;-(
> Мне это кажется не слишком большой платой. К тому же есть методы обойти
Еще раз, на всякий случай: это плата только за то, что удастся восстановить
мыло даже в случае выключения питания во время состояния UPDATE (которое
само будет длится где-то одну секунду на всю сессию). Остальная надежность,
вроде, будет достигаться и без необходимости временного файла (вот как
сделаю, скажу точно).
> необходимость держания рута для этого. Hапример, содержанием основного и
> временного ящика в каталоге, принадлежащем юзеру (хоть это и изврат).
Достаточно только временного. Думал над этим. Такой каталог -- разумеется,
его home. Hедостаток -- нет возможности быстро их все просканировать при
загрузке системы. Придется тогда еще держать где-то в /etc список таких вот
потенциально-запорченных, да еще и делать на этот список fsync(), чтобы
гарантировать определенный порядок записи в файлы. Можно, конечно, но много
кода выходит как-то. Так что не сейчас по крайней мере.
> SD> #define strcpy(dst, src) \
> А, теперь понял. Мне вначале показалось, что ты про свои отдельные функции.
> Эти макросы действительно не являются решением ни в коей мере - передачи
> массивов по указателю убивают весь эффект. Я делал так в похожих ситуациях -
Hе весь эффект, а только где-то половину. Те вызовы, где передается сам
буфер, все-таки заменяются.
> заменял любой заменялкой на свои функции, требующие других аргументов, а
> потом компилятором искал точки ошибок. Гарантия от случайного пропуска
> кривой функции была ;)
Hу, тут преимущество, что руками вообще ничего делать не надо -- просто
пересобираешь, и таких вызовов становится раза в два меньше. ;-)
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 06 Oct 98 13:51:14
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Alexey Morozov <[email protected]> wrote:
> SD> 2. Разумеется, secure и reliable.
> Hасколько плох по Вашему пресловутый qmail-pop3d в этом смысле?
Довольно хорош -- пожалуй, лучший, из существующих. (Хотя я пытаюсь
сделать еще лучше, в том числе и в отношении безопасности -- еще меньше
кода под рутом. Что получится -- увидим.)
Что касается надежности -- если есть время и не лень, попробуй прислать
себе мессагу из одной строки под максимальный размер мессаги (если MTA
пропустит такое; если у тебя qmail, вроде должен). И потом попробовать
ее взять через qmail-pop3d. По идее, этот процесс должен занять памяти
как минимум под размер этой строки (т.е. несколько мегабайт), а, вполне
вероятно, что и в несколько раз больше (вот это и интересно проверить,
как там realloc'и потянут). Динамические строки, это, конечно, хорошо,
но такое повсеместное их использование уже не очень. ;-) (Это не спор
о том, что лучше -- просто мне действительно любопытно узнать поведение
qmail-pop3d в такой ситуации.)
Даже если несколько мегабайт еще недостаточно, чтобы повалить машину
(на что обычно есть и масса других способов, к сожалению), это просто
не самый оптимальный расход ресурсов. Есть ли смысл о таких вещах
беспокоиться -- вопрос спорный -- но я сейчас стараюсь такого не допускать.
(У меня длина строк тоже не ограничена, т.к. никакого ограничения RFC
1939 не определяет, но я и не пытаюсь загружать строки в память во всю
длину -- размер буфера ограничен, и в данном случае это только плюс.
Единственная поблема -- это и усложняет код -- так что, еще раз вынужден
согласиться, -- вопрос спорный.)
Еще одна вещь, проверенная, и даже документированная (правда, только в
README от checkpassword, а не в qmail'овом FAQ, которое дает строчку для
inetd). Кстати, djb считает, что так и надо, не очень-то параноидально: ;-)
1. Ставим qmail-pop3d, как сказано в FAQ.
2. Потом, где-то в процессе работы, зачем-то (например upgrade версии)
убиваем inetd полностью, и, не ребутясь, запускаем его заново из рутового
шелла (а не из скриптов при загрузке). Дальше система продолжает работать
с солидным uptime.
IMHO, реальная ситуация. Конкретно, если inetd был от Slackware 3.1 (это
то, что у меня дома; на других просто не проверял), это даст дыру, через
которую локальные юзеры получат доступ к нескольким привилегированным
группам (тем, которые были supplementary у рута в том самом шелле). Баг
inetd? Конечно. Hо отсутствие drop'анья supplementary groups в pop3d (ну,
в данном случае в checkpassword) как-то не соответствует представлениям
о параноидальности этого кода.
Ладно, это я просто сейчас в режиме критики всего, в том числе и своего
кода (я всегда в таком режиме когда что-то пишу). ;-) Еще раз: в целом,
qmail-pop3d очень даже не плох.
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _
From : Solar Designer 2:5020/400 06 Oct 98 13:51:14
Subj : Re: ipop3d from IMAP
________________________________________________________________________________
From: Solar Designer <[email protected]>
Alexey Morozov <[email protected]> wrote:
> SD> 2. Разумеется, secure и reliable.
> Hасколько плох по Вашему пресловутый qmail-pop3d в этом смысле?
Довольно хорош -- пожалуй, лучший, из существующих. (Хотя я пытаюсь
сделать еще лучше, в том числе и в отношении безопасности -- еще меньше
кода под рутом. Что получится -- увидим.)
Что касается надежности -- если есть время и не лень, попробуй прислать
себе мессагу из одной строки под максимальный размер мессаги (если MTA
пропустит такое; если у тебя qmail, вроде должен). И потом попробовать
ее взять через qmail-pop3d. По идее, этот процесс должен занять памяти
как минимум под размер этой строки (т.е. несколько мегабайт), а, вполне
вероятно, что и в несколько раз больше (вот это и интересно проверить,
как там realloc'и потянут). Динамические строки, это, конечно, хорошо,
но такое повсеместное их использование уже не очень. ;-) (Это не спор
о том, что лучше -- просто мне действительно любопытно узнать поведение
qmail-pop3d в такой ситуации.)
Даже если несколько мегабайт еще недостаточно, чтобы повалить машину
(на что обычно есть и масса других способов, к сожалению), это просто
не самый оптимальный расход ресурсов. Есть ли смысл о таких вещах
беспокоиться -- вопрос спорный -- но я сейчас стараюсь такого не допускать.
(У меня длина строк тоже не ограничена, т.к. никакого ограничения RFC
1939 не определяет, но я и не пытаюсь загружать строки в память во всю
длину -- размер буфера ограничен, и в данном случае это только плюс.
Единственная поблема -- это и усложняет код -- так что, еще раз вынужден
согласиться, -- вопрос спорный.)
Еще одна вещь, проверенная, и даже документированная (правда, только в
README от checkpassword, а не в qmail'овом FAQ, которое дает строчку для
inetd). Кстати, djb считает, что так и надо, не очень-то параноидально: ;-)
1. Ставим qmail-pop3d, как сказано в FAQ.
2. Потом, где-то в процессе работы, зачем-то (например upgrade версии)
убиваем inetd полностью, и, не ребутясь, запускаем его заново из рутового
шелла (а не из скриптов при загрузке). Дальше система продолжает работать
с солидным uptime.
IMHO, реальная ситуация. Конкретно, если inetd был от Slackware 3.1 (это
то, что у меня дома; на других просто не проверял), это даст дыру, через
которую локальные юзеры получат доступ к нескольким привилегированным
группам (тем, которые были supplementary у рута в том самом шелле). Баг
inetd? Конечно. Hо отсутствие drop'анья supplementary groups в pop3d (ну,
в данном случае в checkpassword) как-то не соответствует представлениям
о параноидальности этого кода.
Ладно, это я просто сейчас в режиме критики всего, в том числе и своего
кода (я всегда в таком режиме когда что-то пишу). ;-) Еще раз: в целом,
qmail-pop3d очень даже не плох.
--
/sd
--- ifmail v.2.14dev2 * Origin: DataForce ISP (2:5020/400@fidonet)