Search in sources :

Example 46 with Permission

use of java.security.Permission in project jspwiki by apache.

the class PermissionTag method checkPermission.

/**
 *  Checks a single permission.
 *
 *  @param permission
 *  @return true if granted, false if not
 */
private boolean checkPermission(String permission) {
    WikiSession session = m_wikiContext.getWikiSession();
    WikiPage page = m_wikiContext.getPage();
    AuthorizationManager mgr = m_wikiContext.getEngine().getAuthorizationManager();
    boolean gotPermission = false;
    if (CREATE_GROUPS.equals(permission) || CREATE_PAGES.equals(permission) || EDIT_PREFERENCES.equals(permission) || EDIT_PROFILE.equals(permission) || LOGIN.equals(permission)) {
        gotPermission = mgr.checkPermission(session, new WikiPermission(page.getWiki(), permission));
    } else if (VIEW_GROUP.equals(permission) || EDIT_GROUP.equals(permission) || DELETE_GROUP.equals(permission)) {
        Command command = m_wikiContext.getCommand();
        gotPermission = false;
        if (command instanceof GroupCommand && command.getTarget() != null) {
            GroupPrincipal group = (GroupPrincipal) command.getTarget();
            String groupName = group.getName();
            String action = "view";
            if (EDIT_GROUP.equals(permission)) {
                action = "edit";
            } else if (DELETE_GROUP.equals(permission)) {
                action = "delete";
            }
            gotPermission = mgr.checkPermission(session, new GroupPermission(groupName, action));
        }
    } else if (ALL_PERMISSION.equals(permission)) {
        gotPermission = mgr.checkPermission(session, new AllPermission(m_wikiContext.getEngine().getApplicationName()));
    } else if (page != null) {
        // 
        if (EDIT.equals(permission)) {
            WikiPage latest = m_wikiContext.getEngine().getPage(page.getName());
            if (page.getVersion() != WikiProvider.LATEST_VERSION && latest.getVersion() != page.getVersion()) {
                return false;
            }
        }
        Permission p = PermissionFactory.getPagePermission(page, permission);
        gotPermission = mgr.checkPermission(session, p);
    }
    return gotPermission;
}
Also used : WikiSession(org.apache.wiki.WikiSession) GroupCommand(org.apache.wiki.ui.GroupCommand) Command(org.apache.wiki.ui.Command) GroupCommand(org.apache.wiki.ui.GroupCommand) GroupPrincipal(org.apache.wiki.auth.GroupPrincipal) WikiPage(org.apache.wiki.WikiPage) WikiPermission(org.apache.wiki.auth.permissions.WikiPermission) AllPermission(org.apache.wiki.auth.permissions.AllPermission) Permission(java.security.Permission) GroupPermission(org.apache.wiki.auth.permissions.GroupPermission) AllPermission(org.apache.wiki.auth.permissions.AllPermission) GroupPermission(org.apache.wiki.auth.permissions.GroupPermission) AuthorizationManager(org.apache.wiki.auth.AuthorizationManager) WikiPermission(org.apache.wiki.auth.permissions.WikiPermission)

Example 47 with Permission

use of java.security.Permission in project jspwiki by apache.

the class AttachmentServlet method doGet.

/**
 *  Serves a GET with two parameters: 'wikiname' specifying the wikiname
 *  of the attachment, 'version' specifying the version indicator.
 */
