コード例 #1
0
ファイル: util.cpp プロジェクト: Knochenschaeler/keeperrl
DirSet DirSet::oneElement(Dir dir) {
  return DirSet(1 << int(dir));
}
コード例 #2
0
ファイル: hi_norm.c プロジェクト: DeepnessLab/moly
/**
**  This function inspects the normalized chars for any other processing
**  that we need to do, such as directory traversals.
**
**  The main things that we check for here are '/' and '?'.  There reason
**  for '/' is that we do directory traversals.  If it's a slash, we call
**  the routine that will normalize mutli-slashes, self-referential dirs,
**  and dir traversals.  We do all that processing here and call the
**  appropriate functions.
**
**  The '?' is so we can mark the parameter field, and check for oversize
**  directories one last time.  Once the parameter field is set, we don't
**  do any more oversize directory checks since we aren't in the url
**  any more.
**
**  @param Session      pointer to the current session
**  @param iChar        the char to inspect
**  @param norm_state   the normalization state
**  @param start        the start of the URI buffer
**  @param end          the end of the URI buffer
**  @param ptr          the address of the pointer index into the URI buffer
**  @param ub_start     the start of the norm buffer
**  @param ub_end       the end of the norm buffer
**  @param ub_ptr       the address of the pointer index into the norm buffer
**
**  @return integer
**
**  @retval END_OF_BUFFER    we've reached the end of the URI or norm buffer
**  @retval HI_NONFATAL_ERR  no special char, so just write the char and
**                           increment the ub_ptr.
**  @retval HI_SUCCESS       normalized the special char and already
**                           incremented the buffers.
*/
static inline int InspectUriChar(HI_SESSION *Session, int iChar,
                                 URI_NORM_STATE *norm_state,
                                 const u_char *start, const u_char *end, const u_char **ptr,
                                 u_char *ub_start, u_char *ub_end,
                                 u_char **ub_ptr, uint16_t *encodeType)
{
    HTTPINSPECT_CONF *ServerConf = Session->server_conf;
    int iDir;

    /*
    **  Let's add absolute URI/proxy support everyone.
    */
    if(!norm_state->dir_count && (u_char)iChar == ':' &&
       hi_util_in_bounds(start, end, ((*ptr)+2)))
    {
        if(**ptr == '/' && *((*ptr)+1) == '/')
        {
            /*
            **  We've found absolute vodka.
            */
            if(!hi_util_in_bounds(ub_start, ub_end, ((*ub_ptr)+2)))
                return END_OF_BUFFER;

            /*
            **  Write the :
            */
            **ub_ptr = (u_char)iChar;
            (*ub_ptr)++;

            /*
            **  This increments us past the first slash, so at the next
            **  slash we will track a directory.
            **
            **  The reason we do this is so that an attacker can't trick
            **  us into normalizing a directory away that ended in a :.
            **  For instance, if we got a URL that was separated in by a
            **  packet boundary like this, and we were looking for the
            **  URL real_dir:/file.html:
            **    real_dir://obfuscate_dir/../file.html
            **  we would normalize it with proxy support to:
            **    /file.html
            **  because we never tracked the :// as a valid directory.  So
            **  even though this isn't the best solution, it is the best
            **  we can do given that we are working with stateless
            **  inspection.
            */
            (*ptr)++;

            return HI_SUCCESS;
        }
    }

    /*
    **  Now that we have the "true" byte, we check this byte for other
    **  types of normalization:
    **    -  directory traversals
    **    -  multiple slashes
    */
    if((u_char)iChar == '/')
    {
        /*
        **  First thing we do is check for a long directory.
        */
        CheckLongDir(Session, norm_state, *ub_ptr);

        iDir = DirNorm(Session, start, end, ptr, norm_state, encodeType);

        if(iDir == DIR_TRAV)
        {
            /*
            **  This is the case where we have a directory traversal.
            **
            **  The DirTrav function will reset the ub_ptr to the previous
            **  slash.  After that, we just continue through the loop because
            **  DirNorm has already set ptr to the slash, so we can just
            **  continue on.
            */
            DirTrav(Session,norm_state, ub_start, ub_ptr);
        }
        else
        {
            /*
            **  This is the case where we didn't have a directory traversal,
            **  and we are now just writing the char after the '/'.
            **
            **  We call DirSet, because all this function does is write a
            **  '/' into the buffer and increment the ub_ptr.  We then
            **  check the return code and return END_OF_BUFFER if
            **  needed.
            */
            DirSet(norm_state, ub_ptr);
            if(iDir == END_OF_BUFFER)
                return END_OF_BUFFER;

            /*
            **  We check the bounds before we write the next byte
            */
            if(!hi_util_in_bounds(ub_start, ub_end, *ub_ptr))
                return END_OF_BUFFER;

            /*
            **  Set the char to what we got in DirNorm()
            */
            /*
            **  Look for user-defined Non-Rfc chars.  If we find them
            **  then log an alert.
            */
            if(ServerConf->non_rfc_chars[(u_char)iDir])
            {
                if(hi_eo_generate_event(Session, HI_EO_CLIENT_NON_RFC_CHAR) &&
                   !norm_state->param)
                {
                    hi_eo_client_event_log(Session, HI_EO_CLIENT_NON_RFC_CHAR,
                                           NULL, NULL);
                }
            }

            **ub_ptr = (u_char)iDir;
            (*ub_ptr)++;
        }

        return HI_SUCCESS;
    }

    if((!byte_decoded && (u_char)iChar == '?'))
    {
        /*
        **  We assume that this is the beginning of the parameter field,
        **  and check for a long directory following.  Event though seeing
        **  a question mark does not guarantee the parameter field, thanks
        **  IIS.
        */
        CheckLongDir(Session, norm_state, *ub_ptr);
        norm_state->param = *ub_ptr;
    }

    /*
    **  This is neither char, so we just bail and let the loop finish
    **  for us.
    */
    return HI_NONFATAL_ERR;
}