1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
function PsychPaidSupportAndServices(mininag)
%
% If you require paid support regarding Psychtoolbox, or custom feature
% development (or if you want to buy a Psychtoolbox themed coffee mug, bag or shirt)
% go to the following website which provides such services:
%
% https://www.psychtoolbox.net
%
% For paid support on the user forum or GitHub issue tracker, buy a
% "Psychtoolbox support membership" under the "become a member" section:
%
% https://www.psychtoolbox.net/#service
%
% 1. As part of your purchase, you will receive a document - an invoice - with a
% printed "Order Id" or "Order no.", and a printed "License key".
%
% 2. Next you can run *this* function PsychPaidSupportAndServices in Octave or
% Matlab. The function will ask you if you need paid support and do have
% an active license key to prove your community membership. Answer "y" for yes.
%
% 3. Next the function will ask you about your "Order Id" and "License key".
% Please enter that info that you got from step 1.
%
% 4. The function will print out an "authentication token", a string of letters and
% numbers. Now you can post your question on the Psychtoolbox user forum at
% https://psychtoolbox.discourse.group or open a new issue for bugs and feature
% requests on our GitHub issue tracker at https://github.com/Psychtoolbox-3/Psychtoolbox-3/issues
%
% Please add the "authentication token" to your forum question or GitHub issue.
% This will prove to us that you deserve paid support for your question or
% issue. Please note that initial activation of your license key may take 5-10
% days after date of receipt of payment, so do not buy the paid support last
% minute, when the "house is already burning", but ahead of time, like you
% would do with a fire insurance.
%
%
% For more detailed background information about Psychtoolbox's need for funding, read on:
%
% Continued development, improvement, maintenance and support of
% Psychtoolbox itself, and also improvement of the various open-source
% software components on which Psychtoolbox and other neuroscience toolkits
% (e.g., PsychoPy) critically depend, including improvements to the Linux
% operating system as the strongest and most high quality foundation for
% demanding stimulation and data collection paradigms, requires a lot of
% highly qualified and highly focused work.
%
% This work is currently (year 2006 - present) mostly carried out by Mario
% Kleiner, who is now employed to do this work by the Medical Innovations
% Incubator GmbH (MII) in Tuebingen, Germany ( https://www.mi-incubator.com ).
% The MII belongs by 100% to the non-profit foundation for medical
% innovations ( http://www.mi-foundation.org ) in Tuebingen.
%
% In order to fund Mario's work and provide him with the resources to do
% this job, the MII offers different types of paid services around
% Psychtoolbox and the use of Linux for neuroscience, among them a
% "Psychtoolbox community membership with paid support".
%
% Your lab can now financially contribute to Psychtoolbox sustainability,
% upkeep and continued improvement, by once a year buying such a community
% membership for a modest fee. This membership entitles you to some
% paid support for questions regarding efficient use of Psychtoolbox,
% questions regarding the resolution of issues you may have with it, fixing
% of bugs you may encounter, and feature requests. MII also offers paid
% feature development and other commercial services.
%
% Please visit the following website, operated by MII, for our offering of
% commercial development services, and for the community membership with
% paid support:
%
%
% https://www.psychtoolbox.net
%
%
% The membership allows you to get your voice heard by the developers
% regarding future feature development, as well as preferential treatment
% on the public Psychtoolbox user forum and GitHub issue tracker. Spare
% income generated by your membership fee, that does not have to be used
% to process paid requests made individually by you, will be used to
% fund general development and upkeep of Psychtoolbox and its ecosystem. In
% other words, it contributes to / acts as an insurance that allows
% Psychtoolbox to be around and in good shape years into the future.
%
% To clarify: Psychtoolbox itself will stay open-source software. Anybody
% able and willing to contribute code and ideas of sufficiently high quality
% is invited to contribute to the open-source code, the documentation on our
% public community website and Wiki
% http://psychtoolbox.org, and to participate and help each other on the
% public community forum https://psychtoolbox.discourse.group.
%
% Support by our developers will be reserved to paying community members.
%
% Thanks for your participation and support!
%
% Mini advert requested by some caller, e.g., PsychtoolboxPostInstallRoutine?
if exist('mininag', 'var') && (mininag > 0)
fprintf('\n');
% mininag 2 if called from an error handler, mininag 1 if called from
% general setup code:
if mininag == 2
fprintf('NOTE: You may want to acquire paid support for future issues like this.\n');
else
fprintf('IMPORTANT NEWS:\n\n');
fprintf('You can now financially contribute to Psychtoolbox sustainability, upkeep and continued\n');
fprintf('improvement by buying a paid support membership, which provides some paid support\n');
fprintf('for questions regarding its use, or issues you may have with it. We also offer paid\n');
fprintf('feature development and other useful commercial services.\n');
end
fprintf('Please type ''PsychPaidSupportAndServices'' to learn more.\n');
fprintf('\n\n');
if mininag == 1
end
return;
end
% Nope, full request by user for information:
try
fid = fopen([PsychtoolboxConfigDir 'welcomemsgdone'], 'w');
fclose(fid);
catch
end
more on;
help PsychPaidSupportAndServices;
more off;
% Check if user wants to file a support request:
fprintf('\n\n');
answer = '';
while length(answer)~=1 || ~ismember(answer, ['y', 'n'])
answer = strtrim(input('Do you need paid support now and have an active license key [y/n]? ', 's'));
end
if ~strcmpi(answer, 'y')
fprintf('A paid support membership can be bought as described above. Bye.\n');
return;
end
% Ok, our valued community member wants support now. Guide them through the process:
orderId = '';
while isempty(orderId)
fprintf('\nThe Order Id is on the invoice you received, as "Order no." between the invoice\n');
fprintf('number and the customer number.\n\n');
orderId = strtrim(upper(input('Please enter the Order Id of your license, or just ENTER if you can not find it: ', 's')));
if length(orderId) ~= 8 || ~all(isstrprop(orderId, 'alphanum'))
fprintf('\nOrder Id seems to be invalid: It must be 8 letters or numbers, e.g., XS92UVY3\n');
orderId = '';
end
if isempty(orderId)
fprintf('\nIf you can not find the Order Id, i can also just use the first 8 characters of\n');
fprintf('your license key. This poses a mildly higher risk of somebody guessing your key\n');
fprintf('and abusing your community membership to their advantage, or of other mixups.\n\n');
if lower(input('Do you want me to use the license key instead [y/n]? ', 's')) == 'y'
break;
end
end
end
% Get the date and time string as 2nd component:
requestTimeDate = sprintf('%i', round(clock));
licenseKey = '';
while isempty(licenseKey)
licenseKey = strtrim(upper(input('Please enter the license key: ', 's')));
if length(licenseKey) ~= 35 || ~all(isstrprop(licenseKey([1:5, 7:11, 13:17, 19:23, 25:29, 31:35]), 'alphanum')) || ~strcmp(licenseKey([6, 12, 18, 24, 30]), '-----')
fprintf('The license key seems to be invalid: It must be 30 letters or numbers in dash separated groups of five, e.g.,\n');
fprintf('2BQR7-R5ZQP-SA36G-RAVDJ-ABZBM-PKKFJ\n\n');
licenseKey = '';
end
end
% User wants us to use first eight chars of license key as orderId?
if isempty(orderId)
orderId = licenseKey(1:8);
end
% Assemble the to-be-hashed string:
publicString = [orderId '-' requestTimeDate];
hashSrcString = [publicString '-' licenseKey];
% Hash it with SHA-256:
% fprintf('\nThe following string will be SHA-256 hashed: %s\n\n', hashSrcString);
hashString = computeSHA256(hashSrcString);
% Assemble final token for public posting at user forum, issue tracker etc.:
authToken = [publicString ':' hashString];
fprintf('\n\nPlease add the following string to your request when\n');
fprintf('asking for support on the Psychtoolbox user forum\n');
fprintf('[ https://psychtoolbox.discourse.group ]\n');
fprintf('or on the Psychtoolbox-3 GitHub issue tracker\n');
fprintf('[ https://github.com/Psychtoolbox-3/Psychtoolbox-3/issues ]\n');
fprintf('to prove that you are eligible for paid support:\n');
fprintf('========================================================================================\n\n');
fprintf('%s\n\n', authToken);
fprintf('========================================================================================\n\n');
% Validation code for the above:
if 0
% Disassemble into pieces:
eOrderId = authToken(1:8)
epublicStringHashSep = strfind(authToken, ':');
epublicString = authToken(1:epublicStringHashSep-1)
ehashString = authToken(epublicStringHashSep+1:end)
% Here we'd use eOrderId to lookup licenseKey in our DB.
% Then reassemble source string for hashing:
ehashSrcString = [epublicString '-' licenseKey]
% Hash it, and compare our local hash against the one provided in public authToken:
bingo = strcmp(ehashString, computeSHA256(ehashSrcString))
end
return;
% Embedded SHA-256 implementation. This is the same as PsychComputeSHA(msg, '256'),
% but embedded here to make PsychPaidSupportAndServices() self-contained.
function rethash = computeSHA256(msg)
shaId = '256';
if exist('hash', 'builtin')
% Octave builtin
rethash = hash(['SHA' shaId], msg);
else
md = javaMethod('getInstance', 'java.security.MessageDigest', ['SHA-' shaId]);
rethash = sprintf('%2.2x', typecast(md.digest(uint8(msg)), 'uint8')');
end
return;
|