// FIXME: Messages would need to be localized somehow.
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
    WikiContext context = m_engine.createContext(req, WikiContext.ATTACH);
    String version = req.getParameter(HDR_VERSION);
    String nextPage = req.getParameter("nextpage");
    String msg = "An error occurred. Ouch.";
    int ver = WikiProvider.LATEST_VERSION;
    AttachmentManager mgr = m_engine.getAttachmentManager();
    AuthorizationManager authmgr = m_engine.getAuthorizationManager();
    String page = context.getPage().getName();
    if (page == null) {
        log.info("Invalid attachment name.");
        res.sendError(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }
    OutputStream out = null;
    InputStream in = null;
    try {
        log.debug("Attempting to download att " + page + ", version " + version);
        if (version != null) {
            ver = Integer.parseInt(version);
        }
        Attachment att = mgr.getAttachmentInfo(page, ver);
        if (att != null) {
            // 
            // Check if the user has permission for this attachment
            // 
            Permission permission = PermissionFactory.getPagePermission(att, "view");
            if (!authmgr.checkPermission(context.getWikiSession(), permission)) {
                log.debug("User does not have permission for this");
                res.sendError(HttpServletResponse.SC_FORBIDDEN);
                return;
            }
            // 
            if (HttpUtil.checkFor304(req, att.getName(), att.getLastModified())) {
                log.debug("Client has latest version already, sending 304...");
                res.sendError(HttpServletResponse.SC_NOT_MODIFIED);
                return;
            }
            String mimetype = getMimeType(context, att.getFileName());
            res.setContentType(mimetype);
            // 
            // We use 'inline' instead of 'attachment' so that user agents
            // can try to automatically open the file.
            // 
            res.addHeader("Content-Disposition", "inline; filename=\"" + att.getFileName() + "\";");
            res.addDateHeader("Last-Modified", att.getLastModified().getTime());
            if (!att.isCacheable()) {
                res.addHeader("Pragma", "no-cache");
                res.addHeader("Cache-control", "no-cache");
            }
            // If a size is provided by the provider, report it.
            if (att.getSize() >= 0) {
                // log.info("size:"+att.getSize());
                res.setContentLength((int) att.getSize());
            }
            out = res.getOutputStream();
            in = mgr.getAttachmentStream(context, att);
            int read = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            while ((read = in.read(buffer)) > -1) {
                out.write(buffer, 0, read);
            }
            if (log.isDebugEnabled()) {
                msg = "Attachment " + att.getFileName() + " sent to " + req.getRemoteUser() + " on " + HttpUtil.getRemoteAddress(req);
                log.debug(msg);
            }
            if (nextPage != null) {
                res.sendRedirect(validateNextPage(nextPage, m_engine.getURL(WikiContext.ERROR, "", null, false)));
            }
        } else {
            msg = "Attachment '" + page + "', version " + ver + " does not exist.";
            log.info(msg);
            res.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
        }
    } catch (ProviderException pe) {
        msg = "Provider error: " + pe.getMessage();
        log.debug("Provider failed while reading", pe);
        // 
        try {
            res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
        } catch (IllegalStateException e) {
        }
    } catch (NumberFormatException nfe) {
        log.warn("Invalid version number: " + version);
        res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid version number");
    } catch (SocketException se) {
        // 
        // These are very common in download situations due to aggressive
        // clients.  No need to try and send an error.
        // 
        log.debug("I/O exception during download", se);
    } catch (IOException ioe) {
        // 
        // Client dropped the connection or something else happened.
        // We don't know where the error came from, so we'll at least
        // try to send an error and catch it quietly if it doesn't quite work.
        // 
        msg = "Error: " + ioe.getMessage();
        log.debug("I/O exception during download", ioe);
        try {
            res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
        } catch (IllegalStateException e) {
        }
    } finally {
        IOUtils.closeQuietly(in);
        // 
        // Quite often, aggressive clients close the connection when they have
        // received the last bits.  Therefore, we close the output, but ignore
        // any exception that might come out of it.
        // 
        IOUtils.closeQuietly(out);
    }
}
Also used : SocketException(java.net.SocketException) WikiContext(org.apache.wiki.WikiContext) ProviderException(org.apache.wiki.api.exceptions.ProviderException) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) IOException(java.io.IOException) Permission(java.security.Permission) AuthorizationManager(org.apache.wiki.auth.AuthorizationManager)

Example 48 with Permission

use of java.security.Permission in project jspwiki by apache.

the class AttachmentServlet method executeUpload.

