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