272
static void stopProc(void *p)
274
// printf("--- %s draining %d\n",processName,running);
277
mlogf(M_INFO,M_SHOW,"--- %s terminating %d\n",processName,getpid());
254
284
static void handleSigUsr1(int sig)
287
pthread_attr_t tattr;
289
if (stopAccepting == 0) {
291
pthread_attr_init(&tattr);
292
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
293
pthread_create(&t, &tattr, (void *(*)(void *))stopProc,NULL);
259
297
static void freeBuffer(Buffer * b)
261
Buffer emptyBuf = { NULL, NULL, 0, 0, 0, 0, 0 ,0};
299
Buffer emptyBuf = { NULL, NULL, 0, 0, 0, 0, 0 , NULL, NULL, NULL, NULL, NULL, NULL, NULL};
265
303
free(b->content);
334
374
static int readData(CommHndl conn_fd, char *into, int length)
376
int c = 0, r, isReady;
379
FD_SET(conn_fd.socket,&httpfds);
338
381
while (c < length) {
382
isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpSelectTimeout);
339
387
r = commRead(conn_fd, into + c, length - c);
340
388
if (r < 0 && (errno == EINTR || errno == EAGAIN)) {
391
/* r==0 is a success condition for read(), but the loop should complete prior to this */
393
mlogf(M_INFO,M_SHOW,"--- commRead hit EOF sooner than expected\n");
348
static void getPayload(CommHndl conn_fd, Buffer * b)
402
static int getPayload(CommHndl conn_fd, Buffer * b)
350
404
int c = b->length - b->ptr;
351
406
b->content = (char *) malloc(b->content_length + 8);
352
407
if (c) memcpy(b->content, (b->data) + b->ptr, c);
354
readData(conn_fd, (b->content) + c, b->content_length - c);
409
if (c > b->content_length) {
410
mlogf(M_INFO,M_SHOW,"--- HTTP Content-Length is lying; content truncated\n");
411
c = b->content_length;
414
rc = readData(conn_fd, (b->content) + c, b->content_length - c);
355
415
*((b->content) + b->content_length) = 0;
358
419
void dumpResponse(RespSegments * rs)
571
632
#define hdrBufsize 5000
572
633
#define hdrLimmit 5000
574
static int getHdrs(CommHndl conn_fd, Buffer * b, char *cmd)
635
static int getHdrs(CommHndl conn_fd, Buffer * b, char *cmd)
576
637
int first=1,total=0,isReady;
577
struct timeval httpTimeout;
581
641
FD_ZERO(&httpfds);
582
642
FD_SET(conn_fd.socket,&httpfds);
583
httpTimeout.tv_sec=5;
584
httpTimeout.tv_usec=0;
585
isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpTimeout);
586
if (isReady == 0) return 3;
645
isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpSelectTimeout);
646
if (isReady == 0) return 3;
589
648
char buf[hdrBufsize];
590
649
int r = commRead(conn_fd, buf, sizeof(buf));
592
651
if (r < 0 && (errno == EINTR || errno == EAGAIN)) continue;
653
if (b->size == 0) break;
654
if (strstr(b->data, "\r\n\r\n") == NULL &&
655
strstr(b->data, "\n\n") == NULL) {
656
mlogf(M_ERROR,M_SHOW,"-#- HTTP header ended prematurely\n");
595
662
add2buffer(b, buf, r);
597
// fprintf(stderr,"+++ buf: >%s<\n",buf);
665
/* on first run through, ensure that this is a POST req. */
598
666
if (r && first) {
599
667
if (strncasecmp(buf,cmd,strlen(cmd)) != 0) {
600
668
/* not what we expected - still continue to read to
803
if (!discardInput && doBa) {
882
if (!discardInput && doUdsAuth) {
883
struct sockaddr_un sun;
885
socklen_t cl = sizeof(sun);
886
int rc = getpeername(conn_fd.socket, (struct sockaddr*)&sun, &cl);
887
if (rc == 0 && sun.sun_family == AF_UNIX) {
888
/* Already authenticated via permissions on unix socket */
893
if (!authorized && !discardInput && doBa) {
804
894
if (!(inBuf.authorization && baValidate(inBuf.authorization,&inBuf.principal))) {
805
895
char more[]="WWW-Authenticate: Basic realm=\"cimom\"\r\n";
806
896
genError(conn_fd, &inBuf, 401, "Unauthorized", more);
1272
1369
/* still in handshake */
1273
1370
FD_ZERO(&httpfds);
1274
1371
FD_SET(connFd,&httpfds);
1275
httpTimeout.tv_sec=5;
1276
httpTimeout.tv_usec=0;
1277
1372
if (sslerr == SSL_ERROR_WANT_WRITE) {
1278
isReady = select(connFd+1,NULL,&httpfds,NULL,&httpTimeout);
1373
isReady = select(connFd+1,NULL,&httpfds,NULL,&httpSelectTimeout);
1280
isReady = select(connFd+1,&httpfds,NULL,NULL,&httpTimeout);
1375
isReady = select(connFd+1,&httpfds,NULL,NULL,&httpSelectTimeout);
1282
1377
if (isReady == 0) {
1283
1378
intSSLerror("Timeout error accepting SSL connection");
1440
1564
if (sslMode) mlogf(M_INFO,M_SHOW,"--- %s HTTPS Daemon V" sfcHttpDaemonVersion " started - %d - port %ld\n",
1441
1565
name, currentProc,port);
1442
else mlogf(M_INFO,M_SHOW,"--- %s HTTP Daemon V" sfcHttpDaemonVersion " started - %d - port %ld\n",
1443
name, currentProc,port);
1567
else mlogf(M_INFO,M_SHOW,"--- %s HTTP Daemon V" sfcHttpDaemonVersion " started - %d - port %ld, %s\n",
1568
name, currentProc,port,udsPath);
1446
1571
if (doBa) mlogf(M_INFO,M_SHOW,"--- Using Basic Authentication\n");
1573
if (doUdsAuth) mlogf(M_INFO,M_SHOW,"--- Using Unix Socket Peer Cred Authentication\n");
1448
1576
if (keepaliveTimeout == 0) {
1449
1577
mlogf(M_INFO,M_SHOW,"--- Keep-alive timeout disabled\n");
1452
1580
mlogf(M_INFO,M_SHOW,"--- Maximum requests per connection: %ld\n",keepaliveMaxRequest);
1586
udsListenFd = socket(PF_UNIX, SOCK_STREAM, 0);
1589
if (enableHttp || sslMode) {
1455
1590
#ifdef USE_INET6
1456
listenFd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
1458
mlogf(M_INFO,M_SHOW,"--- Using IPv4 address\n");
1459
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
1591
listenFd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
1593
mlogf(M_INFO,M_SHOW,"--- Using IPv4 address\n");
1594
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
1462
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
1597
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
1599
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (char *) &ru, sizeof(ru));
1465
1602
sin_len = sizeof(sin);
1468
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (char *) &ru, sizeof(ru));
1603
sun_len = sizeof(sun);
1470
1605
memset(&sin,0,sin_len);
1472
if (getControlBool("httpLocalOnly", &httpLocalOnly))
1606
memset(&sun,0,sun_len);
1609
if (udsListenFd >= 0) {
1610
if (getControlChars("httpSocketPath", &udsPath)) {
1611
mlogf(M_ERROR,M_SHOW,"--- No unix socket path defined for HTTP\n");
1615
sun.sun_family=AF_UNIX;
1616
strcpy(sun.sun_path,udsPath);
1620
if (listenFd >= 0) {
1621
if (getControlBool("httpLocalOnly", &httpLocalOnly))
1475
1624
#ifdef USE_INET6
1476
sin.sin6_family = AF_INET6;
1478
sin.sin6_addr = in6addr_loopback;
1480
sin.sin6_addr = in6addr_any;
1481
sin.sin6_port = htons(port);
1625
sin.sin6_family = AF_INET6;
1627
sin.sin6_addr = in6addr_loopback;
1629
sin.sin6_addr = in6addr_any;
1630
sin.sin6_port = htons(port);
1483
sin.sin_family = AF_INET;
1484
if (httpLocalOnly) {
1485
char* loopback_int = "127.0.0.1";
1486
inet_aton(loopback_int, &sin.sin_addr); /* not INADDR_LOOPBACK ? */
1489
sin.sin_addr.s_addr = INADDR_ANY;
1490
sin.sin_port = htons(port);
1632
sin.sin_family = AF_INET;
1633
if (httpLocalOnly) {
1634
char* loopback_int = "127.0.0.1";
1635
inet_aton(loopback_int, &sin.sin_addr); /* not INADDR_LOOPBACK ? */
1638
sin.sin_addr.s_addr = INADDR_ANY;
1639
sin.sin_port = htons(port);
1493
if (bind(listenFd, (struct sockaddr *) &sin, sin_len) ||
1494
listen(listenFd, 0)) {
1495
mlogf(M_ERROR,M_SHOW,"--- Cannot listen on port %ld (%s)\n", port, strerror(errno));
1643
if (listenFd >= 0) {
1644
if (bind(listenFd, (struct sockaddr *) &sin, sin_len) ||
1645
listen(listenFd, 10)) {
1646
mlogf(M_ERROR,M_SHOW,"--- Cannot listen on port %ld (%s)\n", port, strerror(errno));
1652
if (udsListenFd >= 0) {
1655
size_t gbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
1657
struct group* pgrp = NULL;
1661
int rc = getgrnam_r("sfcb", &grp, gbuf, gbuflen, &pgrp);
1662
if (rc == 0 && pgrp)
1664
#ifdef HAVE_SYS_FSUID_H
1665
oldfsgid = setfsgid(pgrp->gr_gid);
1667
oldfsgid = setegid(pgrp->gr_gid);
1670
mode_t oldmask = umask(0007);
1671
if (bind(udsListenFd, (struct sockaddr *) &sun, sun_len) ||
1672
listen(udsListenFd, 10)) {
1673
mlogf(M_ERROR,M_SHOW,"--- Cannot listen on unix socket %s (%s)\n", udsPath, strerror(errno));
1680
#ifdef HAVE_SYS_FSUID_H
1501
1690
int rc = fork();
1502
1691
if (rc == -1) {
1554
1743
if (ccVerifyMode != CC_VERIFY_IGNORE &&
1555
1744
SSL_CTX_load_verify_locations(ctx, fnt, NULL) != 1)
1556
1745
intSSLerror("Error locating the client trust store");
1747
/* SSLv2 is pretty old; no one should be needing it any more */
1748
SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 |
1749
SSL_OP_SINGLE_DH_USE);
1750
/* disable weak ciphers */
1751
if (SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
1752
intSSLerror("Error setting cipher list (no valid ciphers)");
1758
maxfdp1 = (listenFd > udsListenFd? listenFd : udsListenFd) + 1;
1760
maxfdp1 = listenFd + 1;
1563
listen(listenFd, 1);
1565
if ((connFd = accept(listenFd, (__SOCKADDR_ARG) & sin, &sz))<0) {
1764
// listen(listenFd, 1);
1766
if (listenFd >= 0) {
1767
FD_SET(listenFd, &httpfds);
1770
if (udsListenFd >= 0) {
1771
FD_SET(udsListenFd, &httpfds);
1774
rc = select(maxfdp1, &httpfds, NULL, NULL, NULL);
1775
if (stopAccepting) break;
1566
1777
if (errno == EINTR || errno == EAGAIN) {
1567
if (stopAccepting) break;
1570
emsg=strerror(errno);
1571
mlogf(M_ERROR,M_SHOW,"--- accept error %s\n",emsg);
1574
_SFCB_TRACE(1, ("--- Processing http request"));
1576
handleHttpRequest(connFd);
1781
if (listenFd >= 0 && FD_ISSET(listenFd, &httpfds)) {
1783
if ((connFd = accept(listenFd, (__SOCKADDR_ARG) &sin, &sz))<0) {
1784
if (errno == EINTR || errno == EAGAIN) {
1787
emsg=strerror(errno);
1788
mlogf(M_ERROR,M_SHOW,"--- accept error %s\n",emsg);
1791
_SFCB_TRACE(1, ("--- Processing http request"));
1793
handleHttpRequest(connFd);
1797
if (udsListenFd >= 0 && FD_ISSET(udsListenFd, &httpfds)) {
1799
if ((connFd = accept(udsListenFd, (__SOCKADDR_ARG) &sun, &sz))<0) {
1800
if (errno == EINTR || errno == EAGAIN) {
1803
emsg=strerror(errno);
1804
mlogf(M_ERROR,M_SHOW,"--- accept error %s\n",emsg);
1807
_SFCB_TRACE(1, ("--- Processing http request"));
1809
handleHttpRequest(connFd);
1582
// printf("--- %s draining %d\n",processName,running);
1585
mlogf(M_INFO,M_SHOW,"--- %s terminating %d\n",processName,getpid());
1593
1822
#if defined USE_SSL