Initial revision
[blender.git] / source / blender / src / pub / license_key.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include "license_key.h"
34 #include "keyed_functions.h"
35 #include "BKE_utildefines.h"
36 #include "BIF_screen.h"  // splash
37 #include "BIF_toolbox.h"
38 #include "blenkey.h"
39 #include <stdio.h>
40 #include <string.h>
41
42 #include "BLI_blenlib.h"
43
44 #include "BLO_readfile.h"
45 #include "BLO_keyStore.h"
46
47 int LICENSE_KEY_VALID = FALSE;
48 int I_AM_PUBLISHER = TRUE;
49
50 static UserStruct User;
51
52 // Python stuff
53
54 #include "Python.h"
55 #include "marshal.h" 
56 #include "compile.h" /* to give us PyCodeObject */
57 #include "eval.h"               /* prototype for PyEval_EvalCode */
58
59 #include "BPY_extern.h"
60
61 #include "IMB_imbuf.h"
62
63 Fptr g_functab[PYKEY_TABLEN];
64 Fptr g_ptrtab[PYKEY_TABLEN];
65
66 static int g_seed[3] = PYKEY_SEED;
67 static PyObject *g_module_self;
68 static PyObject *g_main;
69
70
71 // end Python stuff
72
73 // **************** PYTHON STUFF **************************
74 /* ----------------------------------------------------- */
75 /* this is the dummy functions to demonstrate */
76
77 int sticky_shoes(void *vp)
78 {
79         return 0;
80 }
81
82 /*
83 int key_func1(void *vp) {
84         printf("function 1 called\n");
85 }
86
87 */
88 int key_return_true(void *vp) {
89         return 1;
90 }
91
92
93 /* ----------------------------------------------------- */
94
95 /* Declarations for objects of type Fplist */
96
97
98 static char prot_getseed__doc__[] = "";
99
100 static PyObject *
101 prot_getseed(self, args)
102         PyObject *self; /* Not used */
103         PyObject *args;
104 {
105         PyObject *p;
106         p = PyTuple_New(3);
107         PyTuple_SetItem(p, 0, PyInt_FromLong(g_seed[0]));
108         PyTuple_SetItem(p, 1, PyInt_FromLong(g_seed[1]));
109         PyTuple_SetItem(p, 2, PyInt_FromLong(g_seed[2]));
110         return p;
111 }
112
113 static char prot_getlen__doc__[] = "";
114 static PyObject *
115 prot_getlen(self, args)
116         PyObject *self; /* Not used */
117         PyObject *args;
118 {
119         return Py_BuildValue("i", PYKEY_TABLEN);
120 }
121
122 static char prot_getptr__doc__[] =
123 ""
124 ;
125
126 static PyObject *
127 prot_getptr(self, args)
128         PyObject *self; /* Not used */
129         PyObject *args;
130 {
131         PyObject *p;
132         Fptr f;
133         int index;
134         /* we don't catch errors here, we're in the key code */
135         if (!g_functab)
136                 return NULL;
137         if (!PyArg_ParseTuple(args, "i", &index))
138                 return NULL;
139         if (index >= PYKEY_TABLEN)
140                 return NULL;
141
142         f = g_functab[index];
143         p = PyCObject_FromVoidPtr(f , NULL);
144         return p;
145 }
146
147 static char prot_setptr__doc__[] =
148 ""
149 ;
150 static PyObject *
151 prot_setptr(self, args)
152         PyObject *self; /* Not used */
153         PyObject *args;
154 {
155         PyObject *p;
156
157         int index;
158
159         if (!g_ptrtab) 
160                 return NULL;
161         if (!PyArg_ParseTuple(args, "iO", &index, &p))
162                 return NULL;
163         if (index >= PYKEY_TABLEN)
164                 return NULL;
165         if (!PyCObject_Check(p)) {
166                 return NULL;
167         }
168
169         g_ptrtab[index] = PyCObject_AsVoidPtr(p);
170         return Py_BuildValue("i", 1);
171 }
172
173 static PyObject *callkeycode(
174         unsigned char *keycode,
175         int keycodelen)
176 {
177         PyCodeObject *code;
178         PyObject *maindict = PyModule_GetDict(g_main);
179
180         code = (PyCodeObject *) PyMarshal_ReadObjectFromString(keycode, keycodelen);
181         if (!PyEval_EvalCode(code, maindict, maindict))
182                 return NULL;
183         return Py_BuildValue("i", 1);
184 }
185
186
187
188 /* List of methods defined in the module */
189
190 static struct PyMethodDef prot_methods[] = {
191         {"getlen",      (PyCFunction)prot_getlen,       METH_VARARGS,   prot_getlen__doc__},
192         {"getseed",     (PyCFunction)prot_getseed,      METH_VARARGS,   prot_getseed__doc__},
193         {"getptr",      (PyCFunction)prot_getptr,       METH_VARARGS,   prot_getptr__doc__},
194         {"setptr",      (PyCFunction)prot_setptr,       METH_VARARGS,   prot_setptr__doc__},
195  
196         {NULL,   (PyCFunction)NULL, 0, NULL}            /* sentinel */
197 };
198
199
200 /* Initialization function for the module (*must* be called initprot) */
201
202 static char prot_module_documentation[] = "No Documentation";
203
204 static void init_ftable(void)  // initializes functiontable
205 {
206         int i;
207
208         g_functab[0] = &key_func1;
209         g_functab[1] = &key_func2;
210         g_functab[2] = &key_func3;
211 /*  add more key_funcs here */
212
213         for (i = 3; i < PYKEY_TABLEN; i++)
214         {
215                 g_functab[i] = &sticky_shoes;
216         }
217 }
218
219
220 static void init_ptable(void)  // initializes functiontable
221 {
222         int i;
223
224         for (i = 0; i < PYKEY_TABLEN; i++)
225         {
226                 g_ptrtab[i] = &sticky_shoes;
227         }
228 }
229
230
231 static void insertname(PyObject *m,PyObject *p, char *name)
232 {
233         PyObject *d = PyModule_GetDict(m);
234
235         PyDict_SetItemString(d, name, p);
236         Py_DECREF(p);
237 }
238
239 /* initialisation */
240 static void initprot()
241 {
242         PyObject *m, *d;
243         PyObject *capi1;
244         PyObject *ErrorObject;
245
246         init_ftable(); 
247
248         g_main = PyImport_AddModule("__main__");
249
250         m = Py_InitModule4("prot", prot_methods,
251                 prot_module_documentation,
252                 (PyObject*)NULL,PYTHON_API_VERSION);
253         g_module_self = m;      
254         d = PyModule_GetDict(m);
255         ErrorObject = PyString_FromString("prot.error");
256         PyDict_SetItemString(d, "error", ErrorObject);
257
258         /* add global object */
259
260         capi1 = PyCObject_FromVoidPtr((void *)g_functab , NULL);
261         if (capi1) {
262                 insertname(m, capi1, "APIfunctab");
263         }       
264         
265         /* Check for errors */
266         if (PyErr_Occurred())
267                 Py_FatalError("can't initialize module prot");
268
269         init_ptable(); 
270 }
271
272 // ******************************* KEY STUFF *********************
273
274 static void create_key_name(char * keyname)
275 {
276         sprintf(keyname, "%s/.BPkey", BLI_gethome());
277 }
278
279 void checkhome()
280 {
281         int keyresult;
282         char *HexPriv, *HexPub, *HexPython;
283         byte *Byte;
284         char keyname[FILE_MAXDIR + FILE_MAXFILE];
285         int wasInitialized;
286         unsigned char *keycode = NULL;
287         int keycodelen = 0;
288
289         create_key_name(keyname);
290         keyresult = ReadKeyFile(keyname, &User, &HexPriv, &HexPub,
291                                 &Byte, &HexPython);
292         if (keyresult != 0) {
293             // printf("\nReadKeyFile error %d\n", keyresult);
294         } else {
295             // printf("\nReadKeyFile OK\n");
296                 LICENSE_KEY_VALID = TRUE;
297
298                 wasInitialized = Py_IsInitialized();
299                 
300                 // make it failsafe if python interpreter was already initialized
301                 if (wasInitialized) 
302                         Py_Initialize();
303                         
304                 initprot();                   // initialize module and function tables
305                 // get python byte code
306                 keycode = DeHexify(HexPython);
307                 keycodelen = strlen(HexPython) / 2;
308
309                 callkeycode(keycode, keycodelen);
310
311                 Py_Finalize(); 
312
313                 if (wasInitialized)     // if we were initialized,
314                         BPY_start_python(); // restart creator python
315
316                 //some debugging stuff
317                 // print_ptable();
318
319                 // Store key stuff for use by stream
320                 keyStoreConstructor(
321                         &User,
322                         HexPriv,
323                         HexPub,
324                         Byte,
325                         HexPython);
326
327                 // other initialization code
328
329                 // enable png writing in the ImBuf library
330                 IMB_fp_png_encode = IMB_png_encode;
331         }
332 }
333
334 void SHOW_LICENSE_KEY(void)
335 {
336         extern int datatoc_tonize;
337         extern char datatoc_ton[];
338         char string[1024];
339         int maxtype, type;
340         char *typestrings[] = {
341                 "",
342                 "Individual",
343                 "Company",
344                 "Unlimited",
345                 "Educational"};
346
347         maxtype = (sizeof(typestrings) / sizeof(char *)) - 1;
348         type = User.keytype;
349         if (type > maxtype) {
350                 type = 0;
351         }
352
353         if (LICENSE_KEY_VALID) {
354                 sprintf(string, "%s License registered to: %s (%s)", typestrings[type], User.name, User.email);
355                 splash((void *)datatoc_ton, datatoc_tonize, string);
356         }
357 }
358
359 void loadKeyboard(char * name)
360 {
361         char keyname[FILE_MAXDIR + FILE_MAXFILE];
362         FILE *in, *out;
363         char string[1024], *match = 0;
364         int i, c;
365         int found = 0;
366
367         // make sure we don't overwrite a valid key...
368         
369         if (!LICENSE_KEY_VALID) {
370                 in = fopen(name, "rb");
371                 if (in) {
372                         // scan for blender key magic, read strings
373                         // with anything but a newline
374                         while (fscanf(in, "%1000[^\n\r]", string) != EOF) {
375                                 match = strstr(string, BLENKEYMAGIC);
376                                 if (match) {
377                                         break;
378                                 }
379                                 fscanf(in, "\n");
380                         }
381                         
382                         if (match) {
383                                 // found blender key magic, open output file
384                                 // to copy key information
385                                 
386                                 create_key_name(keyname);
387                                 out = fopen(keyname, "wb");
388                                 if (out) {
389                                         // printout first line
390                                         fprintf(out, "%s", match);
391                                         for (i = 0; i < 350; i++) {
392                                                 // handle control characters (\n\r)
393                                                 while (1) {
394                                                         c = getc(in);
395                                                         if (c == '\n') {
396                                                                 // output a \n for each \n in the input
397                                                                 fprintf(out, "\n");
398                                                         } else if (c == EOF) {
399                                                                 break;
400                                                         } else if (c < ' ') {
401                                                                 // skip control characters
402                                                         } else {
403                                                                 ungetc(c, in);
404                                                                 break;
405                                                         }
406                                                 }
407                                                 
408                                                 if (fscanf(in, "%1000[^\n\r]", string) != EOF) {
409                                                         if (strcmp(string, BLENKEYSEPERATOR) == 0) {
410                                                                 found++;
411                                                         }
412                                                         fprintf(out, "%s", string);
413                                                 } else {
414                                                         break;
415                                                 }
416
417                                                 if (found >= 2) {
418                                                         break;
419                                                 }
420                                         }
421                                         
422                                         fclose(out);
423                                         
424                                         checkhome();
425                                         if (LICENSE_KEY_VALID) {
426                                                 SHOW_LICENSE_KEY();
427                                         } else {
428                                                 error("Not a valid license key ! Removing installed key.");
429                                                 BLI_delete(keyname, 0, 0);
430                                         }
431
432                                 } else {
433                                         error("Can't install key");
434                                 }
435                         } else {
436                                 error("File doesn't contain a valid key: %s", name);
437                         }
438
439                         fclose(in);
440
441                         if (LICENSE_KEY_VALID) {
442                                 if (okee("Remove input file: '%s'?", name)) {
443                                         BLI_delete(name, 0, 0);
444                                 }
445                         }
446
447                 } else {
448                         error("File doesn't exist: %s", name);
449                 }
450         }
451 }