ruby-lsapi 4.0 → 4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/ext/lsapi/lsapidef.h +4 -2
- data/ext/lsapi/lsapilib.c +1129 -99
- data/ext/lsapi/lsapilib.h +45 -16
- data/ext/lsapi/lsruby.c +2 -2
- metadata +23 -36
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZTBmYTY2NTdiZDk3NjAxNTViYmExOTc4ZDU5ZjJhYjk1MmFmNjhiZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YmRkNDNhMGZiMmI5Y2I2YjQ0M2Q4OTkzZWVhMjRkMmFmZjA4ZDFlYQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NTg2NGQ5Zjc1NWUyYTExNDUzMTYzN2VhODAyMDI4N2Y0MDFhMTBiMThkMWNm
|
10
|
+
MWU3NDY0Njg4MzcxZDUyYmYzYjJjMjIyYTUxNGU4YTUyOGQ1ZDIxZDg1YWJh
|
11
|
+
YjZlNDJlNTJhMWJkMzZiOWVjMmE2ODQ2ZGNmMTkzMzk1MDRhMDg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MzBmZDNhMmY5NGQ3NWY0NmJmMDIyMTgzNTUyMDBhZDczMzM2Y2MwY2I5YzAx
|
14
|
+
NGYxN2M0OWEyYTQ1YjYzNTEwNzlmNGQ3ZGY4ZDU1MGM3MTQ2NThlZDkwODBi
|
15
|
+
MjExZWRkOWIxZTI1NGVjMWEwMDNmYzBkNTBjMTBhNmFlZTc5ZTM=
|
data/ext/lsapi/lsapidef.h
CHANGED
@@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
31
|
*/
|
32
32
|
|
33
33
|
/***************************************************************************
|
34
|
-
$Id: lsapidef.h,v 1.
|
34
|
+
$Id: lsapidef.h,v 1.17 2012/12/01 19:23:31 gwang Exp $
|
35
35
|
-------------------
|
36
36
|
begin : Thu Feb 10 2005
|
37
37
|
author : George Wang
|
@@ -100,12 +100,14 @@ enum
|
|
100
100
|
#define LSAPI_RESP_END 5
|
101
101
|
#define LSAPI_STDERR_STREAM 6
|
102
102
|
#define LSAPI_REQ_RECEIVED 7
|
103
|
+
#define LSAPI_CONN_CLOSE 8
|
104
|
+
#define LSAPI_INTERNAL_ERROR 9
|
103
105
|
|
104
106
|
|
105
107
|
#define LSAPI_MAX_HEADER_LEN 65535
|
106
108
|
#define LSAPI_MAX_DATA_PACKET_LEN 16384
|
107
109
|
|
108
|
-
#define LSAPI_RESP_HTTP_HEADER_MAX
|
110
|
+
#define LSAPI_RESP_HTTP_HEADER_MAX 32768
|
109
111
|
#define LSAPI_PACKET_HEADER_LEN 8
|
110
112
|
|
111
113
|
|
data/ext/lsapi/lsapilib.c
CHANGED
@@ -39,17 +39,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
39
39
|
***************************************************************************/
|
40
40
|
|
41
41
|
|
42
|
-
#include <lsapilib.h>
|
43
|
-
|
44
42
|
#include <ctype.h>
|
43
|
+
#include <dlfcn.h>
|
45
44
|
#include <errno.h>
|
46
45
|
#include <fcntl.h>
|
47
46
|
|
48
|
-
#include <
|
49
|
-
#include <netdb.h>
|
50
|
-
#include <netinet/in.h>
|
51
|
-
#include <netinet/tcp.h>
|
52
|
-
#include <sys/un.h>
|
47
|
+
#include <sys/stat.h>
|
53
48
|
#include <signal.h>
|
54
49
|
#include <stdlib.h>
|
55
50
|
#include <stdio.h>
|
@@ -60,8 +55,48 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
60
55
|
#include <sys/time.h>
|
61
56
|
#include <sys/uio.h>
|
62
57
|
#include <sys/wait.h>
|
58
|
+
#include <grp.h>
|
59
|
+
#include <pwd.h>
|
63
60
|
#include <time.h>
|
64
61
|
#include <unistd.h>
|
62
|
+
#include <arpa/inet.h>
|
63
|
+
#include <netdb.h>
|
64
|
+
#include <netinet/in.h>
|
65
|
+
#include <netinet/tcp.h>
|
66
|
+
#include <sys/un.h>
|
67
|
+
|
68
|
+
#include "lsapilib.h"
|
69
|
+
|
70
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
71
|
+
#include <sys/prctl.h>
|
72
|
+
#endif
|
73
|
+
|
74
|
+
#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \
|
75
|
+
|| defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
76
|
+
#include <sys/sysctl.h>
|
77
|
+
#endif
|
78
|
+
|
79
|
+
#include <inttypes.h>
|
80
|
+
#ifndef uint32
|
81
|
+
#define uint32 uint32_t
|
82
|
+
#endif
|
83
|
+
|
84
|
+
struct lsapi_MD5Context {
|
85
|
+
uint32 buf[4];
|
86
|
+
uint32 bits[2];
|
87
|
+
unsigned char in[64];
|
88
|
+
};
|
89
|
+
|
90
|
+
void lsapi_MD5Init(struct lsapi_MD5Context *context);
|
91
|
+
void lsapi_MD5Update(struct lsapi_MD5Context *context, unsigned char const *buf,
|
92
|
+
unsigned len);
|
93
|
+
void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *context);
|
94
|
+
|
95
|
+
/*
|
96
|
+
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
97
|
+
*/
|
98
|
+
typedef struct lsapi_MD5Context lsapi_MD5_CTX;
|
99
|
+
|
65
100
|
|
66
101
|
#define LSAPI_ST_REQ_HEADER 1
|
67
102
|
#define LSAPI_ST_REQ_BODY 2
|
@@ -72,12 +107,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
72
107
|
#define LSAPI_INIT_RESP_HEADER_LEN 4096
|
73
108
|
|
74
109
|
|
110
|
+
|
75
111
|
static int g_inited = 0;
|
76
112
|
static int g_running = 1;
|
77
113
|
static int s_ppid;
|
78
114
|
static int s_slow_req_msecs = 0;
|
115
|
+
static int s_keepListener = 0;
|
116
|
+
static int s_dump_debug_info = 0;
|
117
|
+
|
79
118
|
LSAPI_Request g_req = { -1, -1 };
|
80
119
|
|
120
|
+
static char s_pSecret[24];
|
121
|
+
|
122
|
+
|
81
123
|
void Flush_RespBuf_r( LSAPI_Request * pReq );
|
82
124
|
|
83
125
|
static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
|
@@ -160,6 +202,35 @@ static void lsapi_signal(int signo, sighandler_t handler)
|
|
160
202
|
}
|
161
203
|
|
162
204
|
|
205
|
+
static int s_enable_core_dump = 0;
|
206
|
+
static void lsapi_enable_core_dump()
|
207
|
+
{
|
208
|
+
#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \
|
209
|
+
|| defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
210
|
+
int mib[2];
|
211
|
+
size_t len;
|
212
|
+
|
213
|
+
len = 2;
|
214
|
+
if ( sysctlnametomib("kern.sugid_coredump", mib, &len) == 0 )
|
215
|
+
{
|
216
|
+
len = sizeof(s_enable_core_dump);
|
217
|
+
if (sysctl(mib, 2, NULL, 0, &s_enable_core_dump, len) == -1)
|
218
|
+
perror( "sysctl: Failed to set 'kern.sugid_coredump', "
|
219
|
+
"core dump may not be available!");
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
#endif
|
224
|
+
|
225
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
226
|
+
if (prctl(PR_SET_DUMPABLE, s_enable_core_dump,0,0,0) == -1)
|
227
|
+
perror( "prctl: Failed to set dumpable, "
|
228
|
+
"core dump may not be available!");
|
229
|
+
#endif
|
230
|
+
}
|
231
|
+
|
232
|
+
|
233
|
+
|
163
234
|
static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader,
|
164
235
|
char type, int len )
|
165
236
|
{
|
@@ -202,9 +273,9 @@ static int lsapi_close( int fd )
|
|
202
273
|
}
|
203
274
|
}
|
204
275
|
|
205
|
-
static inline
|
276
|
+
static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
|
206
277
|
{
|
207
|
-
|
278
|
+
ssize_t ret;
|
208
279
|
while( 1 )
|
209
280
|
{
|
210
281
|
ret = read( fd, (char *)pBuf, len );
|
@@ -251,7 +322,7 @@ static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
|
|
251
322
|
return totalLen - left;
|
252
323
|
while( ret > 0 )
|
253
324
|
{
|
254
|
-
if ( (*pVec)->iov_len <= ret )
|
325
|
+
if ( (*pVec)->iov_len <= (unsigned int )ret )
|
255
326
|
{
|
256
327
|
ret -= (*pVec)->iov_len;
|
257
328
|
++(*pVec);
|
@@ -475,8 +546,426 @@ static void fixHeaderIndexEndian( LSAPI_Request * pReq )
|
|
475
546
|
swapIntEndian( &pCur->valueLen );
|
476
547
|
++pCur;
|
477
548
|
}
|
478
|
-
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
|
552
|
+
static uid_t s_uid = 0;
|
553
|
+
static uid_t s_defaultUid; //web server need set this
|
554
|
+
static gid_t s_defaultGid;
|
555
|
+
|
556
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
557
|
+
|
558
|
+
#define LSAPI_LVE_DISABLED 0
|
559
|
+
#define LSAPI_LVE_ENABLED 1
|
560
|
+
#define LSAPI_CAGEFS_ENABLED 2
|
561
|
+
#define LSAPI_CAGEFS_NO_SUEXEC 3
|
562
|
+
struct liblve;
|
563
|
+
static int s_enable_lve = LSAPI_LVE_DISABLED;
|
564
|
+
static struct liblve * s_lve = NULL;
|
565
|
+
|
566
|
+
static void *s_liblve;
|
567
|
+
static int (*fp_lve_is_available)(void) = NULL;
|
568
|
+
static int (*fp_lve_instance_init)(struct liblve *) = NULL;
|
569
|
+
static int (*fp_lve_destroy)(struct liblve *) = NULL;
|
570
|
+
static int (*fp_lve_enter)(struct liblve *, uint32_t, int32_t, int32_t, uint32_t *) = NULL;
|
571
|
+
static int (*fp_lve_leave)(struct liblve *, uint32_t *) = NULL;
|
572
|
+
static int (*fp_lve_jail)( struct passwd *, char *) = NULL;
|
573
|
+
static int lsapi_load_lve_lib()
|
574
|
+
{
|
575
|
+
s_liblve = dlopen("liblve.so.0", RTLD_LAZY);
|
576
|
+
if (s_liblve)
|
577
|
+
{
|
578
|
+
fp_lve_is_available = dlsym(s_liblve, "lve_is_available");
|
579
|
+
if (dlerror() == NULL)
|
580
|
+
{
|
581
|
+
if ( !(*fp_lve_is_available)() )
|
582
|
+
{
|
583
|
+
int uid = getuid();
|
584
|
+
if ( uid )
|
585
|
+
{
|
586
|
+
setreuid( s_uid, uid );
|
587
|
+
if ( !(*fp_lve_is_available)() )
|
588
|
+
s_enable_lve = 0;
|
589
|
+
setreuid( uid, s_uid );
|
590
|
+
}
|
591
|
+
}
|
592
|
+
}
|
593
|
+
}
|
594
|
+
else
|
595
|
+
{
|
596
|
+
s_enable_lve = LSAPI_LVE_DISABLED;
|
597
|
+
}
|
598
|
+
return (s_liblve)? 0 : -1;
|
599
|
+
}
|
600
|
+
|
601
|
+
static int init_lve_ex()
|
602
|
+
{
|
603
|
+
int rc;
|
604
|
+
if ( !s_liblve )
|
605
|
+
return -1;
|
606
|
+
fp_lve_instance_init = dlsym(s_liblve, "lve_instance_init");
|
607
|
+
fp_lve_destroy = dlsym(s_liblve, "lve_destroy");
|
608
|
+
fp_lve_enter = dlsym(s_liblve, "lve_enter");
|
609
|
+
fp_lve_leave = dlsym(s_liblve, "lve_leave");
|
610
|
+
if ( s_enable_lve >= LSAPI_CAGEFS_ENABLED )
|
611
|
+
fp_lve_jail = dlsym(s_liblve, "jail" );
|
612
|
+
|
613
|
+
if ( s_lve == NULL )
|
614
|
+
{
|
615
|
+
rc = (*fp_lve_instance_init)(NULL);
|
616
|
+
s_lve = malloc(rc);
|
617
|
+
}
|
618
|
+
rc = (*fp_lve_instance_init)(s_lve);
|
619
|
+
if (rc != 0)
|
620
|
+
{
|
621
|
+
perror( "LSAPI: Unable to initialize LVE" );
|
622
|
+
free( s_lve );
|
623
|
+
s_lve = NULL;
|
624
|
+
return -1;
|
625
|
+
}
|
626
|
+
return 0;
|
627
|
+
|
628
|
+
}
|
629
|
+
|
630
|
+
#endif
|
631
|
+
|
632
|
+
|
633
|
+
|
634
|
+
static int readSecret( const char * pSecretFile )
|
635
|
+
{
|
636
|
+
struct stat st;
|
637
|
+
int fd = open( pSecretFile, O_RDONLY , 0600 );
|
638
|
+
if ( fd == -1 )
|
639
|
+
{
|
640
|
+
fprintf( stderr, "LSAPI: failed to open secret file: %s!\n", pSecretFile );
|
641
|
+
return -1;
|
642
|
+
}
|
643
|
+
if ( fstat( fd, &st ) == -1 )
|
644
|
+
{
|
645
|
+
fprintf( stderr, "LSAPI: failed to check state of file: %s!\n", pSecretFile );
|
646
|
+
close( fd );
|
647
|
+
return -1;
|
648
|
+
}
|
649
|
+
/*
|
650
|
+
if ( st.st_uid != s_uid )
|
651
|
+
{
|
652
|
+
fprintf( stderr, "LSAPI: file owner check failure: %s!\n", pSecretFile );
|
653
|
+
close( fd );
|
654
|
+
return -1;
|
655
|
+
}
|
656
|
+
*/
|
657
|
+
if ( st.st_mode & 0077 )
|
658
|
+
{
|
659
|
+
fprintf( stderr, "LSAPI: file permission check failure: %s\n", pSecretFile );
|
660
|
+
close( fd );
|
661
|
+
return -1;
|
662
|
+
}
|
663
|
+
if ( read( fd, s_pSecret, 16 ) < 16 )
|
664
|
+
{
|
665
|
+
fprintf( stderr, "LSAPI: failed to read secret from secret file: %s\n", pSecretFile );
|
666
|
+
close( fd );
|
667
|
+
return -1;
|
668
|
+
}
|
669
|
+
close( fd );
|
670
|
+
return 0;
|
671
|
+
}
|
672
|
+
|
673
|
+
static int lsapi_initSuEXEC()
|
674
|
+
{
|
675
|
+
int i;
|
676
|
+
struct passwd * pw;
|
677
|
+
pw = getpwnam( "nobody" );
|
678
|
+
s_defaultUid = pw->pw_uid;
|
679
|
+
s_defaultGid = pw->pw_gid;
|
680
|
+
if ( s_uid == 0 )
|
681
|
+
{
|
682
|
+
const char * p = getenv( "LSAPI_DEFAULT_UID" );
|
683
|
+
if ( p )
|
684
|
+
{
|
685
|
+
i = atoi( p );
|
686
|
+
if ( i > 0 )
|
687
|
+
s_defaultUid = i;
|
688
|
+
}
|
689
|
+
p = getenv( "LSAPI_DEFAULT_GID" );
|
690
|
+
if ( p )
|
691
|
+
{
|
692
|
+
i = atoi( p );
|
693
|
+
if ( i > 0 )
|
694
|
+
s_defaultGid = i;
|
695
|
+
}
|
696
|
+
p = getenv( "LSAPI_SECRET" );
|
697
|
+
if (( !p )||( readSecret(p) == -1 ))
|
698
|
+
return -1;
|
699
|
+
}
|
700
|
+
return 0;
|
701
|
+
}
|
702
|
+
|
703
|
+
int LSAPI_is_suEXEC_Daemon()
|
704
|
+
{
|
705
|
+
if (( !s_uid )&&( s_pSecret[0] ))
|
706
|
+
return 1;
|
707
|
+
else
|
708
|
+
return 0;
|
709
|
+
}
|
710
|
+
|
711
|
+
static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 )
|
712
|
+
{
|
713
|
+
char achError[1024];
|
714
|
+
int n = snprintf(achError, 1024, "%s:%s: %s\n", pErr1, (pErr2)?pErr2:"", strerror( errno ) );
|
715
|
+
if ( pReq )
|
716
|
+
LSAPI_Write_Stderr_r( pReq, achError, n );
|
717
|
+
else
|
718
|
+
write( STDERR_FILENO, achError, n );
|
719
|
+
return 0;
|
720
|
+
}
|
721
|
+
|
722
|
+
static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid )
|
723
|
+
{
|
724
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
725
|
+
if ( s_lve && uid ) //root user should not do that
|
726
|
+
{
|
727
|
+
uint32_t cookie;
|
728
|
+
int ret = -1;
|
729
|
+
ret = (*fp_lve_enter)(s_lve, uid, -1, -1, &cookie);
|
730
|
+
if ( ret < 0 )
|
731
|
+
{
|
732
|
+
fprintf( stderr, "Pid (%d): enter LVE (%d) : ressult: %d !\n", getpid(), uid, ret );
|
733
|
+
LSAPI_perror_r(pReq, "LSAPI: lve_enter() failure, reached resource limit.", NULL );
|
734
|
+
return -1;
|
735
|
+
}
|
736
|
+
}
|
737
|
+
#endif
|
738
|
+
|
739
|
+
return 0;
|
740
|
+
}
|
741
|
+
|
742
|
+
static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw )
|
743
|
+
{
|
744
|
+
int ret = 0;
|
745
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
746
|
+
char error_msg[1024] = "";
|
747
|
+
ret = (*fp_lve_jail)( pw, error_msg );
|
748
|
+
if ( ret < 0 )
|
749
|
+
{
|
750
|
+
fprintf( stderr, "LSAPI (%d): LVE jail(%d) ressult: %d, error: %s !\n",
|
751
|
+
getpid(), uid, ret, error_msg );
|
752
|
+
LSAPI_perror_r( pReq, "LSAPI: jail() failure.", NULL );
|
753
|
+
return -1;
|
754
|
+
}
|
755
|
+
#endif
|
756
|
+
return ret;
|
757
|
+
}
|
758
|
+
|
759
|
+
|
760
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
761
|
+
static int lsapi_initLVE()
|
762
|
+
{
|
763
|
+
const char * pEnv;
|
764
|
+
if ( (pEnv = getenv( "LSAPI_LVE_ENABLE" ))!= NULL )
|
765
|
+
{
|
766
|
+
s_enable_lve = atol( pEnv );
|
767
|
+
pEnv = NULL;
|
768
|
+
}
|
769
|
+
else if ( (pEnv = getenv( "LVE_ENABLE" ))!= NULL )
|
770
|
+
{
|
771
|
+
s_enable_lve = atol( pEnv );
|
772
|
+
pEnv = NULL;
|
773
|
+
}
|
774
|
+
if ( s_enable_lve && !s_uid )
|
775
|
+
{
|
776
|
+
lsapi_load_lve_lib();
|
777
|
+
if ( s_enable_lve )
|
778
|
+
{
|
779
|
+
return init_lve_ex();
|
780
|
+
}
|
781
|
+
|
782
|
+
}
|
783
|
+
return 0;
|
479
784
|
}
|
785
|
+
#endif
|
786
|
+
|
787
|
+
|
788
|
+
static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * pChroot)
|
789
|
+
{
|
790
|
+
int rv;
|
791
|
+
struct passwd * pw;
|
792
|
+
pw = getpwuid( uid );
|
793
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
794
|
+
if ( s_lve )
|
795
|
+
{
|
796
|
+
if( lsapi_enterLVE( pReq, uid ) == -1 )
|
797
|
+
return -1;
|
798
|
+
if ( pw && fp_lve_jail)
|
799
|
+
{
|
800
|
+
rv = lsapi_jailLVE( pReq, uid, pw );
|
801
|
+
if ( rv == -1 )
|
802
|
+
return -1;
|
803
|
+
if (( rv == 1 )&&(s_enable_lve == LSAPI_CAGEFS_NO_SUEXEC )) //this mode only use cageFS, does not use suEXEC
|
804
|
+
{
|
805
|
+
uid = s_defaultUid;
|
806
|
+
gid = s_defaultGid;
|
807
|
+
pw = getpwuid( uid );
|
808
|
+
}
|
809
|
+
}
|
810
|
+
}
|
811
|
+
#endif
|
812
|
+
//if ( !uid || !gid ) //do not allow root
|
813
|
+
//{
|
814
|
+
// return -1;
|
815
|
+
//}
|
816
|
+
|
817
|
+
#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \
|
818
|
+
|| defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
819
|
+
if ( s_enable_core_dump )
|
820
|
+
lsapi_enable_core_dump();
|
821
|
+
#endif
|
822
|
+
|
823
|
+
rv = setgid(gid);
|
824
|
+
if (rv == -1)
|
825
|
+
{
|
826
|
+
LSAPI_perror_r(pReq, "LSAPI: setgid()", NULL);
|
827
|
+
return -1;
|
828
|
+
}
|
829
|
+
if ( pw && (pw->pw_gid == gid ))
|
830
|
+
{
|
831
|
+
rv = initgroups( pw->pw_name, gid );
|
832
|
+
if (rv == -1)
|
833
|
+
{
|
834
|
+
LSAPI_perror_r(pReq, "LSAPI: initgroups()", NULL);
|
835
|
+
return -1;
|
836
|
+
}
|
837
|
+
}
|
838
|
+
else
|
839
|
+
{
|
840
|
+
rv = setgroups(1, &gid);
|
841
|
+
if (rv == -1)
|
842
|
+
{
|
843
|
+
LSAPI_perror_r(pReq, "LSAPI: setgroups()", NULL);
|
844
|
+
}
|
845
|
+
}
|
846
|
+
if ( pChroot )
|
847
|
+
{
|
848
|
+
rv = chroot( pChroot );
|
849
|
+
if ( rv == -1 )
|
850
|
+
{
|
851
|
+
LSAPI_perror_r(pReq, "LSAPI: chroot()", NULL);
|
852
|
+
return -1;
|
853
|
+
}
|
854
|
+
}
|
855
|
+
rv = setuid(uid);
|
856
|
+
if (rv == -1)
|
857
|
+
{
|
858
|
+
LSAPI_perror_r(pReq, "LSAPI: setuid()", NULL);
|
859
|
+
return -1;
|
860
|
+
}
|
861
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
862
|
+
if ( s_enable_core_dump )
|
863
|
+
lsapi_enable_core_dump();
|
864
|
+
#endif
|
865
|
+
return 0;
|
866
|
+
}
|
867
|
+
|
868
|
+
static int lsapi_suexec_auth( LSAPI_Request *pReq,
|
869
|
+
char * pAuth, int len, char * pUgid, int ugidLen )
|
870
|
+
{
|
871
|
+
lsapi_MD5_CTX md5ctx;
|
872
|
+
unsigned char achMD5[16];
|
873
|
+
if ( len < 32 )
|
874
|
+
return -1;
|
875
|
+
memmove( achMD5, pAuth + 16, 16 );
|
876
|
+
memmove( pAuth + 16, s_pSecret, 16 );
|
877
|
+
lsapi_MD5Init( &md5ctx );
|
878
|
+
lsapi_MD5Update( &md5ctx, (unsigned char *)pAuth, 32 );
|
879
|
+
lsapi_MD5Update( &md5ctx, (unsigned char *)pUgid, 8 );
|
880
|
+
lsapi_MD5Final( (unsigned char *)pAuth + 16, &md5ctx);
|
881
|
+
if ( memcmp( achMD5, pAuth + 16, 16 ) == 0 )
|
882
|
+
return 0;
|
883
|
+
return 1;
|
884
|
+
}
|
885
|
+
|
886
|
+
|
887
|
+
static int lsapi_changeUGid( LSAPI_Request * pReq )
|
888
|
+
{
|
889
|
+
int uid = s_defaultUid;
|
890
|
+
int gid = s_defaultGid;
|
891
|
+
const char * pChroot = NULL;
|
892
|
+
struct LSAPI_key_value_pair * pEnv;
|
893
|
+
struct LSAPI_key_value_pair * pAuth;
|
894
|
+
int i;
|
895
|
+
if ( s_uid )
|
896
|
+
return 0;
|
897
|
+
//with special ID 0x00
|
898
|
+
//authenticate the suEXEC request;
|
899
|
+
//first one should be MD5( nonce + lscgid secret )
|
900
|
+
//remember to clear the secret after verification
|
901
|
+
//it should be set at the end of special env
|
902
|
+
i = pReq->m_pHeader->m_cntSpecialEnv - 1;
|
903
|
+
if ( i >= 0 )
|
904
|
+
{
|
905
|
+
pEnv = pReq->m_pSpecialEnvList + i;
|
906
|
+
if (( *pEnv->pKey == '\000' )&&
|
907
|
+
( strcmp( pEnv->pKey+1, "SUEXEC_AUTH" ) == 0 ))
|
908
|
+
{
|
909
|
+
--pReq->m_pHeader->m_cntSpecialEnv;
|
910
|
+
pAuth = pEnv--;
|
911
|
+
if (( *pEnv->pKey == '\000' )&&
|
912
|
+
( strcmp( pEnv->pKey+1, "SUEXEC_UGID" ) == 0 ))
|
913
|
+
{
|
914
|
+
--pReq->m_pHeader->m_cntSpecialEnv;
|
915
|
+
uid = *(uint32_t *)pEnv->pValue;
|
916
|
+
gid = *(((uint32_t *)pEnv->pValue) + 1 );
|
917
|
+
//fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid );
|
918
|
+
}
|
919
|
+
else
|
920
|
+
{
|
921
|
+
fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" );
|
922
|
+
pEnv = NULL;
|
923
|
+
}
|
924
|
+
if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 )
|
925
|
+
{
|
926
|
+
//read UID, GID from specialEnv
|
927
|
+
|
928
|
+
}
|
929
|
+
else
|
930
|
+
{
|
931
|
+
//authentication error
|
932
|
+
fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" );
|
933
|
+
uid = 0;
|
934
|
+
}
|
935
|
+
}
|
936
|
+
else
|
937
|
+
{
|
938
|
+
//fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" );
|
939
|
+
}
|
940
|
+
}
|
941
|
+
|
942
|
+
|
943
|
+
if ( !uid )
|
944
|
+
{
|
945
|
+
uid = s_defaultUid;
|
946
|
+
gid = s_defaultGid;
|
947
|
+
}
|
948
|
+
|
949
|
+
//change uid
|
950
|
+
if ( setUID_LVE( pReq, uid, gid, pChroot ) == -1 )
|
951
|
+
{
|
952
|
+
return -1;
|
953
|
+
}
|
954
|
+
|
955
|
+
s_uid = uid;
|
956
|
+
|
957
|
+
return 0;
|
958
|
+
|
959
|
+
}
|
960
|
+
|
961
|
+
static int parseContentLenFromHeader(LSAPI_Request * pReq)
|
962
|
+
{
|
963
|
+
const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH );
|
964
|
+
if ( pContentLen )
|
965
|
+
pReq->m_reqBodyLen = strtoll( pContentLen, NULL, 10 );
|
966
|
+
return 0;
|
967
|
+
}
|
968
|
+
|
480
969
|
|
481
970
|
static int parseRequest( LSAPI_Request * pReq, int totalLen )
|
482
971
|
{
|
@@ -523,13 +1012,21 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
|
|
523
1012
|
pReq->m_pHttpHeader = pBegin;
|
524
1013
|
pBegin += pReq->m_pHeader->m_httpHeaderLen;
|
525
1014
|
if ( pBegin != pEnd )
|
1015
|
+
{
|
1016
|
+
fprintf( stderr, "%d: request header does match total size, total: %d, real: %ld\n", getpid(), totalLen,
|
1017
|
+
pBegin - pReq->m_pReqBuf );
|
526
1018
|
return -1;
|
527
|
-
|
1019
|
+
}
|
528
1020
|
if ( shouldFixEndian )
|
529
1021
|
{
|
530
1022
|
fixHeaderIndexEndian( pReq );
|
531
1023
|
}
|
532
|
-
|
1024
|
+
pReq->m_reqBodyLen = pReq->m_pHeader->m_reqBodyLen;
|
1025
|
+
if ( pReq->m_reqBodyLen == -2 )
|
1026
|
+
{
|
1027
|
+
parseContentLenFromHeader(pReq);
|
1028
|
+
}
|
1029
|
+
|
533
1030
|
return 0;
|
534
1031
|
}
|
535
1032
|
|
@@ -546,11 +1043,45 @@ static inline int notify_req_received( int fd )
|
|
546
1043
|
return 0;
|
547
1044
|
}
|
548
1045
|
|
1046
|
+
static inline int lsapi_notify_pid( int fd )
|
1047
|
+
{
|
1048
|
+
char achBuf[16];
|
1049
|
+
lsapi_buildPacketHeader( (struct lsapi_packet_header *)achBuf, LSAPI_STDERR_STREAM,
|
1050
|
+
8 + LSAPI_PACKET_HEADER_LEN );
|
1051
|
+
memmove( &achBuf[8], "\0PID", 4 );
|
1052
|
+
*((int *)&achBuf[12]) = getpid();
|
1053
|
+
|
1054
|
+
if ( write( fd, achBuf, 16 ) < 16 )
|
1055
|
+
return -1;
|
1056
|
+
return 0;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
static char s_conn_key_packet[16];
|
1060
|
+
static inline int init_conn_key( int fd )
|
1061
|
+
{
|
1062
|
+
struct lsapi_packet_header * pHeader = (struct lsapi_packet_header *)s_conn_key_packet;
|
1063
|
+
struct timeval tv;
|
1064
|
+
int i;
|
1065
|
+
gettimeofday( &tv, NULL );
|
1066
|
+
srand( (tv.tv_sec % 0x1000 + tv.tv_usec) ^ rand() );
|
1067
|
+
for( i = 8; i < 16; ++i )
|
1068
|
+
{
|
1069
|
+
s_conn_key_packet[i]=(int) (256.0*rand()/(RAND_MAX+1.0));
|
1070
|
+
}
|
1071
|
+
lsapi_buildPacketHeader( pHeader, LSAPI_REQ_RECEIVED,
|
1072
|
+
8 + LSAPI_PACKET_HEADER_LEN );
|
1073
|
+
if ( write( fd, s_conn_key_packet, LSAPI_PACKET_HEADER_LEN+8 )
|
1074
|
+
< LSAPI_PACKET_HEADER_LEN+8 )
|
1075
|
+
return -1;
|
1076
|
+
return 0;
|
1077
|
+
|
1078
|
+
|
1079
|
+
}
|
549
1080
|
|
550
1081
|
static int readReq( LSAPI_Request * pReq )
|
551
1082
|
{
|
552
|
-
|
553
|
-
|
1083
|
+
int len;
|
1084
|
+
int packetLen;
|
554
1085
|
if ( !pReq )
|
555
1086
|
return -1;
|
556
1087
|
if ( pReq->m_reqBufSize < 8192 )
|
@@ -570,9 +1101,15 @@ static int readReq( LSAPI_Request * pReq )
|
|
570
1101
|
|
571
1102
|
packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST );
|
572
1103
|
if ( packetLen < 0 )
|
1104
|
+
{
|
1105
|
+
fprintf( stderr, "%d: packetLen < 0\n", getpid() );
|
573
1106
|
return -1;
|
1107
|
+
}
|
574
1108
|
if ( packetLen > LSAPI_MAX_HEADER_LEN )
|
1109
|
+
{
|
1110
|
+
fprintf( stderr, "%d: packetLen > %d\n", getpid(), LSAPI_MAX_HEADER_LEN );
|
575
1111
|
return -1;
|
1112
|
+
}
|
576
1113
|
|
577
1114
|
if ( packetLen + 1024 > pReq->m_reqBufSize )
|
578
1115
|
{
|
@@ -587,7 +1124,13 @@ static int readReq( LSAPI_Request * pReq )
|
|
587
1124
|
pReq->m_bufRead += len;
|
588
1125
|
}
|
589
1126
|
if ( parseRequest( pReq, packetLen ) < 0 )
|
1127
|
+
{
|
1128
|
+
fprintf( stderr, "%d: parseRequest error\n", getpid() );
|
590
1129
|
return -1;
|
1130
|
+
}
|
1131
|
+
if ( !s_uid )
|
1132
|
+
if ( lsapi_changeUGid( pReq ) )
|
1133
|
+
return -1;
|
591
1134
|
pReq->m_bufProcessed = packetLen;
|
592
1135
|
pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER;
|
593
1136
|
|
@@ -604,6 +1147,8 @@ int LSAPI_Init(void)
|
|
604
1147
|
{
|
605
1148
|
if ( !g_inited )
|
606
1149
|
{
|
1150
|
+
s_uid = geteuid();
|
1151
|
+
s_pSecret[0] = 0;
|
607
1152
|
lsapi_signal(SIGPIPE, lsapi_sigpipe);
|
608
1153
|
lsapi_signal(SIGUSR1, lsapi_siguser1);
|
609
1154
|
|
@@ -683,6 +1228,7 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
|
|
683
1228
|
return -1;
|
684
1229
|
if ( LSAPI_Finish_r( pReq ) == -1 )
|
685
1230
|
return -1;
|
1231
|
+
lsapi_set_nblock( pReq->m_fdListen , 0 );
|
686
1232
|
while( g_running )
|
687
1233
|
{
|
688
1234
|
if ( pReq->m_fd == -1 )
|
@@ -707,9 +1253,11 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
|
|
707
1253
|
setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
708
1254
|
(char *)&nodelay, sizeof(nodelay));
|
709
1255
|
}
|
1256
|
+
//init_conn_key( pReq->m_fd );
|
710
1257
|
//OPTIMIZATION
|
711
1258
|
if ( s_accept_notify )
|
712
|
-
|
1259
|
+
if ( notify_req_received( pReq->m_fd ) == -1 )
|
1260
|
+
return -1;
|
713
1261
|
}
|
714
1262
|
}
|
715
1263
|
else
|
@@ -717,6 +1265,7 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
|
|
717
1265
|
}
|
718
1266
|
if ( !readReq( pReq ) )
|
719
1267
|
break;
|
1268
|
+
//abort();
|
720
1269
|
lsapi_close( pReq->m_fd );
|
721
1270
|
pReq->m_fd = -1;
|
722
1271
|
LSAPI_Reset_r( pReq );
|
@@ -799,13 +1348,13 @@ char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
|
|
799
1348
|
|
800
1349
|
static int readBodyToReqBuf( LSAPI_Request * pReq )
|
801
1350
|
{
|
802
|
-
|
803
|
-
|
1351
|
+
off_t bodyLeft;
|
1352
|
+
ssize_t len = pReq->m_bufRead - pReq->m_bufProcessed;
|
804
1353
|
if ( len > 0 )
|
805
1354
|
return len;
|
806
1355
|
pReq->m_bufRead = pReq->m_bufProcessed = pReq->m_pHeader->m_pktHeader.m_packetLen.m_iLen;
|
807
1356
|
|
808
|
-
bodyLeft = pReq->
|
1357
|
+
bodyLeft = pReq->m_reqBodyLen - pReq->m_reqBodyRead;
|
809
1358
|
len = pReq->m_reqBufSize - pReq->m_bufRead;
|
810
1359
|
if ( len < 0 )
|
811
1360
|
return -1;
|
@@ -834,10 +1383,10 @@ int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq )
|
|
834
1383
|
|
835
1384
|
|
836
1385
|
|
837
|
-
int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf,
|
1386
|
+
int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF )
|
838
1387
|
{
|
839
|
-
|
840
|
-
|
1388
|
+
ssize_t len;
|
1389
|
+
ssize_t left;
|
841
1390
|
char * pBufEnd = pBuf + bufLen - 1;
|
842
1391
|
char * pBufCur = pBuf;
|
843
1392
|
char * pCur;
|
@@ -881,15 +1430,15 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *
|
|
881
1430
|
}
|
882
1431
|
|
883
1432
|
|
884
|
-
|
1433
|
+
ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen )
|
885
1434
|
{
|
886
|
-
|
887
|
-
|
1435
|
+
ssize_t len;
|
1436
|
+
off_t total;
|
888
1437
|
/* char *pOldBuf = pBuf; */
|
889
1438
|
if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 ))
|
890
1439
|
return -1;
|
891
1440
|
|
892
|
-
total = pReq->
|
1441
|
+
total = pReq->m_reqBodyLen - pReq->m_reqBodyRead;
|
893
1442
|
|
894
1443
|
if ( total <= 0 )
|
895
1444
|
return 0;
|
@@ -930,14 +1479,14 @@ int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen )
|
|
930
1479
|
}
|
931
1480
|
|
932
1481
|
|
933
|
-
|
1482
|
+
ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
|
934
1483
|
{
|
935
1484
|
struct lsapi_packet_header * pHeader;
|
936
1485
|
const char * pEnd;
|
937
1486
|
const char * p;
|
938
|
-
|
939
|
-
|
940
|
-
|
1487
|
+
ssize_t bufLen;
|
1488
|
+
ssize_t toWrite;
|
1489
|
+
ssize_t packetLen;
|
941
1490
|
int skip = 0;
|
942
1491
|
|
943
1492
|
if ( !pReq || !pBuf || (pReq->m_fd == -1) )
|
@@ -1015,6 +1564,95 @@ int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len )
|
|
1015
1564
|
return p - pBuf;
|
1016
1565
|
}
|
1017
1566
|
|
1567
|
+
#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__)
|
1568
|
+
ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
|
1569
|
+
{
|
1570
|
+
ssize_t ret;
|
1571
|
+
off_t written;
|
1572
|
+
ret = sendfile( fdIn, fdOut, *off, size, NULL, &written, 0 );
|
1573
|
+
if ( written > 0 )
|
1574
|
+
{
|
1575
|
+
ret = written;
|
1576
|
+
*off += ret;
|
1577
|
+
}
|
1578
|
+
return ret;
|
1579
|
+
}
|
1580
|
+
#endif
|
1581
|
+
|
1582
|
+
#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
1583
|
+
ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size )
|
1584
|
+
{
|
1585
|
+
ssize_t ret;
|
1586
|
+
off_t len = size;
|
1587
|
+
ret = sendfile( fdIn, fdOut, *off, &len, NULL, 0 );
|
1588
|
+
if (( ret == 0 )&&( len > 0 ))
|
1589
|
+
{
|
1590
|
+
ret = len;
|
1591
|
+
*off += len;
|
1592
|
+
}
|
1593
|
+
return ret;
|
1594
|
+
}
|
1595
|
+
#endif
|
1596
|
+
|
1597
|
+
#if defined(sun) || defined(__sun)
|
1598
|
+
#include <sys/sendfile.h>
|
1599
|
+
ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size )
|
1600
|
+
{
|
1601
|
+
int n = 0 ;
|
1602
|
+
sendfilevec_t vec[1];
|
1603
|
+
|
1604
|
+
vec[n].sfv_fd = fdIn;
|
1605
|
+
vec[n].sfv_flag = 0;
|
1606
|
+
vec[n].sfv_off = *off;
|
1607
|
+
vec[n].sfv_len = size;
|
1608
|
+
++n;
|
1609
|
+
|
1610
|
+
size_t written;
|
1611
|
+
ssize_t ret = ::sendfilev( fdOut, vec, n, &written );
|
1612
|
+
if (( !ret )||( errno == EAGAIN ))
|
1613
|
+
ret = written;
|
1614
|
+
if ( ret > 0 )
|
1615
|
+
*off += ret;
|
1616
|
+
return ret;
|
1617
|
+
}
|
1618
|
+
#endif
|
1619
|
+
|
1620
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || \
|
1621
|
+
defined(__gnu_linux__)
|
1622
|
+
#include <sys/sendfile.h>
|
1623
|
+
#define gsendfile sendfile
|
1624
|
+
#endif
|
1625
|
+
#if defined(HPUX)
|
1626
|
+
ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size )
|
1627
|
+
{
|
1628
|
+
return sendfile( fdOut, fdIn, off, size, NULL, 0 );
|
1629
|
+
}
|
1630
|
+
#endif
|
1631
|
+
|
1632
|
+
ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size )
|
1633
|
+
{
|
1634
|
+
struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
|
1635
|
+
if ( !pReq || (pReq->m_fd == -1) || fdIn == -1 )
|
1636
|
+
return -1;
|
1637
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
|
1638
|
+
{
|
1639
|
+
LSAPI_FinalizeRespHeaders_r( pReq );
|
1640
|
+
}
|
1641
|
+
pReq->m_reqState |= LSAPI_ST_RESP_BODY;
|
1642
|
+
|
1643
|
+
LSAPI_Flush_r(pReq);
|
1644
|
+
|
1645
|
+
lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
|
1646
|
+
size + LSAPI_PACKET_HEADER_LEN );
|
1647
|
+
|
1648
|
+
|
1649
|
+
if (write(pReq->m_fd, (const char *) pHeader, LSAPI_PACKET_HEADER_LEN ) != LSAPI_PACKET_HEADER_LEN)
|
1650
|
+
return -1;
|
1651
|
+
|
1652
|
+
return gsendfile( pReq->m_fd, fdIn, off, size );
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
|
1018
1656
|
void Flush_RespBuf_r( LSAPI_Request * pReq )
|
1019
1657
|
{
|
1020
1658
|
struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
|
@@ -1085,13 +1723,13 @@ int LSAPI_Flush_r( LSAPI_Request * pReq )
|
|
1085
1723
|
}
|
1086
1724
|
|
1087
1725
|
|
1088
|
-
|
1726
|
+
ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t len )
|
1089
1727
|
{
|
1090
1728
|
struct lsapi_packet_header header;
|
1091
1729
|
const char * pEnd;
|
1092
1730
|
const char * p;
|
1093
|
-
|
1094
|
-
|
1731
|
+
ssize_t packetLen;
|
1732
|
+
ssize_t totalLen;
|
1095
1733
|
int ret;
|
1096
1734
|
struct iovec iov[2];
|
1097
1735
|
struct iovec *pIov;
|
@@ -1200,6 +1838,20 @@ char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name )
|
|
1200
1838
|
return NULL;
|
1201
1839
|
}
|
1202
1840
|
|
1841
|
+
struct _headerInfo
|
1842
|
+
{
|
1843
|
+
const char * _name;
|
1844
|
+
int _nameLen;
|
1845
|
+
const char * _value;
|
1846
|
+
int _valueLen;
|
1847
|
+
};
|
1848
|
+
|
1849
|
+
int compareValueLocation(const void * v1, const void *v2 )
|
1850
|
+
{
|
1851
|
+
return ((const struct _headerInfo *)v1)->_value -
|
1852
|
+
((const struct _headerInfo *)v2)->_value;
|
1853
|
+
}
|
1854
|
+
|
1203
1855
|
int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
|
1204
1856
|
LSAPI_CB_EnvHandler fn, void * arg )
|
1205
1857
|
{
|
@@ -1208,8 +1860,10 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
|
|
1208
1860
|
char * pValue;
|
1209
1861
|
int ret;
|
1210
1862
|
int count = 0;
|
1863
|
+
struct _headerInfo headers[512];
|
1211
1864
|
if ( !pReq || !fn )
|
1212
1865
|
return -1;
|
1866
|
+
|
1213
1867
|
for( i = 0; i < H_TRANSFER_ENCODING; ++i )
|
1214
1868
|
{
|
1215
1869
|
if ( pReq->m_pHeaderIndex->m_headerOff[i] )
|
@@ -1217,11 +1871,16 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
|
|
1217
1871
|
len = pReq->m_pHeaderIndex->m_headerLen[i];
|
1218
1872
|
pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
|
1219
1873
|
*(pValue + len ) = 0;
|
1220
|
-
|
1221
|
-
|
1874
|
+
headers[count]._name = HTTP_HEADERS[i];
|
1875
|
+
headers[count]._nameLen = HTTP_HEADER_LEN[i];
|
1876
|
+
headers[count]._value = pValue;
|
1877
|
+
headers[count]._valueLen = len;
|
1222
1878
|
++count;
|
1223
|
-
|
1224
|
-
|
1879
|
+
|
1880
|
+
//ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i],
|
1881
|
+
// pValue, len, arg );
|
1882
|
+
//if ( ret <= 0 )
|
1883
|
+
// return ret;
|
1225
1884
|
}
|
1226
1885
|
}
|
1227
1886
|
if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 )
|
@@ -1238,14 +1897,29 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq,
|
|
1238
1897
|
|
1239
1898
|
pValue = pReq->m_pHttpHeader + pCur->valueOff;
|
1240
1899
|
*(pValue + pCur->valueLen ) = 0;
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1900
|
+
headers[count]._name = pKey;
|
1901
|
+
headers[count]._nameLen = keyLen;
|
1902
|
+
headers[count]._value = pValue;
|
1903
|
+
headers[count]._valueLen = pCur->valueLen;
|
1904
|
+
++count;
|
1905
|
+
if ( count == 512 )
|
1906
|
+
break;
|
1907
|
+
//ret = (*fn)( pKey, keyLen,
|
1908
|
+
// pValue, pCur->valueLen, arg );
|
1909
|
+
//if ( ret <= 0 )
|
1910
|
+
// return ret;
|
1245
1911
|
++pCur;
|
1246
1912
|
}
|
1247
1913
|
}
|
1248
|
-
|
1914
|
+
qsort( headers, count, sizeof( struct _headerInfo ), compareValueLocation );
|
1915
|
+
for( i = 0; i < count; ++i )
|
1916
|
+
{
|
1917
|
+
ret = (*fn)( headers[i]._name, headers[i]._nameLen,
|
1918
|
+
headers[i]._value, headers[i]._valueLen, arg );
|
1919
|
+
if ( ret <= 0 )
|
1920
|
+
return ret;
|
1921
|
+
}
|
1922
|
+
return count;
|
1249
1923
|
|
1250
1924
|
}
|
1251
1925
|
|
@@ -1288,11 +1962,11 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
|
|
1288
1962
|
{
|
1289
1963
|
pKey = pReq->m_pHttpHeader + pCur->nameOff;
|
1290
1964
|
keyLen = pCur->nameLen;
|
1965
|
+
if ( keyLen > 250 )
|
1966
|
+
keyLen = 250;
|
1291
1967
|
pKeyEnd = pKey + keyLen;
|
1292
1968
|
memcpy( achHeaderName, "HTTP_", 5 );
|
1293
1969
|
p = &achHeaderName[5];
|
1294
|
-
if ( keyLen > 250 )
|
1295
|
-
keyLen = 250;
|
1296
1970
|
|
1297
1971
|
while( pKey < pKeyEnd )
|
1298
1972
|
{
|
@@ -1397,9 +2071,64 @@ int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
|
|
1397
2071
|
}
|
1398
2072
|
|
1399
2073
|
|
2074
|
+
int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
|
2075
|
+
const char * pHeaderValue )
|
2076
|
+
{
|
2077
|
+
int nameLen, valLen, len;
|
2078
|
+
if ( !pReq || !pHeaderName || !pHeaderValue )
|
2079
|
+
return -1;
|
2080
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_BODY )
|
2081
|
+
return -1;
|
2082
|
+
if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS )
|
2083
|
+
return -1;
|
2084
|
+
nameLen = strlen( pHeaderName );
|
2085
|
+
valLen = strlen( pHeaderValue );
|
2086
|
+
if ( nameLen == 0 )
|
2087
|
+
return -1;
|
2088
|
+
while( nameLen > 0 )
|
2089
|
+
{
|
2090
|
+
char ch = *(pHeaderName + nameLen - 1 );
|
2091
|
+
if (( ch == '\n' )||( ch == '\r' ))
|
2092
|
+
--nameLen;
|
2093
|
+
else
|
2094
|
+
break;
|
2095
|
+
}
|
2096
|
+
if ( nameLen <= 0 )
|
2097
|
+
return 0;
|
2098
|
+
while( valLen > 0 )
|
2099
|
+
{
|
2100
|
+
char ch = *(pHeaderValue + valLen - 1 );
|
2101
|
+
if (( ch == '\n' )||( ch == '\r' ))
|
2102
|
+
--valLen;
|
2103
|
+
else
|
2104
|
+
break;
|
2105
|
+
}
|
2106
|
+
len = nameLen + valLen + 1;
|
2107
|
+
if ( len > LSAPI_RESP_HTTP_HEADER_MAX )
|
2108
|
+
return -1;
|
2109
|
+
|
2110
|
+
if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd )
|
2111
|
+
{
|
2112
|
+
int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf;
|
2113
|
+
newlen -= newlen % 4096;
|
2114
|
+
if ( allocateRespHeaderBuf( pReq, newlen ) == -1 )
|
2115
|
+
return -1;
|
2116
|
+
}
|
2117
|
+
memmove( pReq->m_pRespHeaderBufPos, pHeaderName, nameLen );
|
2118
|
+
pReq->m_pRespHeaderBufPos += nameLen;
|
2119
|
+
*pReq->m_pRespHeaderBufPos++ = ':';
|
2120
|
+
memmove( pReq->m_pRespHeaderBufPos, pHeaderValue, valLen );
|
2121
|
+
pReq->m_pRespHeaderBufPos += valLen;
|
2122
|
+
*pReq->m_pRespHeaderBufPos++ = 0;
|
2123
|
+
++len; /* add one byte padding for \0 */
|
2124
|
+
pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len;
|
2125
|
+
++pReq->m_respHeader.m_respInfo.m_cntHeaders;
|
2126
|
+
return 0;
|
2127
|
+
}
|
2128
|
+
|
1400
2129
|
|
1401
2130
|
|
1402
|
-
int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len )
|
2131
|
+
int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len )
|
1403
2132
|
{
|
1404
2133
|
if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX )
|
1405
2134
|
return -1;
|
@@ -1494,7 +2223,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
|
|
1494
2223
|
if ( !pBind )
|
1495
2224
|
return -1;
|
1496
2225
|
|
1497
|
-
while( isspace( *
|
2226
|
+
while( isspace( *pBind ) )
|
1498
2227
|
++pBind;
|
1499
2228
|
|
1500
2229
|
strncpy( achAddr, pBind, 256 );
|
@@ -1551,7 +2280,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr )
|
|
1551
2280
|
++pEnd;
|
1552
2281
|
|
1553
2282
|
port = atoi( pEnd );
|
1554
|
-
if (( port <= 0 )||( port >
|
2283
|
+
if (( port <= 0 )||( port > 65535 ))
|
1555
2284
|
return -1;
|
1556
2285
|
if ( doAddrInfo )
|
1557
2286
|
{
|
@@ -1597,9 +2326,11 @@ static fn_select_t g_fnSelect = select;
|
|
1597
2326
|
typedef struct _lsapi_child_status
|
1598
2327
|
{
|
1599
2328
|
int m_pid;
|
2329
|
+
long m_tmStart;
|
1600
2330
|
|
1601
2331
|
volatile short m_iKillSent;
|
1602
2332
|
volatile short m_inProcess;
|
2333
|
+
volatile int m_iReqCounter;
|
1603
2334
|
|
1604
2335
|
volatile long m_tmWaitBegin;
|
1605
2336
|
volatile long m_tmReqBegin;
|
@@ -1629,6 +2360,7 @@ static lsapi_prefork_server * g_prefork_server = NULL;
|
|
1629
2360
|
|
1630
2361
|
int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
|
1631
2362
|
{
|
2363
|
+
int pid;
|
1632
2364
|
if ( g_prefork_server )
|
1633
2365
|
return 0;
|
1634
2366
|
if ( max_children <= 1 )
|
@@ -1646,11 +2378,15 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
|
|
1646
2378
|
g_fnSelect = fp;
|
1647
2379
|
|
1648
2380
|
s_ppid = getppid();
|
2381
|
+
pid = getpid();
|
2382
|
+
setpgid( pid, pid );
|
1649
2383
|
g_prefork_server->m_iAvoidFork = avoidFork;
|
1650
2384
|
g_prefork_server->m_iMaxChildren = max_children;
|
1651
2385
|
|
1652
2386
|
g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ;
|
1653
2387
|
g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3);
|
2388
|
+
if ( g_prefork_server->m_iMaxIdleChildren == 0 )
|
2389
|
+
g_prefork_server->m_iMaxIdleChildren = 1;
|
1654
2390
|
g_prefork_server->m_iChildrenMaxIdleTime = 300;
|
1655
2391
|
g_prefork_server->m_iMaxReqProcessTime = 300;
|
1656
2392
|
return 0;
|
@@ -1679,9 +2415,10 @@ static int lsapi_accept( int fdListen )
|
|
1679
2415
|
setsockopt( fd, IPPROTO_TCP, TCP_NODELAY,
|
1680
2416
|
(char *)&nodelay, sizeof(nodelay));
|
1681
2417
|
}
|
2418
|
+
|
1682
2419
|
//OPTIMIZATION
|
1683
|
-
if ( s_accept_notify )
|
1684
|
-
|
2420
|
+
//if ( s_accept_notify )
|
2421
|
+
// notify_req_received( fd );
|
1685
2422
|
}
|
1686
2423
|
return fd;
|
1687
2424
|
|
@@ -1727,10 +2464,18 @@ static void lsapi_sigchild( int signal )
|
|
1727
2464
|
{
|
1728
2465
|
break;
|
1729
2466
|
}
|
2467
|
+
if ( WIFSIGNALED( status ))
|
2468
|
+
{
|
2469
|
+
int sig_num = WTERMSIG( status );
|
2470
|
+
int dump = WCOREDUMP( status );
|
2471
|
+
fprintf( stderr, "Child process with pid: %d was killed by signal: %d, core dump: %d\n", pid, sig_num, dump );
|
2472
|
+
}
|
1730
2473
|
child_status = find_child_status( pid );
|
1731
2474
|
if ( child_status )
|
2475
|
+
{
|
1732
2476
|
child_status->m_pid = 0;
|
1733
|
-
|
2477
|
+
--g_prefork_server->m_iCurChildren;
|
2478
|
+
}
|
1734
2479
|
}
|
1735
2480
|
|
1736
2481
|
}
|
@@ -1754,70 +2499,87 @@ static int lsapi_init_children_status()
|
|
1754
2499
|
return 0;
|
1755
2500
|
}
|
1756
2501
|
|
2502
|
+
static void dump_debug_info( lsapi_child_status * pStatus, long tmCur )
|
2503
|
+
{
|
2504
|
+
char achCmd[1024];
|
2505
|
+
int pid = fork();
|
2506
|
+
if ( pid != 0 )
|
2507
|
+
return;
|
2508
|
+
fprintf( stderr, "[%s] Possible runaway process, PPID: %d, PID: %d, reqCount: %d, process time: %ld, checkpoint time: %ld, start time: %ld\n",
|
2509
|
+
ctime(&tmCur), getpid(), pStatus->m_pid, pStatus->m_iReqCounter,
|
2510
|
+
tmCur - pStatus->m_tmReqBegin, tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart );
|
2511
|
+
snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" -ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2", pStatus->m_pid, pStatus->m_pid );
|
2512
|
+
if ( system( achCmd ) == -1 )
|
2513
|
+
perror( "system()" );
|
2514
|
+
exit( 0 );
|
2515
|
+
}
|
2516
|
+
|
1757
2517
|
static void lsapi_check_child_status( long tmCur )
|
1758
2518
|
{
|
1759
2519
|
int idle = 0;
|
1760
2520
|
int tobekilled;
|
1761
2521
|
int dying = 0;
|
2522
|
+
int count = 0;
|
1762
2523
|
lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus;
|
1763
2524
|
lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2;
|
1764
2525
|
while( pStatus < pEnd )
|
1765
2526
|
{
|
1766
|
-
tobekilled =
|
2527
|
+
tobekilled = 0;
|
1767
2528
|
if ( pStatus->m_pid != 0 )
|
1768
2529
|
{
|
1769
|
-
|
2530
|
+
++count;
|
2531
|
+
if ( !pStatus->m_inProcess )
|
1770
2532
|
{
|
1771
|
-
|
2533
|
+
|
2534
|
+
if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)||
|
2535
|
+
( idle > g_prefork_server->m_iMaxIdleChildren ))
|
1772
2536
|
{
|
1773
|
-
|
1774
|
-
if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)||
|
1775
|
-
( idle >= g_prefork_server->m_iMaxIdleChildren ))
|
1776
|
-
{
|
1777
|
-
tobekilled = 1;
|
1778
|
-
}
|
1779
|
-
else
|
1780
|
-
{
|
1781
|
-
if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 ))
|
1782
|
-
tobekilled = 1;
|
1783
|
-
}
|
1784
|
-
if ( !tobekilled )
|
1785
|
-
++idle;
|
2537
|
+
tobekilled = SIGUSR1;
|
1786
2538
|
}
|
1787
2539
|
else
|
1788
2540
|
{
|
1789
|
-
if ( tmCur - pStatus->
|
1790
|
-
|
1791
|
-
tobekilled =
|
2541
|
+
if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 ))
|
2542
|
+
{
|
2543
|
+
tobekilled = SIGUSR1;
|
2544
|
+
}
|
1792
2545
|
}
|
2546
|
+
if ( !tobekilled )
|
2547
|
+
++idle;
|
1793
2548
|
}
|
1794
2549
|
else
|
1795
2550
|
{
|
1796
|
-
if ( pStatus->
|
1797
|
-
|
2551
|
+
if ( tmCur - pStatus->m_tmReqBegin >
|
2552
|
+
g_prefork_server->m_iMaxReqProcessTime )
|
2553
|
+
{
|
2554
|
+
if (( ( pStatus->m_iKillSent % 5 ) == 0 )&&( s_dump_debug_info ))
|
2555
|
+
dump_debug_info( pStatus, tmCur );
|
2556
|
+
if ( pStatus->m_iKillSent > 5 )
|
2557
|
+
{
|
2558
|
+
tobekilled = SIGKILL;
|
2559
|
+
fprintf( stderr, "Force killing runaway process PID: %d with SIGKILL\n", pStatus->m_pid );
|
2560
|
+
}
|
2561
|
+
else
|
2562
|
+
{
|
2563
|
+
tobekilled = SIGTERM;
|
2564
|
+
fprintf( stderr, "Killing runaway process PID: %d with SIGTERM\n", pStatus->m_pid );
|
2565
|
+
}
|
2566
|
+
}
|
1798
2567
|
}
|
1799
2568
|
if ( tobekilled )
|
1800
2569
|
{
|
1801
|
-
tobekilled
|
1802
|
-
if ( pStatus->m_iKillSent > 5 )
|
1803
|
-
tobekilled = SIGKILL;
|
1804
|
-
else if ( pStatus->m_iKillSent == 3 )
|
1805
|
-
tobekilled = SIGTERM;
|
1806
|
-
else if ( pStatus->m_iKillSent == 1 )
|
1807
|
-
{
|
1808
|
-
tobekilled = SIGUSR1;
|
1809
|
-
}
|
1810
|
-
if ( tobekilled )
|
1811
|
-
kill( pStatus->m_pid, tobekilled );
|
2570
|
+
kill( pStatus->m_pid, tobekilled );
|
1812
2571
|
++pStatus->m_iKillSent;
|
1813
2572
|
++dying;
|
1814
2573
|
}
|
1815
|
-
|
1816
2574
|
}
|
1817
|
-
else
|
1818
|
-
++dying;
|
1819
2575
|
++pStatus;
|
1820
2576
|
}
|
2577
|
+
if ( g_prefork_server->m_iCurChildren != count )
|
2578
|
+
{
|
2579
|
+
fprintf( stderr, "Children tracking is wrong: PID: %d, Cur Childen: %d, count: %d, idle: %d, dying: %d\n", getpid(),
|
2580
|
+
g_prefork_server->m_iCurChildren, count, idle, dying );
|
2581
|
+
|
2582
|
+
}
|
1821
2583
|
}
|
1822
2584
|
|
1823
2585
|
static int lsapi_all_children_must_die()
|
@@ -1880,10 +2642,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1880
2642
|
s_stop = 0;
|
1881
2643
|
while( !s_stop )
|
1882
2644
|
{
|
1883
|
-
|
1884
|
-
curTime = time( NULL );
|
1885
|
-
else
|
1886
|
-
++curTime;
|
2645
|
+
curTime = time( NULL );
|
1887
2646
|
if (curTime != lastTime )
|
1888
2647
|
{
|
1889
2648
|
lastTime = curTime;
|
@@ -1914,6 +2673,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1914
2673
|
timeout.tv_sec = 1; timeout.tv_usec = 0;
|
1915
2674
|
if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 )
|
1916
2675
|
{
|
2676
|
+
/*
|
1917
2677
|
if ( pServer->m_iCurChildren >= 0 )
|
1918
2678
|
{
|
1919
2679
|
usleep( 10 );
|
@@ -1922,7 +2682,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1922
2682
|
timeout.tv_sec = 0; timeout.tv_usec = 0;
|
1923
2683
|
if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 )
|
1924
2684
|
continue;
|
1925
|
-
}
|
2685
|
+
}*/
|
1926
2686
|
}
|
1927
2687
|
else if ( ret == -1 )
|
1928
2688
|
{
|
@@ -1940,6 +2700,8 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1940
2700
|
if ( pReq->m_fd != -1 )
|
1941
2701
|
{
|
1942
2702
|
child_status = find_child_status( 0 );
|
2703
|
+
if ( child_status )
|
2704
|
+
memset( child_status, 0, sizeof( *child_status ) );
|
1943
2705
|
pid = fork();
|
1944
2706
|
if ( !pid )
|
1945
2707
|
{
|
@@ -1947,15 +2709,22 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1947
2709
|
s_ppid = getppid();
|
1948
2710
|
s_req_processed = 0;
|
1949
2711
|
s_pChildStatus = child_status;
|
1950
|
-
child_status->m_iKillSent = 0;
|
1951
2712
|
lsapi_set_nblock( pReq->m_fd, 0 );
|
1952
|
-
|
2713
|
+
if ( pReq->m_fdListen != -1 )
|
2714
|
+
{
|
2715
|
+
close( pReq->m_fdListen );
|
2716
|
+
pReq->m_fdListen = -1;
|
2717
|
+
}
|
1953
2718
|
/* don't catch our signals */
|
1954
2719
|
sigaction( SIGCHLD, &old_child, 0 );
|
1955
2720
|
sigaction( SIGTERM, &old_term, 0 );
|
1956
2721
|
sigaction( SIGQUIT, &old_quit, 0 );
|
1957
2722
|
sigaction( SIGINT, &old_int, 0 );
|
1958
2723
|
sigaction( SIGUSR1, &old_usr1, 0 );
|
2724
|
+
//init_conn_key( pReq->m_fd );
|
2725
|
+
lsapi_notify_pid( pReq->m_fd );
|
2726
|
+
if ( s_accept_notify )
|
2727
|
+
return notify_req_received( pReq->m_fd );
|
1959
2728
|
return 0;
|
1960
2729
|
}
|
1961
2730
|
else if ( pid == -1 )
|
@@ -1968,8 +2737,8 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1968
2737
|
if ( child_status )
|
1969
2738
|
{
|
1970
2739
|
child_status->m_pid = pid;
|
1971
|
-
child_status->
|
1972
|
-
child_status->
|
2740
|
+
child_status->m_tmWaitBegin = curTime;
|
2741
|
+
child_status->m_tmStart = curTime;
|
1973
2742
|
}
|
1974
2743
|
}
|
1975
2744
|
close( pReq->m_fd );
|
@@ -1991,7 +2760,7 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
|
|
1991
2760
|
|
1992
2761
|
}
|
1993
2762
|
|
1994
|
-
void lsapi_error( char * pMessage, int err_no )
|
2763
|
+
void lsapi_error( const char * pMessage, int err_no )
|
1995
2764
|
{
|
1996
2765
|
fprintf( stderr, "%d: %s, errno: %d (%s)\n", getpid(), pMessage, err_no, strerror( err_no ) );
|
1997
2766
|
}
|
@@ -2020,6 +2789,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
|
|
2020
2789
|
{
|
2021
2790
|
s_pChildStatus->m_tmWaitBegin = time( NULL );
|
2022
2791
|
}
|
2792
|
+
|
2023
2793
|
|
2024
2794
|
while( g_running )
|
2025
2795
|
{
|
@@ -2031,8 +2801,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
|
|
2031
2801
|
fd = pReq->m_fdListen;
|
2032
2802
|
else
|
2033
2803
|
{
|
2034
|
-
|
2035
|
-
return -1;
|
2804
|
+
break;
|
2036
2805
|
}
|
2037
2806
|
wait_secs = 0;
|
2038
2807
|
while( 1 )
|
@@ -2076,6 +2845,15 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
|
|
2076
2845
|
{
|
2077
2846
|
fd = pReq->m_fd;
|
2078
2847
|
lsapi_set_nblock( fd, 0 );
|
2848
|
+
//init_conn_key( pReq->m_fd );
|
2849
|
+
if ( !s_keepListener )
|
2850
|
+
{
|
2851
|
+
close( pReq->m_fdListen );
|
2852
|
+
pReq->m_fdListen = -1;
|
2853
|
+
}
|
2854
|
+
if ( s_accept_notify )
|
2855
|
+
if ( notify_req_received( pReq->m_fd ) == -1 )
|
2856
|
+
return -1;
|
2079
2857
|
}
|
2080
2858
|
else
|
2081
2859
|
{
|
@@ -2094,7 +2872,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
|
|
2094
2872
|
{
|
2095
2873
|
if ( s_pChildStatus )
|
2096
2874
|
{
|
2875
|
+
s_pChildStatus->m_iKillSent = 0;
|
2097
2876
|
s_pChildStatus->m_inProcess = 1;
|
2877
|
+
++s_pChildStatus->m_iReqCounter;
|
2098
2878
|
s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL);
|
2099
2879
|
}
|
2100
2880
|
++s_req_processed;
|
@@ -2176,7 +2956,8 @@ static void unset_lsapi_envs()
|
|
2176
2956
|
#endif
|
2177
2957
|
while( env != NULL && *env != NULL )
|
2178
2958
|
{
|
2179
|
-
if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 )
|
2959
|
+
if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 )
|
2960
|
+
|| (!strncmp( *env, "PHPRC=", 6 )&&(!s_uid)))
|
2180
2961
|
{
|
2181
2962
|
char ** del = env;
|
2182
2963
|
do
|
@@ -2188,7 +2969,7 @@ static void unset_lsapi_envs()
|
|
2188
2969
|
}
|
2189
2970
|
}
|
2190
2971
|
|
2191
|
-
|
2972
|
+
int LSAPI_Init_Env_Parameters( fn_select_t fp )
|
2192
2973
|
{
|
2193
2974
|
const char *p;
|
2194
2975
|
int n;
|
@@ -2229,6 +3010,9 @@ void LSAPI_Init_Env_Parameters( fn_select_t fp )
|
|
2229
3010
|
struct rlimit limit = { 0, 0 };
|
2230
3011
|
setrlimit( RLIMIT_CORE, &limit );
|
2231
3012
|
}
|
3013
|
+
else
|
3014
|
+
s_enable_core_dump = 1;
|
3015
|
+
|
2232
3016
|
#endif
|
2233
3017
|
|
2234
3018
|
p = getenv( "LSAPI_MAX_IDLE" );
|
@@ -2238,6 +3022,14 @@ void LSAPI_Init_Env_Parameters( fn_select_t fp )
|
|
2238
3022
|
LSAPI_Set_Max_Idle( n );
|
2239
3023
|
}
|
2240
3024
|
|
3025
|
+
p = getenv( "LSAPI_KEEP_LISTEN" );
|
3026
|
+
if ( p )
|
3027
|
+
{
|
3028
|
+
n = atoi( p );
|
3029
|
+
s_keepListener = n;
|
3030
|
+
}
|
3031
|
+
|
3032
|
+
|
2241
3033
|
if ( LSAPI_Is_Listen() )
|
2242
3034
|
{
|
2243
3035
|
n = 0;
|
@@ -2274,8 +3066,246 @@ void LSAPI_Init_Env_Parameters( fn_select_t fp )
|
|
2274
3066
|
{
|
2275
3067
|
LSAPI_No_Check_ppid();
|
2276
3068
|
}
|
3069
|
+
|
3070
|
+
p = getenv( "LSAPI_DUMP_DEBUG_INFO" );
|
3071
|
+
if ( p )
|
3072
|
+
s_dump_debug_info = atoi( p );
|
3073
|
+
|
3074
|
+
if ( lsapi_initSuEXEC() == -1 )
|
3075
|
+
return -1;
|
3076
|
+
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__)
|
3077
|
+
lsapi_initLVE();
|
3078
|
+
#endif
|
2277
3079
|
}
|
2278
3080
|
unset_lsapi_envs();
|
3081
|
+
return 0;
|
3082
|
+
}
|
3083
|
+
|
3084
|
+
|
3085
|
+
|
3086
|
+
|
3087
|
+
|
3088
|
+
static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16]);
|
3089
|
+
|
3090
|
+
/*
|
3091
|
+
* Note: this code is harmless on little-endian machines.
|
3092
|
+
*/
|
3093
|
+
static void byteReverse(unsigned char *buf, unsigned longs)
|
3094
|
+
{
|
3095
|
+
uint32 t;
|
3096
|
+
do {
|
3097
|
+
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
3098
|
+
((unsigned) buf[1] << 8 | buf[0]);
|
3099
|
+
*(uint32 *) buf = t;
|
3100
|
+
buf += 4;
|
3101
|
+
} while (--longs);
|
2279
3102
|
}
|
2280
3103
|
|
3104
|
+
/*
|
3105
|
+
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
3106
|
+
* initialization constants.
|
3107
|
+
*/
|
3108
|
+
void lsapi_MD5Init(struct lsapi_MD5Context *ctx)
|
3109
|
+
{
|
3110
|
+
ctx->buf[0] = 0x67452301;
|
3111
|
+
ctx->buf[1] = 0xefcdab89;
|
3112
|
+
ctx->buf[2] = 0x98badcfe;
|
3113
|
+
ctx->buf[3] = 0x10325476;
|
3114
|
+
|
3115
|
+
ctx->bits[0] = 0;
|
3116
|
+
ctx->bits[1] = 0;
|
3117
|
+
}
|
3118
|
+
|
3119
|
+
/*
|
3120
|
+
* Update context to reflect the concatenation of another buffer full
|
3121
|
+
* of bytes.
|
3122
|
+
*/
|
3123
|
+
void lsapi_MD5Update(struct lsapi_MD5Context *ctx, unsigned char const *buf, unsigned len)
|
3124
|
+
{
|
3125
|
+
register uint32 t;
|
3126
|
+
|
3127
|
+
/* Update bitcount */
|
3128
|
+
|
3129
|
+
t = ctx->bits[0];
|
3130
|
+
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
3131
|
+
ctx->bits[1]++; /* Carry from low to high */
|
3132
|
+
ctx->bits[1] += len >> 29;
|
3133
|
+
|
3134
|
+
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
3135
|
+
|
3136
|
+
/* Handle any leading odd-sized chunks */
|
3137
|
+
|
3138
|
+
if (t) {
|
3139
|
+
unsigned char *p = (unsigned char *) ctx->in + t;
|
3140
|
+
|
3141
|
+
t = 64 - t;
|
3142
|
+
if (len < t) {
|
3143
|
+
memmove(p, buf, len);
|
3144
|
+
return;
|
3145
|
+
}
|
3146
|
+
memmove(p, buf, t);
|
3147
|
+
byteReverse(ctx->in, 16);
|
3148
|
+
lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
3149
|
+
buf += t;
|
3150
|
+
len -= t;
|
3151
|
+
}
|
3152
|
+
/* Process data in 64-byte chunks */
|
3153
|
+
|
3154
|
+
while (len >= 64) {
|
3155
|
+
memmove(ctx->in, buf, 64);
|
3156
|
+
byteReverse(ctx->in, 16);
|
3157
|
+
lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
3158
|
+
buf += 64;
|
3159
|
+
len -= 64;
|
3160
|
+
}
|
3161
|
+
|
3162
|
+
/* Handle any remaining bytes of data. */
|
3163
|
+
|
3164
|
+
memmove(ctx->in, buf, len);
|
3165
|
+
}
|
3166
|
+
|
3167
|
+
/*
|
3168
|
+
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
3169
|
+
* 1 0* (64-bit count of bits processed, MSB-first)
|
3170
|
+
*/
|
3171
|
+
void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *ctx)
|
3172
|
+
{
|
3173
|
+
unsigned int count;
|
3174
|
+
unsigned char *p;
|
3175
|
+
|
3176
|
+
/* Compute number of bytes mod 64 */
|
3177
|
+
count = (ctx->bits[0] >> 3) & 0x3F;
|
3178
|
+
|
3179
|
+
/* Set the first char of padding to 0x80. This is safe since there is
|
3180
|
+
always at least one byte free */
|
3181
|
+
p = ctx->in + count;
|
3182
|
+
*p++ = 0x80;
|
3183
|
+
|
3184
|
+
/* Bytes of padding needed to make 64 bytes */
|
3185
|
+
count = 64 - 1 - count;
|
3186
|
+
|
3187
|
+
/* Pad out to 56 mod 64 */
|
3188
|
+
if (count < 8) {
|
3189
|
+
/* Two lots of padding: Pad the first block to 64 bytes */
|
3190
|
+
memset(p, 0, count);
|
3191
|
+
byteReverse(ctx->in, 16);
|
3192
|
+
lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
3193
|
+
|
3194
|
+
/* Now fill the next block with 56 bytes */
|
3195
|
+
memset(ctx->in, 0, 56);
|
3196
|
+
} else {
|
3197
|
+
/* Pad block to 56 bytes */
|
3198
|
+
memset(p, 0, count - 8);
|
3199
|
+
}
|
3200
|
+
byteReverse(ctx->in, 14);
|
3201
|
+
|
3202
|
+
/* Append length in bits and transform */
|
3203
|
+
((uint32 *) ctx->in)[14] = ctx->bits[0];
|
3204
|
+
((uint32 *) ctx->in)[15] = ctx->bits[1];
|
3205
|
+
|
3206
|
+
lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
3207
|
+
byteReverse((unsigned char *) ctx->buf, 4);
|
3208
|
+
memmove(digest, ctx->buf, 16);
|
3209
|
+
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
3210
|
+
}
|
3211
|
+
|
3212
|
+
/* The four core functions - F1 is optimized somewhat */
|
3213
|
+
|
3214
|
+
/* #define F1(x, y, z) (x & y | ~x & z) */
|
3215
|
+
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
3216
|
+
#define F2(x, y, z) F1(z, x, y)
|
3217
|
+
#define F3(x, y, z) (x ^ y ^ z)
|
3218
|
+
#define F4(x, y, z) (y ^ (x | ~z))
|
3219
|
+
|
3220
|
+
/* This is the central step in the MD5 algorithm. */
|
3221
|
+
#define MD5STEP(f, w, x, y, z, data, s) \
|
3222
|
+
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
3223
|
+
|
3224
|
+
/*
|
3225
|
+
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
3226
|
+
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
3227
|
+
* the data and converts bytes into longwords for this routine.
|
3228
|
+
*/
|
3229
|
+
static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16])
|
3230
|
+
{
|
3231
|
+
register uint32 a, b, c, d;
|
3232
|
+
|
3233
|
+
a = buf[0];
|
3234
|
+
b = buf[1];
|
3235
|
+
c = buf[2];
|
3236
|
+
d = buf[3];
|
3237
|
+
|
3238
|
+
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
3239
|
+
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
3240
|
+
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
3241
|
+
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
3242
|
+
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
3243
|
+
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
3244
|
+
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
3245
|
+
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
3246
|
+
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
3247
|
+
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
3248
|
+
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
3249
|
+
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
3250
|
+
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
3251
|
+
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
3252
|
+
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
3253
|
+
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
3254
|
+
|
3255
|
+
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
3256
|
+
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
3257
|
+
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
3258
|
+
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
3259
|
+
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
3260
|
+
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
3261
|
+
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
3262
|
+
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
3263
|
+
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
3264
|
+
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
3265
|
+
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
3266
|
+
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
3267
|
+
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
3268
|
+
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
3269
|
+
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
3270
|
+
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
3271
|
+
|
3272
|
+
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
3273
|
+
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
3274
|
+
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
3275
|
+
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
3276
|
+
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
3277
|
+
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
3278
|
+
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
3279
|
+
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
3280
|
+
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
3281
|
+
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
3282
|
+
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
3283
|
+
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
3284
|
+
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
3285
|
+
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
3286
|
+
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
3287
|
+
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
3288
|
+
|
3289
|
+
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
3290
|
+
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
3291
|
+
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
3292
|
+
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
3293
|
+
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
3294
|
+
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
3295
|
+
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
3296
|
+
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
3297
|
+
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
3298
|
+
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
3299
|
+
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
3300
|
+
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
3301
|
+
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
3302
|
+
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
3303
|
+
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
3304
|
+
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
3305
|
+
|
3306
|
+
buf[0] += a;
|
3307
|
+
buf[1] += b;
|
3308
|
+
buf[2] += c;
|
3309
|
+
buf[3] += d;
|
3310
|
+
}
|
2281
3311
|
|