/**
 * @param context the wiki context
 * @param data the input stream data
 * @param filename the name of the file to upload
 * @param errorPage the place to which you want to get a redirection
 * @param parentPage the page to which the file should be attached
 * @param changenote The change note
 * @param contentLength The content length
 * @return <code>true</code> if upload results in the creation of a new page;
 * <code>false</code> otherwise
 * @throws RedirectException If the content needs to be redirected
 * @throws IOException       If there is a problem in the upload.
 * @throws ProviderException If there is a problem in the backend.
 */
protected boolean executeUpload(WikiContext context, InputStream data, String filename, String errorPage, String parentPage, String changenote, long contentLength) throws RedirectException, IOException, ProviderException {
    boolean created = false;
    try {
        filename = AttachmentManager.validateFileName(filename);
    } catch (WikiException e) {
        // here we have the context available, so we can internationalize it properly :
        throw new RedirectException(Preferences.getBundle(context, InternationalizationManager.CORE_BUNDLE).getString(e.getMessage()), errorPage);
    }
    if (!context.hasAdminPermissions()) {
        if (contentLength > m_maxSize) {
            // FIXME: Does not delete the received files.
            throw new RedirectException("File exceeds maximum size (" + m_maxSize + " bytes)", errorPage);
        }
        if (!isTypeAllowed(filename)) {
            throw new RedirectException("Files of this type may not be uploaded to this wiki", errorPage);
        }
    }
    Principal user = context.getCurrentUser();
    AttachmentManager mgr = m_engine.getAttachmentManager();
    log.debug("file=" + filename);
    if (data == null) {
        log.error("File could not be opened.");
        throw new RedirectException("File could not be opened.", errorPage);
    }
    // 
    // Check whether we already have this kind of a page.
    // If the "page" parameter already defines an attachment
    // name for an update, then we just use that file.
    // Otherwise we create a new attachment, and use the
    // filename given.  Incidentally, this will also mean
    // that if the user uploads a file with the exact
    // same name than some other previous attachment,
    // then that attachment gains a new version.
    // 
    Attachment att = mgr.getAttachmentInfo(context.getPage().getName());
    if (att == null) {
        att = new Attachment(m_engine, parentPage, filename);
        created = true;
    }
    att.setSize(contentLength);
    // 
    // Check if we're allowed to do this?
    // 
    Permission permission = PermissionFactory.getPagePermission(att, "upload");
    if (m_engine.getAuthorizationManager().checkPermission(context.getWikiSession(), permission)) {
        if (user != null) {
            att.setAuthor(user.getName());
        }
        if (changenote != null && changenote.length() > 0) {
            att.setAttribute(WikiPage.CHANGENOTE, changenote);
        }
        try {
            m_engine.getAttachmentManager().storeAttachment(att, data);
        } catch (ProviderException pe) {
            // here we have the context available, so we can internationalize it properly :
            throw new ProviderException(Preferences.getBundle(context, InternationalizationManager.CORE_BUNDLE).getString(pe.getMessage()));
        }
        log.info("User " + user + " uploaded attachment to " + parentPage + " called " + filename + ", size " + att.getSize());
    } else {
        throw new RedirectException("No permission to upload a file", errorPage);
    }
    return created;
}
Also used : WikiException(org.apache.wiki.api.exceptions.WikiException) ProviderException(org.apache.wiki.api.exceptions.ProviderException) Permission(java.security.Permission) Principal(java.security.Principal) RedirectException(org.apache.wiki.api.exceptions.RedirectException)

Example 49 with Permission

use of java.security.Permission in project jspwiki by apache.

the class AuthorizationManager method checkPermission.

