1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2011 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17 
18 //  Mac_GUI.cpp
19 
20 #include <Security/Authorization.h>
21 #include <Security/AuthorizationTags.h>
22 
23 #include <unistd.h>
24 #include "sandbox.h"
25 #include "miofile.h"
26 #include "BOINCGUIApp.h"
27 #include "SkinManager.h"
28 
29 using std::min;
30 using std::max;
31 
32 
33 /* Begin items to include "BOINC Manager" Mac menu items in localization templates */
ThisDummyRoutineIsNeverCalled()34 void ThisDummyRoutineIsNeverCalled() {
35     wxString (_("Services"));
36     wxString (_("Hide %s"));
37     wxString (_("Hide Others"));
38     wxString (_("Show All"));
39     wxString (_("Quit %s"));
40 }
41 /* End items to include "BOINC Manager" Mac menu items in localization templates */
42 
43 
44 // Determine if the currently logged-in user is auhorized to
45 // perform operations which have potential security risks.
46 // An example is "Attach to Project", where a dishonest user might
47 // attach to a rogue project which could then read private files
48 // belonging to the user who owns the BOINC application.  This
49 // would be possible because the BOINC Manager runs with the
50 // effectve user ID of its owner on the Mac.
51 
Mac_Authorize()52 Boolean Mac_Authorize()
53 {
54     static Boolean      sIsAuthorized = false;
55     AuthorizationRef	ourAuthRef = NULL;
56     AuthorizationRights	ourAuthRights;
57     AuthorizationFlags	ourAuthFlags;
58     AuthorizationItem	ourAuthItem[1];
59     OSStatus		err = noErr;
60 
61     if (sIsAuthorized)
62         return true;
63 
64     // User is not the owner, so require admin authentication
65     ourAuthItem[0].name = kAuthorizationRightExecute;
66     ourAuthItem[0].value = NULL;
67     ourAuthItem[0].valueLength = 0;
68     ourAuthItem[0].flags = 0;
69 
70     ourAuthRights.count = 1;
71     ourAuthRights.items = ourAuthItem;
72 
73     ourAuthFlags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;
74 
75     err = AuthorizationCreate (&ourAuthRights, kAuthorizationEmptyEnvironment, ourAuthFlags, &ourAuthRef);
76 
77     if (err == noErr) {
78         sIsAuthorized = true;
79         // We have authenticated user's credentials; we won't actually use the
80         // privileges / rights so destroy / discard them.
81         err = AuthorizationFree(ourAuthRef, kAuthorizationFlagDestroyRights);
82     }
83 
84     return sIsAuthorized;
85 }
86 
87 
88 #define MAX_DISPLAYS 32
89 
90 // Returns true if at least a 5 X 5 pixel area of the
91 // window's title bar is entirely on the displays
92 // Note: Arguments are Quickdraw-style coordinates,
93 // but CGDisplayBounds() sets top left corner as (0, 0)
IsWindowOnScreen(int iLeft,int iTop,int iWidth,int iHeight)94 Boolean IsWindowOnScreen(int iLeft, int iTop, int iWidth, int iHeight) {
95     CGDirectDisplayID displays[MAX_DISPLAYS];
96     CGDisplayCount numDisplays;
97     CGDisplayCount i;
98     CGRect displayRect, intersectedRect;
99     CGFloat mBarHeight = GetMBarHeight();
100 
101     CGRect titleRect = CGRectMake(iLeft, iTop, iWidth, 22);
102     // Make sure at least a 5X5 piece of title bar is visible
103     titleRect = CGRectInset(titleRect, 5, 5);
104 
105     CGGetActiveDisplayList (MAX_DISPLAYS, displays, &numDisplays);
106 
107     // The geometries of windows and display arangements are such
108     // that even if the title bar spans multiple windows, a 5X5
109     // section is on-screen only if at least one 5X5 section is
110     // entirely on one or more displays, so this test is sufficient.
111     for (i = 0; i < numDisplays; i++)
112     {
113         displayRect = CGDisplayBounds(displays[i]);
114         if (i == 0) {   // CGDisplayBounds returns main display first
115             displayRect.origin.y += mBarHeight;
116             displayRect.size.height -= mBarHeight;
117         }
118 
119         intersectedRect = CGRectIntersection(displayRect, titleRect);
120         if (! CGRectIsNull(intersectedRect)) {
121             return true;
122         }
123     }
124 
125     return false;
126 }
127