ruby-lsapi 4.0 → 4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|