HTTP proxy: no NTLM left

NTLM authentication of proxy clients was gone but for what was left of
it: the 407 answer offering NTLM before Basic (12, under NOCRYPT, which
nothing else used) and the one for its handshake (13), sent by nothing,
and the prototypes of genchallenge() and mschap(), defined nowhere. The
strings after them in proxy_stringtable move up two: 403 with <pre> is
12, 503 13, 401 of the FTP server 14, 100 Continue 15.

rus.3ps, StringsPlugin's translation, follows: the two strings go, the
403 with <pre> is UTF-8 as the rest, the XML of the running services
has its Content-disposition, and the table of counters the columns of
its rows (Action and #/Description were one).

NT: passwords, MD4 hashes as Windows keeps them, stay. The documents
no longer tell to give proxy -n to turn off NTLM.

Plugin binary compatibility: a plugin indexing proxy_stringtable finds
the strings from 12 on two places earlier, and a .3ps file of its own
with the NTLM strings has two more than 3proxy (StringsPlugin warns).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Vladimir Dubrovin 2026-10-28 12:02:27 +03:00
parent e396da2696
commit add40b1d85
12 changed files with 22 additions and 61 deletions

View File

@ -70,7 +70,7 @@ ifeq ($(PF_CHECK), true)
endif endif
ifeq ($(STATIC), true) ifeq ($(STATIC), true)
LDFLAGS += -static LDFLAGS += -static
CFLAGS += -DNOPLUGINS -DNOSTDRESOLVE -DNOCRYPT CFLAGS += -DNOPLUGINS -DNOSTDRESOLVE
ZLIB = -lz -lzstd ZLIB = -lz -lzstd
PLUGINS = PLUGINS =
PAM_CHECK = false PAM_CHECK = false

View File

@ -68,7 +68,7 @@ CFLAGS += -DWITH_TRANSPARENT
TRANSPARENT_OBJS = transparent$(OBJSUFFICS) TRANSPARENT_OBJS = transparent$(OBJSUFFICS)
ifeq ($(STATIC), true) ifeq ($(STATIC), true)
LDFLAGS += -static LDFLAGS += -static
CFLAGS += -DNOPLUGINS -DNOSTDRESOLVE -DNOCRYPT CFLAGS += -DNOPLUGINS -DNOSTDRESOLVE
ZLIB = -lz -lzstd ZLIB = -lz -lzstd
PLUGINS = PLUGINS =
PAM_CHECK = false PAM_CHECK = false

View File

@ -1539,7 +1539,7 @@ must be used.
<pre> <pre>
authcache ip 60 authcache ip 60
auth cache strong windows auth cache strong windows
proxy -n proxy
</pre> </pre>
</p> </p>
Please note that caching affects security. Never use caching for access to Please note that caching affects security. Never use caching for access to

View File

@ -1541,7 +1541,7 @@ HTTP-сервера - для хоста, на который отвечает п
<pre> <pre>
authcache ip 60 authcache ip 60
auth cache strong windows auth cache strong windows
proxy -n</pre> proxy</pre>
Кэширование влияет на безопасность доступа. Ни в коем случае не следует Кэширование влияет на безопасность доступа. Ни в коем случае не следует
использовать кэширование для доступа к критичным ресурсам, в частности к использовать кэширование для доступа к критичным ресурсам, в частности к
интерфейсу администрирования. интерфейсу администрирования.
@ -1705,8 +1705,7 @@ HTTP-сервера - для хоста, на который отвечает п
нестандартных портах, для SOCKSv4 не поддрживается авторизация с нестандартных портах, для SOCKSv4 не поддрживается авторизация с
паролем (IE поддерживает только SOCKSv4), но при этом IE передает паролем (IE поддерживает только SOCKSv4), но при этом IE передает
имя пользователя по SOCKSv4 (имя, с которым пользователь вошел в систему). имя пользователя по SOCKSv4 (имя, с которым пользователь вошел в систему).
Для SOCKSv5 не поддерживается NTLM авторизация, пароли передаются в открытом Для SOCKSv5 пароли передаются в открытом тексте.
тексте.
</p> </p>
<li><a name="REDIRADV"><i>Q: Какие преимущества?</i></a></li> <li><a name="REDIRADV"><i>Q: Какие преимущества?</i></a></li>
<p> <p>

View File

@ -53,7 +53,7 @@ configuration files.</p>
<p style="margin-left:9%; margin-top: 1em">When invoked <p style="margin-left:9%; margin-top: 1em">When invoked
with a single argument, it produces an NT password hash with a single argument, it produces an NT password hash
(MD4-based, suitable for NTLM authentication). The output is (MD4-based, as Windows stores passwords). The output is
prefixed with <b>NT:</b>.</p> prefixed with <b>NT:</b>.</p>
<p style="margin-left:9%; margin-top: 1em">When invoked <p style="margin-left:9%; margin-top: 1em">When invoked

View File

@ -25,7 +25,6 @@ After the plugin is loaded, the 'windows' authentication type is supported.
auth cache windows auth cache windows
</pre> </pre>
<li>NTLM authentication is not currently supported for plugins; you should use the proxy -n switch to disable it.
</ol> </ol>
<h4>Download:</h4> <h4>Download:</h4>
<ul> <ul>

View File

@ -25,8 +25,6 @@ auth windows
auth cache windows auth cache windows
</pre> </pre>
<li>В настоящее время не поддерживается NTLM-аутентификация для плагинов,
поэтому необходимо запускать proxy с ключиком -n.
</ol> </ol>
<h4>Загрузить:</h4> <h4>Загрузить:</h4>
<ul> <ul>

View File

@ -76,9 +76,8 @@ allow * * * 80,8080-8088
# уровня и заменить ip, порт, имя пользователя и пароль на свои значения # уровня и заменить ip, порт, имя пользователя и пароль на свои значения
# parent 1000 http 192.168.0.1 8080 username passwd # parent 1000 http 192.168.0.1 8080 username passwd
# allow * # allow *
# Запускаем службу HTTP-proxy на порту (3128) и # Запускаем службу HTTP-proxy на порту 3128
# (-n) c отключенной NTLM-авторизацией) proxy -p3128
proxy -p3128 -n
# Ограничиваем толшину канала для пользователей # Ограничиваем толшину канала для пользователей
# vasia и petia в 20000 bps, # vasia и petia в 20000 bps,

View File

@ -15,7 +15,7 @@ configuration. Encrypted passwords allow the system to avoid storing
passwords in cleartext in configuration files. passwords in cleartext in configuration files.
.PP .PP
When invoked with a single argument, it produces an NT password hash When invoked with a single argument, it produces an NT password hash
(MD4-based, suitable for NTLM authentication). The output is prefixed with (MD4-based, as Windows stores passwords). The output is prefixed with
.BR NT: . .BR NT: .
.PP .PP
When invoked with two arguments (salt and password), it produces a BLAKE2b When invoked with two arguments (salt and password), it produces a BLAKE2b

23
rus.3ps
View File

@ -31,6 +31,7 @@ HTTP/1.0 200 OK\n
Connection: close\n Connection: close\n
Cache-Control: no-cache\n Cache-Control: no-cache\n
Content-type: text/xml; charset=utf-8\n Content-type: text/xml; charset=utf-8\n
Content-disposition: inline; filename=running.xml\n
\n \n
<?xml version="1.0"?>\n <?xml version="1.0"?>\n
<?xml-stylesheet href="/SX" type="text/css"?>\n <?xml-stylesheet href="/SX" type="text/css"?>\n
@ -100,11 +101,11 @@ value {\n
[end] [end]
<h3>Счетчики</h3>\n <h3>Счетчики</h3>\n
<table border = '1'>\n <table border = '1'>\n
<tr align='center'><td>Описание</td><td>Активный</td> <tr align='center'><td>Действие</td><td>#/Описание</td><td>Активный</td>
<td>Пользователи</td><td>Адрес источника</td><td>Адрес назначения</td> <td>Пользователи</td><td>Адрес источника</td><td>Адрес назначения</td>
<td>Порты</td> <td>Порты</td>
<td>Лимит</td><td>Ед.</td><td>Значение</td> <td>Лимит</td><td>Ед.</td><td>Значение</td>
<td>Дата сброса</td><td>Дата обновения</td><td>Номер</td></tr>\n <td>Дата сброса</td><td>Дата обновления</td><td>Номер</td></tr>\n
[end] [end]
</table>\n </table>\n
[end] [end]
@ -208,25 +209,9 @@ Content-type: text/html; charset=utf-8\n
Если Вы считаете, что это ошибка обратитесь к администратору Если Вы считаете, что это ошибка обратитесь к администратору
</h3></body></html>\n </h3></body></html>\n
[end] [end]
HTTP/1.0 407 Proxy Authentication Required\n
Proxy-Authenticate: NTLM\n
Proxy-Authenticate: basic realm="proxy", encoding="utf-8"\n
Connection: close\n
Content-type: text/html; charset=utf-8\n
\n
<html><head><title>407 Proxy Authentication Required</title></head>\n
<body><h2>407 Proxy Authentication Required</h2><h3>Access to requested resource disallowed by administrator or you need valid username/password to use this resource.<br><hr>
Доступ запрещен администратором или Вы ввели неправильное имя/пароль.
</h3></body></html>\n
[end]
HTTP/1.0 407 Proxy Authentication Required\n
Connection: keep-alive\n
Content-Length: 0\n
Proxy-Authenticate: NTLM
[end]
HTTP/1.0 403 Forbidden\n HTTP/1.0 403 Forbidden\n
Connection: close\n Connection: close\n
Content-type: text/html; charset=us-ascii\n Content-type: text/html; charset=utf-8\n
\n \n
<pre> <pre>
[end] [end]

View File

@ -88,36 +88,20 @@ char * proxy_stringtable[] = {
"<html><head><title>403 Access Denied</title></head>\r\n" "<html><head><title>403 Access Denied</title></head>\r\n"
"<body><h2>403 Access Denied</h2><h3>Access control list denies you to access this resource</body></html>\r\n", "<body><h2>403 Access Denied</h2><h3>Access control list denies you to access this resource</body></html>\r\n",
/* 12*/ "HTTP/1.0 407 Proxy Authentication Required\r\n" /* 12*/ "HTTP/1.0 403 Forbidden\r\n"
#ifndef NOCRYPT
"Proxy-Authenticate: NTLM\r\n"
#endif
"Proxy-Authenticate: Basic realm=\"proxy\"\r\n"
"Connection: close\r\n"
"Content-type: text/html; charset=utf-8\r\n"
"\r\n"
"<html><head><title>407 Proxy Authentication Required</title></head>\r\n"
"<body><h2>407 Proxy Authentication Required</h2><h3>Access to requested resource disallowed by administrator or you need valid username/password to use this resource</h3></body></html>\r\n",
/* 13*/ "HTTP/1.0 407 Proxy Authentication Required\r\n"
"Connection: keep-alive\r\n"
"Content-Length: 0\r\n"
"Proxy-Authenticate: NTLM ",
/* 14*/ "HTTP/1.0 403 Forbidden\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-type: text/html; charset=utf-8\r\n" "Content-type: text/html; charset=utf-8\r\n"
"\r\n" "\r\n"
"<pre>", "<pre>",
/* 15*/ "HTTP/1.0 503 Service Unavailable\r\n" /* 13*/ "HTTP/1.0 503 Service Unavailable\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-type: text/html; charset=utf-8\r\n" "Content-type: text/html; charset=utf-8\r\n"
"\r\n" "\r\n"
"<html><head><title>503 Service Unavailable</title></head>\r\n" "<html><head><title>503 Service Unavailable</title></head>\r\n"
"<body><h2>503 Service Unavailable</h2><h3>Your request violates configured policy</h3></body></html>\r\n", "<body><h2>503 Service Unavailable</h2><h3>Your request violates configured policy</h3></body></html>\r\n",
/* 16*/ "HTTP/1.0 401 Authentication Required\r\n" /* 14*/ "HTTP/1.0 401 Authentication Required\r\n"
"WWW-Authenticate: Basic realm=\"FTP Server\"\r\n" "WWW-Authenticate: Basic realm=\"FTP Server\"\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-type: text/html; charset=utf-8\r\n" "Content-type: text/html; charset=utf-8\r\n"
@ -125,7 +109,7 @@ char * proxy_stringtable[] = {
"<html><head><title>401 FTP Server requires authentication</title></head>\r\n" "<html><head><title>401 FTP Server requires authentication</title></head>\r\n"
"<body><h2>401 FTP Server requires authentication</h2><h3>This FTP server rejects anonymous access</h3></body></html>\r\n", "<body><h2>401 FTP Server requires authentication</h2><h3>This FTP server rejects anonymous access</h3></body></html>\r\n",
/* 17*/ "HTTP/1.1 100 Continue\r\n" /* 15*/ "HTTP/1.1 100 Continue\r\n"
"\r\n", "\r\n",
NULL NULL
@ -532,7 +516,7 @@ static void proxystatus(struct clientparam *param, int hdrsdone, char *ftpbuf, i
} }
} }
if(r == 10) stidx = 2; if(r == 10) stidx = 2;
else if(r == 700 || r == 701) stidx = 16; else if(r == 700 || r == 701) stidx = 14;
else if(r == 100 || (r > 10 && r < 20) || (r > 701 && r <= 705)) stidx = 1; else if(r == 100 || (r > 10 && r < 20) || (r > 701 && r <= 705)) stidx = 1;
else if(r >= 20 && r < 30) stidx = 6; else if(r >= 20 && r < 30) stidx = 6;
else if(r >= 30 && r < 80) stidx = 5; else if(r >= 30 && r < 80) stidx = 5;
@ -540,7 +524,7 @@ static void proxystatus(struct clientparam *param, int hdrsdone, char *ftpbuf, i
else if(r < 10) stidx = 7; else if(r < 10) stidx = 7;
else if(r == 999) stidx = 4; else if(r == 999) stidx = 4;
else if(r == 519) stidx = 3; else if(r == 519) stidx = 3;
else if(r == 517) stidx = 15; else if(r == 517) stidx = 13;
else if(r == 780) stidx = 10; else if(r == 780) stidx = 10;
else if(r >= 511 && r <= 516) stidx = 0; else if(r >= 511 && r <= 516) stidx = 0;
@ -841,7 +825,7 @@ for(;;){
} }
if( i > 11 && !strncasecmp((char *)(buf+inbuf), "Expect: 100", 11)){ if( i > 11 && !strncasecmp((char *)(buf+inbuf), "Expect: 100", 11)){
keepalive = 1; keepalive = 1;
send_st(param, 17); send_st(param, 15);
continue; continue;
} }
if(param->transparent && i > 6 && !strncasecmp((char *)buf + inbuf, "Host:", 5)){ if(param->transparent && i > 6 && !strncasecmp((char *)buf + inbuf, "Host:", 5)){

View File

@ -461,9 +461,6 @@ SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned c
int text2unicode(const char * text, char * buf, int buflen); int text2unicode(const char * text, char * buf, int buflen);
void unicode2text(const char *unicode, char * buf, int len); void unicode2text(const char *unicode, char * buf, int len);
void genchallenge(struct clientparam *param, char * challenge, char *buf);
void mschap(const unsigned char *win_password,
const unsigned char *challenge, unsigned char *response);
void destroyhashtable(struct hashtable *ht); void destroyhashtable(struct hashtable *ht);
int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, unsigned growlimit); int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, unsigned growlimit);