ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:27.58 GB of 70.42 GB (39.17%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ src/ courier-0.66.1/ tcpd/ - drwxrwxrwx

Directory:
Viewing file:     tlscache.c (12.21 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 2002 Double Precision, Inc.
** See COPYING for distribution information.
*/
#include    "config.h"
#include    "numlib/numlib.h"
#include    "liblock/config.h"
#include    "liblock/liblock.h"
#include    <stdio.h>
#include    <string.h>
#include    <stdlib.h>
#include    <errno.h>
#include    <ctype.h>

#if HAVE_SYS_STAT_H
#include    <sys/stat.h>
#endif
#if HAVE_FCNTL_H
#include    <fcntl.h>
#endif

#include    "tlscache.h"


/*
** The cache file begins with the following record:
*/

struct hdr {
    off_t filesize;        /* Size of the file, don't trust fstat */
    off_t head, tail;    /* Head and tail ptrs */
    off_t first;        /* See below */
};

#ifndef TLSCACHEMINSIZE
#define TLSCACHEMINSIZE 16384
#endif

#define BORK(p) BORK2(__LINE__, (p))

static void BORK2(int l, const char *p)
{
    fprintf(stderr, "ALERT: tlscache.c(%d): corruption detected in %s\n",
        (l), (p));
}

/*
** Cached SSL session objects are written starting at the end of the file
** the file, growing to the beginning of the file.  The head pointer
** points to the most recently added cached object.  When the beginning of
** the file is reached, it's wrapped around.
**
** After the wraparound, old SSL session objects are freed. starting with
** the tail ptr, to make room for newer object.  There may be unused space
** between struct hdr, and the first cached object, the 'first' pointer
** helps me find the first cached object, when searching.
** When searching for a cached object, begin at the head ptr (most recent,
** and continue until we find an object referenced by the tail ptr).
**
** Each cached object carries the following header.
*/

struct obj {
    size_t prev_size;    /* Size of the previous cached object,
                ** this must be the first member of this
                ** struct.
                */

    size_t my_size;        /* Size of this cached object */
};

/* Read cnt number of bytes, or else */

static int my_read(int fd, void *buffer, size_t cnt)
{
    char *p=(char *)buffer;

    while (cnt > 0)
    {
        int n=read(fd, p, cnt);

        if (n <= 0)
            return n;
        p += n;
        cnt -= n;
    }
    return 1;
}

/* Write cnt number of bytes, or else */

static int my_write(int fd, const void *buffer, size_t cnt)
{
    const char *p=(const char *)buffer;

    while (cnt > 0)
    {
        int n=write(fd, p, cnt);

        if (n <= 0)
            return -1;
        p += n;
        cnt -= n;
    }
    return 0;
}

static int init(struct CACHE *, off_t s);

void tls_cache_close(struct CACHE *p)
{
    if (p->filename != NULL)
        free(p->filename);
    if (p->fd >= 0)
        close(p->fd);
    free(p);
}

/*
** Open a cache file, creating one if necessary
*/

struct CACHE *tls_cache_open(const char *filename, off_t req_size)
{
    struct CACHE *p=malloc(sizeof(struct CACHE));
    struct hdr h;
    int rc;

    if (!p) return NULL;

    if ((p->fd=open(filename, O_RDWR|O_CREAT, 0600)) < 0)
    {
        free(p);
        return NULL;
    }

    if ((p->filename=strdup(filename)) == NULL)
    {
        close(p->fd);
        free(p);
        return (NULL);
    }

    rc=my_read(p->fd, &h, sizeof(h));

    if (rc < 0)
    {
        tls_cache_close(p);
        return (NULL);
    }

    if (rc == 0 || h.filesize == 0)
    {
        /* Once again, but this time lock it */

        if (ll_lock_ex(p->fd) < 0 ||
            lseek(p->fd, 0, SEEK_SET) < 0)
        {
            tls_cache_close(p);
            return (NULL);
        }

        rc=my_read(p->fd, &h, sizeof(h));

        if (rc < 0)
        {
            tls_cache_close(p);
            return (NULL);
        }

        if (rc == 0 || h.filesize == 0)
        {
            if (init(p, req_size))
            {
                tls_cache_close(p);
                return (NULL);
            }
        }
        ll_unlock_ex(p->fd);
    }
    return p;
}

static int doadd(struct CACHE *p, const char *val, size_t vallen);

int tls_cache_add(struct CACHE *p, const char *val, size_t vallen)
{
    int rc;

    if (p->fd < 0)
        return (0);    /* Previous error invalidated obj */

    if (ll_lock_ex(p->fd) < 0)
    {
        close(p->fd);
        p->fd= -1;
        return (-1);
    }

    rc=doadd(p, val, vallen);

    if (rc < 0 && p->fd >= 0)
    {
        close(p->fd);
        p->fd= -1;
        unlink(p->filename);    /* Blow it away, something's wrong */
        perror("ALERT: tlscache.c: ");
        fprintf(stderr, "ALERT: tlscache.c: removing %s\n",
            p->filename);
    }

    if (p->fd >= 0 && ll_unlock_ex(p->fd) < 0)
    {
        close(p->fd);
        p->fd= -1;
        rc= -1;
    }

    if (rc != 0)
        rc= -1;

    return rc;
}

/*
** Read the header, and do a simple sanity check
*/

static int readhdr(struct CACHE *p, struct hdr *h)
{
    if (lseek(p->fd, 0, SEEK_SET) < 0 ||
        my_read(p->fd, h, sizeof(*h)) <= 0)
    {
        BORK(p->filename);
        return (-1);
    }

    if (h->filesize < TLSCACHEMINSIZE || h->head >= h->filesize ||
        h->tail >= h->filesize || h->first >= h->filesize ||
        h->head < 0 || h->tail < 0 || h->first < 0 ||
        h->first > h->head || h->first > h->tail)
    {
        BORK(p->filename);
        return (-1);    /* Sanity check */
    }
    return (0);
}

static int writehdr(struct CACHE *p, const struct hdr *h)
{
    if (lseek(p->fd, 0, SEEK_SET) < 0 ||
        my_write(p->fd, h, sizeof(*h)) < 0)
    {
        BORK(p->filename);
        return -1;
    }
    return 0;
}

/*
** Read the header of a cached object, and do a sanity check
*/

static int readobj(struct CACHE *p, off_t w,
           const struct hdr *h, struct obj *o)
{
    if (lseek(p->fd, w, SEEK_SET) < 0 ||
        my_read(p->fd, o, sizeof(*o)) <= 0)
    {
        BORK(p->filename);
        return (-1);
    }

    if (o->prev_size < sizeof(*o) || o->my_size < sizeof(*o) ||
        o->prev_size >= h->filesize || o->my_size >= h->filesize ||
        h->filesize - w < o->my_size)
    {
        BORK(p->filename);
        errno=EIO;
        return (-1);    /* Sanity check */
    }
    return 0;
}


static int doadd(struct CACHE *p, const char *val, size_t vallen)
{
    struct hdr h;
    struct obj o;
    int timer=0;
    int first=0;
    char *buf;

    if (readhdr(p, &h))
        return -1;

    /* Keep trying to allocate sufficient space in the cache file */

    for (;;)
    {
        if (++timer > 100)
        {
            BORK(p->filename);
            errno=EIO;
            return (-1);    /* Sanity check */
        }

        if (h.head == 0 && h.tail == 0)    /* First time */
        {
            if (vallen + sizeof(struct obj) +
                sizeof(struct hdr) > h.filesize)
            {
                errno=ENOSPC;
                return 1;
            }

            /* First cached object goes at the end */

            h.head=h.tail=h.filesize - vallen - sizeof(struct obj);
            first=1;
            break;
        }

        if (h.head <= h.tail)    /* Not wrapped around */
        {
            if (h.head >= sizeof(struct hdr) +
                sizeof(struct obj) + vallen)
            {
                h.head -= sizeof(struct obj) + vallen;
                break;
                /* Room earlier in the file */
            }

            /*
            ** No room before, we must now wrap around.  Find
            ** where the last object ends, and see if there's
            ** enough room between the end of the last object,
            ** and the end of the file, to save the new object.
            */

            if (readobj(p, h.tail, &h, &o) < 0)
                return -1;

            if (h.filesize - h.tail - o.my_size >=
                sizeof(struct obj) + vallen)
            {
                h.first=h.head;
                h.head=h.filesize - vallen -
                    sizeof(struct obj);
                /* Room to wrap around */

                break;
            }
        }
        else    /* We're currently wrapped around, so all the free
            ** space is from tail to head.
            */
        {
            if (readobj(p, h.tail, &h, &o) < 0)
                return -1;

            if (h.head >= h.tail + o.my_size +
                sizeof(struct obj) + vallen)
            {
                h.head -= sizeof(struct obj) + vallen;
                break;
            }
        }

        if (h.head == h.tail)    /* Sanity check */
        {
            errno=ENOSPC;
            return 1;
        }

        /* Pop one off tail */

        if (readobj(p, h.tail, &h, &o))
            return -1;

        if (sizeof(h) + o.prev_size <= h.tail)
        {
            h.tail -= o.prev_size;

            if (writehdr(p, &h))
                return (-1);
            continue;
        }

        if (h.tail != h.first)
        {
            BORK(p->filename);
            errno=EIO;
            return (-1);    /* Sanity check */
        }

        h.first=0;
        h.tail=h.filesize - o.prev_size;

        if (h.tail < h.first)
        {
            BORK(p->filename);
            errno=EIO;
            return (-1);    /* Sanity check */
        }

        if (writehdr(p, &h))
            return (-1);
    }

    buf=malloc(vallen + sizeof(o) + sizeof(o.prev_size));

    if (!buf)
        return (1);

    o.prev_size=0;
    o.my_size=vallen + sizeof(o);
    memcpy(buf, &o, sizeof(o));
    memcpy(buf + sizeof(o), val, vallen);
    o.prev_size=o.my_size;
    memcpy(buf + sizeof(o) + vallen, &o.prev_size, sizeof(o.prev_size));

    if (lseek(p->fd, h.head, SEEK_SET) < 0)
        return (-1);

    if (h.head + sizeof(o) + vallen < h.filesize)
    {
        if (my_write(p->fd, buf, sizeof(o)+vallen+sizeof(o.prev_size)) < 0)
            return -1;
    }
    else
    {
        if (my_write(p->fd, buf, sizeof(o)+vallen) < 0 ||
            (!first && (lseek(p->fd, h.first, SEEK_SET) < 0 ||
                my_write(p->fd, &o.prev_size,
                     sizeof(o.prev_size)) < 0)))
            return -1;
    }
                
    return writehdr(p, &h);
}

static int init(struct CACHE *p, off_t size)
{
    char buffer[BUFSIZ];
    off_t c;
    struct hdr h;

    if (size < TLSCACHEMINSIZE)
    {
        errno=EINVAL;
        return -1;
    }

    if (lseek(p->fd, 0, SEEK_SET) < 0)
        return -1;

    memset(buffer, 0, sizeof(buffer));

    c=size;

    while (c > 0)
    {
        int i;

        off_t n=c;

        if (n > sizeof(buffer))
            n=sizeof(buffer);

        i=write(p->fd, buffer, n);

        if (i <= 0)
            return -1;

        c -= i;
    }

    memset(&h, 0, sizeof(h));
    h.filesize=size;

    if (lseek(p->fd, 0, SEEK_SET) < 0 ||
        my_write(p->fd, &h, sizeof(h)))
        return (-1);
    return (0);
}

static int dowalk(struct CACHE *cache,
          int (*walk_func)(void *rec, size_t recsize,
                   int *doupdate,
                   void *arg),
          void *arg);

int tls_cache_walk(struct CACHE *p,
           int (*walk_func)(void *rec, size_t recsize,
                    int *doupdate,
                    void *arg),
           void *arg)
{
    int rc;

    if (p->fd < 0)
        return (0);    /* Previous error invalidated obj */

    if (ll_lockfd(p->fd, ll_readlock||ll_whence_start|ll_wait, 0, 0) < 0)
    {
        /* Some locking methods don't support readonly locks */

        if (ll_lock_ex(p->fd) < 0)
        {
            close(p->fd);
            p->fd= -1;
            return (-1);
        }
    }

    rc=dowalk(p, walk_func, arg);

    if (rc < 0 && p->fd >= 0)
    {
        close(p->fd);
        p->fd= -1;
        unlink(p->filename);
        perror("ALERT: tlscache.c: ");
        fprintf(stderr, "ALERT: tlscache.c: removing %s\n",
            p->filename);
    }

    if (p->fd >= 0 && ll_unlock_ex(p->fd) < 0)
    {
        close(p->fd);
        p->fd= -1;
        rc= -1;
    }

    return rc;
}

/* Buffered reads when searching, for speed */

struct walkbuf {
    char buffer[BUFSIZ];
    char *bufptr;
    int left;
};

static int buf_read(int fd, struct walkbuf *w,
            const void *buffer, size_t cnt)
{
    char *p=(char *)buffer;

    while (cnt > 0)
    {
        if (w->left <= 0)
        {
            w->left=read(fd, w->buffer, sizeof(w->buffer));

            if (w->left <= 0)
                return -1;
            w->bufptr=w->buffer;
        }

        *p++ = *w->bufptr++;
        --w->left;
        --cnt;
    }
    return 1;
}

static int dowalk(struct CACHE *p,
          int (*walk_func)(void *rec, size_t recsize,
                   int *doupdate, void *arg),
          void *arg)
{
    struct hdr h;
    struct obj o;
    char *buf=NULL;
    size_t bufsize=0;
    int rc;
    int counter;
    struct walkbuf wb;
    int updateflag;

    off_t pos;
    off_t lastpos;

    if (readhdr(p, &h))
        return -1;

    if (h.head == 0 && h.tail == 0)    /* First time */
        return (0);

    pos=h.head;
    if (lseek(p->fd, pos, SEEK_SET) < 0)
        return (-1);

    counter=0;
    wb.left=0;
    for (;;)
    {
        if (++counter > h.filesize / sizeof(o))
        {
            BORK(p->filename);
            return (-1);
        }

        if (h.filesize - pos < sizeof(o))
        {
            BORK(p->filename);
            errno=EIO;
            if (buf)
                free(buf);
            return (-1);    /* Sanity check */
        }

        if (buf_read(p->fd, &wb, &o, sizeof(o)) <= 0)
        {
            if (buf)
                free(buf);
            return (-1);
        }

        if (h.filesize - pos < o.my_size || o.my_size < sizeof(o))
        {
            BORK(p->filename);
            errno=EIO;
            if (buf)
                free(buf);
            return (-1);    /* Sanity check */
        }

        if (buf == NULL || bufsize < o.my_size - sizeof(o)+1)
        {
            char *newbuf;

            bufsize=o.my_size - sizeof(o)+1;

            if ((newbuf=buf ? realloc(buf, bufsize):
                 malloc(bufsize)) == NULL)
            {
                free(buf);
                return (-1);
            }
            buf=newbuf;
        }

        if (buf_read(p->fd, &wb, buf, o.my_size - sizeof(o)) <= 0)
        {
            free(buf);
            return (-1);
        }

        updateflag=0;

        rc= (*walk_func)(buf, o.my_size - sizeof(o), &updateflag, arg);

        if (updateflag && rc >= 0)
        {
            if (lseek(p->fd, pos + sizeof(o), SEEK_SET) < 0 ||
                my_write(p->fd, buf, o.my_size - sizeof(o)) < 0)
            {
                free(buf);
                return (-1);
            }
            wb.left=0;
        }

        if (rc != 0)
        {
            free(buf);
            if (rc < 0)
                rc=1;
            return (rc);
        }

        if (pos == h.tail)
            break;

        lastpos=pos;
        pos += o.my_size;

        if (pos < h.filesize)
        {
            if (lastpos < h.tail && pos > h.tail)
            {
                BORK(p->filename);
                errno=EIO;
                free(buf);
                return (-1);
            }
        }
        else
        {
            pos=h.first;
            if (h.first < sizeof(h))
            {
                BORK(p->filename);
                free(buf);
                errno=EIO;
                return (-1);
            }

            if (lseek(p->fd, pos, SEEK_SET) < 0)
            {
                free(buf);
                return (-1);
            }
            wb.left=0;
        }
    }
    if (buf)
        free(buf);
    return (0);
}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.1886 seconds