/**
 * Returns <code>true</code> or <code>false</code>, depending on
 * whether a Permission is allowed for the Subject associated with
 * a supplied WikiSession. The access control algorithm works this way:
 * <ol>
 * <li>The {@link org.apache.wiki.auth.acl.Acl} for the page is obtained</li>
 * <li>The Subject associated with the current
 * {@link org.apache.wiki.WikiSession} is obtained</li>
 * <li>If the Subject's Principal set includes the Role Principal that is
 * the administrator group, always allow the Permission</li>
 * <li>For all permissions, check to see if the Permission is allowed according
 * to the default security policy. If it isn't, deny the permission and halt
 * further processing.</li>
 * <li>If there is an Acl, get the list of Principals assigned this
 * Permission in the Acl: these will be role, group or user Principals, or
 * {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}s (see below).
 * Then iterate through the Subject's Principal set and determine whether
 * the user (Subject) possesses any one of these specified Roles or
 * Principals. The matching process delegates to
 * {@link #hasRoleOrPrincipal(WikiSession, Principal)}.
 * </ol>
 * <p>
 * Note that when iterating through the Acl's list of authorized Principals,
 * it is possible that one or more of the Acl's Principal entries are of
 * type <code>UnresolvedPrincipal</code>. This means that the last time
 * the ACL was read, the Principal (user, built-in Role, authorizer Role, or
 * wiki Group) could not be resolved: the Role was not valid, the user
 * wasn't found in the UserDatabase, or the Group wasn't known to (e.g.,
 * cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is
 * encountered, this method will attempt to resolve it first <em>before</em>
 * checking to see if the Subject possesses this principal, by calling
 * {@link #resolvePrincipal(String)}. If the (re-)resolution does not
 * succeed, the access check for the principal will fail by definition (the
 * Subject should never contain UnresolvedPrincipals).
 * </p>
 * <p>
 * If security not set to JAAS, will return true.
 * </p>
 * @param session the current wiki session
 * @param permission the Permission being checked
 * @see #hasRoleOrPrincipal(WikiSession, Principal)
 * @return the result of the Permission check
 */
public boolean checkPermission(WikiSession session, Permission permission) {
    // 
    if (session == null || permission == null) {
        fireEvent(WikiSecurityEvent.ACCESS_DENIED, null, permission);
        return false;
    }
    Principal user = session.getLoginPrincipal();
    // Always allow the action if user has AllPermission
    Permission allPermission = new AllPermission(m_engine.getApplicationName());
    boolean hasAllPermission = checkStaticPermission(session, allPermission);
    if (hasAllPermission) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // If the user doesn't have *at least* the permission
    // granted by policy, return false.
    boolean hasPolicyPermission = checkStaticPermission(session, permission);
    if (!hasPolicyPermission) {
        fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
        return false;
    }
    // If this isn't a PagePermission, it's allowed
    if (!(permission instanceof PagePermission)) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // 
    // If the page or ACL is null, it's allowed.
    // 
    String pageName = ((PagePermission) permission).getPage();
    WikiPage page = m_engine.getPage(pageName);
    Acl acl = (page == null) ? null : m_engine.getAclManager().getPermissions(page);
    if (page == null || acl == null || acl.isEmpty()) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // 
    // Next, iterate through the Principal objects assigned
    // this permission. If the context's subject possesses
    // any of these, the action is allowed.
    Principal[] aclPrincipals = acl.findPrincipals(permission);
    log.debug("Checking ACL entries...");
    log.debug("Acl for this page is: " + acl);
    log.debug("Checking for principal: " + Arrays.toString(aclPrincipals));
    log.debug("Permission: " + permission);
    for (Principal aclPrincipal : aclPrincipals) {
        // try to resolve it here & correct the Acl
        if (aclPrincipal instanceof UnresolvedPrincipal) {
            AclEntry aclEntry = acl.getEntry(aclPrincipal);
            aclPrincipal = resolvePrincipal(aclPrincipal.getName());
            if (aclEntry != null && !(aclPrincipal instanceof UnresolvedPrincipal)) {
                aclEntry.setPrincipal(aclPrincipal);
            }
        }
        if (hasRoleOrPrincipal(session, aclPrincipal)) {
            fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
            return true;
        }
    }
    fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
    return false;
}
Also used : WikiPage(org.apache.wiki.WikiPage) PagePermission(org.apache.wiki.auth.permissions.PagePermission) AllPermission(org.apache.wiki.auth.permissions.AllPermission) Permission(java.security.Permission) AclEntry(org.apache.wiki.auth.acl.AclEntry) AllPermission(org.apache.wiki.auth.permissions.AllPermission) Acl(org.apache.wiki.auth.acl.Acl) Principal(java.security.Principal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) PagePermission(org.apache.wiki.auth.permissions.PagePermission) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal)

