Search in sources :

Example 1 with SqlInjectionException

use of org.ovirt.engine.core.common.errors.SqlInjectionException in project ovirt-engine by oVirt.

the class SearchQuery method initQueryData.

private QueryData initQueryData(boolean useCache) {
    final String ASTR = "*";
    QueryData data = null;
    boolean isExistsValue = false;
    boolean IsFromYesterday = false;
    boolean isSafe = false;
    String searchKey = "";
    try {
        if (getParameters().getMaxCount() < 0) {
            throw new RuntimeException(String.format("Illegal max count value for query : %s", getParameters().getMaxCount()));
        }
        String searchText = getParameters().getSearchPattern();
        // do not cache expressions with '*' since it is translated to specific IDs that might be changed
        useCache = useCache && !searchText.contains(ASTR);
        if (useCache) {
            // first lets check the cache of queries.
            searchKey = String.format("%1$s,%2$s,%3$s", searchText, getParameters().getMaxCount(), getParameters().getCaseSensitive());
            data = queriesCache.get(searchKey);
            isExistsValue = data != null;
            if (isExistsValue) {
                TimeSpan span = DateTime.getNow().subtract(new Date(data.getDate()));
                if (span.Days >= 1) {
                    IsFromYesterday = true;
                }
            }
        }
        // search text.
        if (!isExistsValue || IsFromYesterday) {
            log.debug("ResourceManager::searchBusinessObjects(''{}'') - entered", searchText);
            final char AT = '@';
            String queryAuthz = null;
            String queryNamespace = null;
            ISyntaxChecker curSyntaxChecker;
            Matcher m = adSearchPattern.matcher(searchText);
            // checks if this is a AD query, if it is, verify given profile and namespace and pass the query
            if (m.matches()) {
                final String COLON = ":";
                String prefix = m.group("prefix");
                searchText = m.group("content");
                // get profile
                List<String> profiles = backend.runInternalQuery(QueryType.GetDomainList, new QueryParametersBase(getParameters().getSessionId())).getReturnValue();
                for (String profile : profiles) {
                    if (searchText.startsWith(profile + COLON)) {
                        queryAuthz = profile;
                        searchText = searchText.replaceFirst(profile + COLON, StringUtils.EMPTY);
                        break;
                    }
                }
                if (queryAuthz == null) {
                    queryAuthz = getDefaultAuthz();
                }
                // get namespace
                Map<String, List<String>> namespacesMap = backend.runInternalQuery(QueryType.GetAvailableNamespaces, new QueryParametersBase(getParameters().getSessionId())).getReturnValue();
                List<String> namespaces = namespacesMap.get(queryAuthz);
                for (String namespace : namespaces) {
                    if (searchText.startsWith(namespace + COLON)) {
                        queryNamespace = namespace;
                        searchText = searchText.replace(namespace + COLON, StringUtils.EMPTY);
                        break;
                    }
                }
                // ADUSER/ADGROUP<profile>::<query>
                if (searchText.startsWith(COLON)) {
                    searchText = prefix + searchText;
                } else {
                    searchText = prefix + COLON + searchText;
                }
                curSyntaxChecker = SyntaxCheckerFactory.createADSyntaxChecker(LDAP);
            } else {
                curSyntaxChecker = SyntaxCheckerFactory.createBackendSyntaxChecker(LDAP);
            }
            SyntaxContainer searchObj = curSyntaxChecker.analyzeSyntaxState(searchText, true);
            // set the case-sensitive flag
            searchObj.setCaseSensitive(getParameters().getCaseSensitive());
            // If a number > maxValue is given then maxValue will be used
            searchObj.setMaxCount(Math.min(Integer.MAX_VALUE, getParameters().getMaxCount()));
            // setting FromSearch value
            searchObj.setSearchFrom(getParameters().getSearchFrom());
            if (searchObj.getError() != SyntaxError.NO_ERROR) {
                int startPos = searchObj.getErrorStartPos();
                int endPos = searchObj.getErrorEndPos();
                int length = endPos - startPos;
                String error = (length > 0 && ((startPos + 1 + length) < searchText.length()) && (endPos + 1 < searchText.length())) ? searchText.substring(0, startPos) + "$" + searchText.substring(startPos + 1, startPos + 1 + length) + "$" + searchText.substring(endPos + 1) : searchObj.getError().toString();
                getQueryReturnValue().setExceptionString(error);
                log.info("ResourceManager::searchBusinessObjects - erroneous search text - ''{}'' error - ''{}''", searchText, error);
                return null;
            }
            if (!searchObj.getvalid()) {
                log.warn("ResourceManager::searchBusinessObjects - Invalid search text - ''{}''", searchText);
                return null;
            }
            // find if this is a trivial search expression (like 'Vms:' etc).
            isSafe = SearchObjects.isSafeExpression(searchText);
            // An expression is considered safe if matches a trivial search.
            data = new QueryData(curSyntaxChecker.generateQueryFromSyntaxContainer(searchObj, isSafe), DateTime.getNow().getTime(), queryAuthz, queryNamespace);
            // query from scratch.
            if (!containsStaticInValues(data.getQuery())) {
                queriesCache.put(searchKey, data);
            }
        }
    } catch (SearchEngineIllegalCharacterException e) {
        log.error("Search expression can not end with ESCAPE character: {}", getParameters().getSearchPattern());
        data = null;
    } catch (SqlInjectionException e) {
        log.error("Sql Injection in search: {}", getParameters().getSearchPattern());
        data = null;
    } catch (RuntimeException ex) {
        log.warn("Illegal search: {}: {}", getParameters().getSearchPattern(), ex.getMessage());
        log.debug("Exception", ex);
        throw ex;
    }
    return data;
}
Also used : QueryData(org.ovirt.engine.core.aaa.QueryData) Matcher(java.util.regex.Matcher) SearchEngineIllegalCharacterException(org.ovirt.engine.core.common.errors.SearchEngineIllegalCharacterException) ISyntaxChecker(org.ovirt.engine.core.searchbackend.ISyntaxChecker) Date(java.util.Date) TimeSpan(org.ovirt.engine.core.compat.TimeSpan) SyntaxContainer(org.ovirt.engine.core.searchbackend.SyntaxContainer) SqlInjectionException(org.ovirt.engine.core.common.errors.SqlInjectionException) QueryParametersBase(org.ovirt.engine.core.common.queries.QueryParametersBase) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 List (java.util.List)1 Matcher (java.util.regex.Matcher)1 QueryData (org.ovirt.engine.core.aaa.QueryData)1 SearchEngineIllegalCharacterException (org.ovirt.engine.core.common.errors.SearchEngineIllegalCharacterException)1 SqlInjectionException (org.ovirt.engine.core.common.errors.SqlInjectionException)1 QueryParametersBase (org.ovirt.engine.core.common.queries.QueryParametersBase)1 TimeSpan (org.ovirt.engine.core.compat.TimeSpan)1 ISyntaxChecker (org.ovirt.engine.core.searchbackend.ISyntaxChecker)1 SyntaxContainer (org.ovirt.engine.core.searchbackend.SyntaxContainer)1