Fossil SCM

Improved TLS read-from-client support on Windows.

stephan 2022-01-28 17:36 trunk merge
Commit b0834be5d024d2fbb05d15ca53de4d6c1e0fdc0661eb586d856dd10e78bdfc06
3 files changed +2 -2 +18 -14 +2 -2
+2 -2
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364364
}
365365
366366
/* Works like fread():
367367
**
368368
** Read as many as bytes of content as we can, up to a maximum of nmemb
369
-** bytes. Return the number of bytes read. Return -1 if there is no
369
+** bytes. Return the number of bytes read. Return 0 if there is no
370370
** further input or if an I/O error occurs.
371371
*/
372372
size_t cgi_fread(void *ptr, size_t nmemb){
373373
if( !g.httpUseSSL ){
374374
return fread(ptr, 1, nmemb, g.httpIn);
375375
}
376376
#ifdef FOSSIL_ENABLE_SSL
377
- return ssl_read_server(g.httpSSLConn, ptr, nmemb);
377
+ return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378378
#else
379379
fossil_fatal("SSL not available");
380380
#endif
381381
}
382382
383383
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return -1 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
383
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return 0 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
383
+18 -14
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,37 +811,41 @@
811811
}
812812
813813
/*
814814
** Read cleartext bytes that have been received from the client and
815815
** decrypted by the SSL server codec.
816
+**
817
+** If the expected payload size unknown, i.e. if the HTTP
818
+** Content-Length: header field has not been parsed, the doLoop
819
+** argument should be 0, or SSL_read() may block and wait for more
820
+** data than is eventually going to arrive (on Windows). On
821
+** non-Windows builds, it has been our experience that the final
822
+** argument must always be true, as discussed at length at:
823
+**
824
+** https://fossil-scm.org/forum/forumpost/2f818850abb72719
816825
*/
817
-size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
826
+size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
818827
int n;
819828
size_t rc = 0;
820829
SslServerConn *pServer = (SslServerConn*)pServerArg;
821830
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822
- else if( BIO_eof(pServer->bio) ) return 0;
823
- while( nBuf!=rc ){
831
+ while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
824832
n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825
- if( n<=0 ){
826
- break;
827
- }else if(n>0){
833
+ if( n>0 ){
828834
rc += n;
829835
}
830
-#ifdef _WIN32
831
- /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832
- ** not require reading in a loop, returning all data in a single
833
- ** call. If we read in a loop on Windows, SSL reads fail. Details:
834
- ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835
- break;
836
-#endif
836
+ if( doLoop==0 || n<=0 ){
837
+ break;
838
+ }
837839
}
838840
return rc;
839841
}
840842
841843
/*
842
-** Read a single line of text from the client.
844
+** Read a single line of text from the client, up to nBuf-1 bytes. On
845
+** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846
+** Returns NULL on an I/O error or at EOF.
843847
*/
844848
char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
845849
int n = 0;
846850
int i;
847851
SslServerConn *pServer = (SslServerConn*)pServerArg;
848852
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,37 +811,41 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
 
 
 
 
 
 
 
 
 
816 */
817 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
818 int n;
819 size_t rc = 0;
820 SslServerConn *pServer = (SslServerConn*)pServerArg;
821 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822 else if( BIO_eof(pServer->bio) ) return 0;
823 while( nBuf!=rc ){
824 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825 if( n<=0 ){
826 break;
827 }else if(n>0){
828 rc += n;
829 }
830 #ifdef _WIN32
831 /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832 ** not require reading in a loop, returning all data in a single
833 ** call. If we read in a loop on Windows, SSL reads fail. Details:
834 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835 break;
836 #endif
837 }
838 return rc;
839 }
840
841 /*
842 ** Read a single line of text from the client.
 
 
843 */
844 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
845 int n = 0;
846 int i;
847 SslServerConn *pServer = (SslServerConn*)pServerArg;
848
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,37 +811,41 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
816 **
817 ** If the expected payload size unknown, i.e. if the HTTP
818 ** Content-Length: header field has not been parsed, the doLoop
819 ** argument should be 0, or SSL_read() may block and wait for more
820 ** data than is eventually going to arrive (on Windows). On
821 ** non-Windows builds, it has been our experience that the final
822 ** argument must always be true, as discussed at length at:
823 **
824 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719
825 */
826 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
827 int n;
828 size_t rc = 0;
829 SslServerConn *pServer = (SslServerConn*)pServerArg;
830 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
831 while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
 
832 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
833 if( n>0 ){
 
 
834 rc += n;
835 }
836 if( doLoop==0 || n<=0 ){
837 break;
838 }
 
 
 
 
839 }
840 return rc;
841 }
842
843 /*
844 ** Read a single line of text from the client, up to nBuf-1 bytes. On
845 ** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846 ** Returns NULL on an I/O error or at EOF.
847 */
848 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
849 int n = 0;
850 int i;
851 SslServerConn *pServer = (SslServerConn*)pServerArg;
852
+2 -2
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363363
#endif
364364
}
365365
while( amt<szHdr ){
366366
if( sslConn ){
367367
#ifdef FOSSIL_ENABLE_SSL
368
- got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt);
368
+ got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369369
#endif
370370
}else{
371371
got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372372
if( got==SOCKET_ERROR ) goto end_request;
373373
}
@@ -394,11 +394,11 @@
394394
if( out==0 ) goto end_request;
395395
fwrite(zBuf, 1, amt, out);
396396
while( wanted>0 ){
397397
if( sslConn ){
398398
#ifdef FOSSIL_ENABLE_SSL
399
- got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
399
+ got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400400
#endif
401401
}else{
402402
got = recv(p->s, zBuf, sizeof(zBuf), 0);
403403
if( got==SOCKET_ERROR ) goto end_request;
404404
}
405405
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button