Example 50 with Permission

use of java.security.Permission in project jspwiki by apache.

the class DefaultAclManager method printAcl.

/**
 * Generates an ACL string for inclusion in a wiki page, based on a supplied Acl object.
 * All of the permissions in this Acl are assumed to apply to the same page scope.
 * The names of the pages are ignored; only the actions and principals matter.
 *
 * @param acl the ACL
 * @return the ACL string
 */
protected static String printAcl(Acl acl) {
    // Extract the ACL entries into a Map with keys == permissions, values == principals
    Map<String, List<Principal>> permissionPrincipals = new TreeMap<String, List<Principal>>();
    Enumeration<AclEntry> entries = acl.entries();
    while (entries.hasMoreElements()) {
        AclEntry entry = entries.nextElement();
        Principal principal = entry.getPrincipal();
        Enumeration<Permission> permissions = entry.permissions();
        while (permissions.hasMoreElements()) {
            Permission permission = permissions.nextElement();
            List<Principal> principals = permissionPrincipals.get(permission.getActions());
            if (principals == null) {
                principals = new ArrayList<Principal>();
                String action = permission.getActions();
                if (action.indexOf(',') != -1) {
                    throw new IllegalStateException("AclEntry permission cannot have multiple targets.");
                }
                permissionPrincipals.put(action, principals);
            }
            principals.add(principal);
        }
    }
    // Now, iterate through each permission in the map and generate an ACL string
    StringBuilder s = new StringBuilder();
    for (Map.Entry<String, List<Principal>> entry : permissionPrincipals.entrySet()) {
        String action = entry.getKey();
        List<Principal> principals = entry.getValue();
        Collections.sort(principals, new PrincipalComparator());
        s.append("[{ALLOW ");
        s.append(action);
        s.append(" ");
        for (int i = 0; i < principals.size(); i++) {
            Principal principal = principals.get(i);
            s.append(principal.getName());
            if (i < (principals.size() - 1)) {
                s.append(",");
            }
        }
        s.append("}]\n");
    }
    return s.toString();
}
Also used : TreeMap(java.util.TreeMap) PrincipalComparator(org.apache.wiki.auth.PrincipalComparator) PagePermission(org.apache.wiki.auth.permissions.PagePermission) Permission(java.security.Permission) ArrayList(java.util.ArrayList) List(java.util.List) Map(java.util.Map) TreeMap(java.util.TreeMap) Principal(java.security.Principal)

Aggregations

Permission (java.security.Permission)236 Test (org.junit.Test)55 PermissionCollection (java.security.PermissionCollection)39 FilePermission (java.io.FilePermission)38 Permissions (java.security.Permissions)31 ProtectionDomain (java.security.ProtectionDomain)27 IOException (java.io.IOException)20 AllPermission (java.security.AllPermission)20 QuickTest (com.hazelcast.test.annotation.QuickTest)17 File (java.io.File)17 URL (java.net.URL)16 AccessControlException (java.security.AccessControlException)14 Principal (java.security.Principal)14 PropertyPermission (java.util.PropertyPermission)14 Policy (java.security.Policy)13 MBeanPermission (javax.management.MBeanPermission)13 AccessControlContext (java.security.AccessControlContext)12 CodeSource (java.security.CodeSource)11 SecurityPermission (java.security.SecurityPermission)11 ArrayList (java.util.ArrayList)10