forked from dashingsoft/pyarmor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpyarmor-deprecated.py
executable file
·843 lines (683 loc) · 27.5 KB
/
pyarmor-deprecated.py
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
#############################################################
# #
# Copyright @ 2013 - 2017 Dashingsoft corp. #
# All rights reserved. #
# #
# pyarmor #
# #
# Version: 1.7.0 - 3.3.0 #
# #
#############################################################
#
# DEPRECATED from v3.4. It will be replaced by pyarmor2.py
# from v4.
#
# @File: pyarmor.py
#
# @Author: Jondy Zhao([email protected])
#
# @Create Date: 2013/07/24
#
# @Description:
#
# A tool used to import or un encrypted python scripts.
#
from distutils.filelist import FileList
from distutils.text_file import TextFile
from distutils.util import get_platform
import fnmatch
import getopt
import glob
import imp
import logging
import os
import shutil
import sys
import tempfile
import time
from zipfile import ZipFile
try:
unhexlify = bytes.fromhex
except Exception:
from binascii import a2b_hex as unhexlify
from config import (version, version_info)
dll_name = '_pytransform'
dll_ext = '.dylib' if sys.platform == 'darwin' \
else '.dll' if sys.platform in ('win32', 'cygwin') else '.so'
# Extra suffix char for encrypted python scripts
ext_char = 'e'
wrap_runner = '''import pyimcore
from pytransform import exec_file
exec_file('%s')
'''
trial_info = '''
You're using trail version. Free trial version never expires,
the limitations are
- The maximum size of code object is 35728 bytes in trial version
- The scripts obfuscated by trial version are not private. It means
anyone could generate the license file which works for these
obfuscated scripts.
A registration code is required to obfuscate big code object or
generate private obfuscated scripts.
If PyArmor is helpful for you, please purchase one by visiting
https://order.shareit.com/cart/add?vendorid=200089125&PRODUCT[300871197]=1
If you have received a registration code, run the following command to
make it effective::
pyarmor register REGISTRATION_CODE
Enjoy it!
'''
help_footer = '''
For more information, refer to http://pyarmor.dashingsoft.com
'''
# The last three components of the filename before the extension are
# called "compatibility tags." The compatibility tags express the
# package's basic interpreter requirements and are detailed in PEP
# 425(https://www.python.org/dev/peps/pep-0425).
plat_name = get_platform().split('-')
plat_name = '_'.join(plat_name if len(plat_name) < 3 else plat_name[0:3:2])
plat_name = plat_name.replace('i586', 'i386') \
.replace('i686', 'i386') \
.replace('armv7l', 'armv7') \
.replace('intel', 'x86_64')
def _import_pytransform():
try:
m = __import__('pytransform')
if hasattr(m, 'plat_path'):
m.plat_path = 'platforms'
m.pyarmor_init(is_runtime=1)
return m
except Exception:
pass
logging.info('Searching pytransform library ...')
path = sys.rootdir
pname = plat_name.replace('i586', 'i386').replace('i686', 'i386')
src = os.path.join(path, 'platforms', pname, dll_name + dll_ext)
if os.path.exists(src):
logging.info('Find pytransform library "%s"', src)
logging.info('Copy %s to %s', src, path)
shutil.copy(src, path)
m = __import__('pytransform')
if hasattr(m, 'plat_path'):
m.plat_path = 'platforms'
m.pyarmor_init(is_runtime=1)
logging.info('Load pytransform OK.')
return m
logging.error('No library %s found', src)
def _get_registration_code():
try:
code = pytransform.get_registration_code()
except Exception:
code = ''
return code
def checklicense(func):
# Fix python25 no "as" keyword in statement "except"
exc_msg = lambda : str(sys.exc_info()[1])
def wrap(*arg, **kwargs):
code = _get_registration_code()
if code == '':
sys.stderr.write('PyArmor Trial Version %s\n' % version)
sys.stderr.write(trial_info)
else:
sys.stderr.write('PyArmor Version %s\n' % version)
try:
func(*arg, **kwargs)
except RuntimeError:
logging.error(exc_msg())
except getopt.GetoptError:
logging.error(exc_msg())
except pytransform.PytransformError:
logging.error(exc_msg())
wrap.__doc__ = func.__doc__
return wrap
def show_version_info(verbose=True):
code = _get_registration_code()
trial = ' Trial' if code == '' else ''
print('PyArmor%s Version %s' % (trial, version))
if verbose:
print(version_info)
if code == '':
print(trial_info)
print(help_footer)
def show_hd_info():
pytransform.show_hd_info()
def usage(command=None):
'''
Usage: pyarmor [command name] [options]
Command name can be one of the following list
help Show this usage
version Show version information
capsule Generate project capsule used to encrypted files
encrypt Encrypt the scripts
license Generate registration code
If you want to know the usage of each command, type the
following command:
pyarmor help [command name]
and you can type the left match command, such as
pyarmor c
or pyarmor cap
or pyarmor capsule
'''
show_version_info(verbose=False)
if command is None:
print(usage.__doc__)
else:
funcname = 'do_' + command
func = globals().get(funcname, usage)
print(func.__doc__)
print(help_footer)
def make_capsule(rootdir=None, filename='project.zip'):
'''Generate all the files used by running encrypted scripts, pack all
of them to a zip file.
rootdir pyarmor root dir, where you can find license files,
auxiliary library and pyshield extension module.
filename output filename, the default value is project.zip
Return True if sucess, otherwise False or raise exception
'''
try:
if rootdir is None:
rootdir = sys.rootdir
except AttributeError:
rootdir = os.path.dirname(os.path.abspath(sys.argv[0]))
logging.info('Rootdir is %s', rootdir)
filelist = 'public.key', 'pyimcore.py', 'pytransform.py'
for x in filelist:
src = os.path.join(rootdir, x)
if not os.path.exists(src):
raise RuntimeError('No %s found in the rootdir' % src)
licfile = os.path.join(rootdir, 'license.lic')
if not os.path.exists(licfile):
raise RuntimeError('Missing license file %s' % licfile)
logging.info('Generating project key ...')
pri, pubx, capkey, lic = pytransform.generate_project_capsule(licfile)
logging.info('Generating project OK.')
logging.info('Writing capsule to %s ...', filename)
myzip = ZipFile(filename, 'w')
try:
myzip.write(os.path.join(rootdir, 'public.key'), 'pyshield.key')
myzip.writestr('pyshield.lic', capkey)
myzip.write(os.path.join(rootdir, 'pyimcore.py'), 'pyimcore.py')
myzip.write(os.path.join(rootdir, 'pytransform.py'), 'pytransform.py')
myzip.writestr('private.key', pri)
myzip.writestr('product.key', pubx)
myzip.writestr('license.lic', lic)
finally:
myzip.close()
logging.info('Write project capsule OK.')
def encrypt_files(files, prokey, mode=8, output=None):
'''Encrypt all the files, all the encrypted scripts will be plused with
a suffix 'e', for example, hello.py -> hello.pye
files list all the scripts
prokey project key file used to encrypt scripts
output output directory. If None, the output file will be saved
in the same path as the original script
Return None if sucess, otherwise raise exception
'''
ext = '.py' if mode in (7, 8, 9, 10, 11, 12, 13, 14) else \
'.pyc' if mode in (1, 3, 4, 5, 6) else '.py' + ext_char
if output is None:
fn = lambda a, b: b[1] + ext
else:
# fn = lambda a, b : os.path.join(a, os.path.basename(b) + ch)
# fn = lambda a, b: os.path.join(a, b[1] + ext)
if not os.path.exists(output):
os.makedirs(output)
def _get_path(a, b):
p = os.path.join(a, b[1] + ext)
d = os.path.dirname(p)
if not os.path.exists(d):
os.makedirs(d)
return p
fn = _get_path
flist = []
for x in files:
flist.append((x[0], fn(output, x)))
logging.info('Encrypt %s to %s', *flist[-1])
if len(flist[:1]) == 0:
logging.info('No any script specified')
else:
if not os.path.exists(prokey):
raise RuntimeError('Missing project key "%s"' % prokey)
pytransform.encrypt_project_files(prokey, tuple(flist), mode)
logging.info('Encrypt all scripts OK.')
def make_license(capsule, filename, code):
myzip = ZipFile(capsule, 'r')
myzip.extract('private.key', tempfile.gettempdir())
prikey = os.path.join(tempfile.tempdir, 'private.key')
try:
pytransform.generate_license_file(filename, prikey, code)
finally:
os.remove(prikey)
@checklicense
def do_capsule(argv):
'''Usage: pyarmor capsule [OPTIONS] [NAME]
Generate a capsule which used to encrypt/decrypt python scripts later,
it will generate random capsule when run this command again. Note that
the trial version of PyArmor will always generate same project capsule
Generately, one project, one capsule.
Available options:
-O, --output=DIR [option] The path used to save license file.
-f, --force [option] Overwrite output file even it exists.
For example,
- Generate default capsule "project.zip":
pyarmor capsule project
- Generate a capsule "mycapsules/foo.zip":
pyarmor capsule --output mycapsules foo
'''
opts, args = getopt.getopt(argv, 'fO:', ['force', 'output='])
output = os.getcwd()
overwrite = False
for o, a in opts:
if o in ('-O', '--output'):
output = a
elif o in ('-f', '--force'):
overwrite = True
if len(args) == 0:
filename = os.path.join(output, 'project.zip')
else:
filename = os.path.join(output, '%s.zip' % args[0])
if os.path.exists(filename) and not overwrite:
logging.info("Specify -f to overwrite it if you really want to do")
raise RuntimeError("Capsule %s already exists" % filename)
if not os.path.exists(output):
logging.info("Make output path %s", output)
os.makedirs(output)
logging.info('Output filename is %s', filename)
make_capsule(sys.rootdir, filename)
logging.info('Generate capsule OK.')
def _parse_template_file(filename, path=None):
template = TextFile(filename,
strip_comments=1,
skip_blanks=1,
join_lines=1,
lstrip_ws=1,
rstrip_ws=1,
collapse_join=1)
lines = template.readlines()
filelist = FileList()
try:
if path is not None and not path == os.getcwd():
oldpath = os.getcwd()
os.chdir(path)
else:
oldpath = None
for line in lines:
filelist.process_template_line(line)
finally:
if oldpath is not None:
os.chdir(oldpath)
return filelist.files
def _parse_file_args(args, srcpath=None):
filelist = []
if srcpath is None:
path, n = '', 0
else:
path, n = srcpath, len(srcpath) + 1
if len(args) == 1 and args[0][0] == '@' and args[0].endswith('MANIFEST.in'):
for x in _parse_template_file(args[0][1:], path=srcpath):
filelist.append((os.path.join(path, x), os.path.splitext(x)[0]))
return filelist
patterns = []
for arg in args:
if arg[0] == '@':
f = open(arg[1:], 'r')
for pattern in f.read().splitlines():
if not pattern.strip() == '':
patterns.append(pattern.strip())
f.close()
else:
patterns.append(arg)
for pat in patterns:
for name in glob.glob(os.path.join(path, pat)):
p = os.path.splitext(name)
filelist.append((name, p[0][n:]))
return filelist
@checklicense
def do_encrypt(argv):
'''Usage: pyarmor encrypt [OPTIONS] [File Patterns or @Filename]
Encrpty the files list in the command line, you can use a specified
pattern according to the rules used by the Unix shell. No tilde
expansion is done, but *, ?, and character ranges expressed with []
will be correctly matched.
You can either list file patterns in one file, one pattern one line,
then add a prefix '@' to the filename.
All the files will be encrypted and saved as orginal file name plus
'e'. By default, the encrypted scripts and all the auxiliary files
used to run the encrypted scripts are save in the path "dist".
Available options:
-O, --output=DIR Output path for runtime files and encrypted
files (if no --in-place)
The default value is "build".
-C, --with-capsule=FILENAME Specify the filename of capsule generated
before.
The default value is "project.zip".
-i, --in-place [option], the encrypted scripts will be
saved in the original path (same as source).
Otherwise, save to --output specified.
-s, --src=DIR [option], the source path of python scripts.
The default value is current path.
-p, --plat-name [option] platform name to run encrypted
scripts. Only used when encrypted scripts
will be run in different platform.
-m, --main=NAME Generate wrapper file to run encrypted script
-e, --mode=MODE Encrypt mode, available value:
0 Encrypt both source and bytecode
1 Encrypt bytecode only.
2 Encrypt source code only.
3 Obfuscate bytecodes.
5 Obfuscate code object of module.
6 Combine mode 3 and 4
7 Obfuscate code object of module,
output wrapper scripts
8 Obfuscate both code object and bytecode,
output wrapper scripts
Mode 0, 1, 2 is deprecated from v3.2.0, this
option can be ignored in general.
-d, --clean Clean output path at start.
--manifest FILENAME Write file list to FILENAME
For examples:
- Encrypt a.py and b.py as a.pyx and b.pyx, saved in the path "dist":
pyarmor encrypt a.py b.py
- Use file pattern to specify files:
pyarmor encrypt a.py *.py src/*.py lib/*.pyc
- Save encrypted files in the directory "/tmp/build" other than "dist":
pyarmor encrypt --output=/tmp/build a.py
- Encrypt python scripts by project capsule "project.zip" in the
current directory:
pyarmor encrypt --with-capsule=project.zip src/*.py
- Encrypt python scripts to run in different platform:
pyarmor encrypt --plat-name=linux_x86_64 a.py b.py
Use MANIFEST.in to list files
pyarmor encrypt --with-capsule=project.zip @myproject/MANIFEST.in
It's Following the Distutils’ own manifest template
'''
opts, args = getopt.getopt(
argv, 'C:de:im:O:p:s:',
['in-place', 'output=', 'src=', 'with-capsule=', 'plat-name=',
'main=', 'clean', 'mode=', 'manifest=']
)
output = 'build'
srcpath = None
capsule = 'project.zip'
inplace = False
pname = None
extfile = None
mainname = []
clean = False
mode = 8
manifest = None
for o, a in opts:
if o in ('-O', '--output'):
output = a
elif o in ('-s', '--src'):
srcpath = a
elif o in ('-i', '--in-place'):
inplace = True
elif o in ('-C', '--with-capsule'):
capsule = a
elif o in ('-p', '--plat-name'):
pname = a
elif o in ('-d', '--clean'):
clean = True
elif o in ('-e', '--mode'):
if a not in ('0', '1', '2', '3', '5', '6',
'7', '8', '9', '10', '11', '12',
'13', '14'):
raise RuntimeError('Invalid mode "%s"' % a)
mode = int(a)
elif o in ('-m', '--main'):
mainname.append(a)
elif o in ('--manifest', ):
manifest = a
if srcpath is not None and not os.path.exists(srcpath):
raise RuntimeError('No found specified source path "%s"' % srcpath)
if capsule is None or not os.path.exists(capsule):
raise RuntimeError('No found capsule file %s' % capsule)
# Maybe user specify an empty path
if output == '':
output = 'build'
logging.info('Output path is %s' % output)
if os.path.exists(output) and clean:
logging.info('Removing output path %s', output)
shutil.rmtree(output)
logging.info('Remove output path OK.')
if not os.path.exists(output):
logging.info('Make output path %s', output)
os.makedirs(output)
if pname is None:
extfile = os.path.join(sys.rootdir, dll_name + dll_ext)
else:
logging.info("Cross publish, target platform is %s", pname)
name = dll_name + ('.so' if pname.startswith('linux') else '.dll')
extfile = os.path.join(sys.rootdir, 'platforms', pname, name)
if not os.path.exists(extfile):
# Need to download platforms/... from pyarmor homepage
logging.info('You need download prebuilt library files '
'from pyarmor homepage first.')
raise RuntimeError('Missing cross platform library %s' % extfile)
logging.info('Copy %s to %s' % (extfile, output))
shutil.copy(extfile, output)
logging.info('Extract capsule %s ...', capsule)
ZipFile(capsule).extractall(path=output)
logging.info('Extract capsule to %s OK.', output)
# Fix bootstrap restrict issue from v5.7.0
make_license(capsule, os.path.join(output, 'license.lic'),
'*FLAGS:A*CODE:PyArmor')
if mode >= 3:
logging.info('Encrypt mode: %s', mode)
with open(os.path.join(output, 'pyimcore.py'), 'w') as f:
lines = 'from pytransform import old_init_runtime', \
'old_init_runtime(0, 0, 0, 0)', ''
f.write('\n'.join(lines))
elif mode:
logging.info('Encrypt mode: %s', mode)
with open(os.path.join(output, 'pyimcore.py'), 'r') as f:
lines = f.read()
with open(os.path.join(output, 'pyimcore.py'), 'w') as f:
i = lines.rfind('\n\n')
if i == -1:
raise RuntimeError('Invalid pyimcore.py')
f.write(lines[:i])
if mode == 1:
f.write('\n\nold_init_runtime()\n')
elif mode == 2:
f.write('\n\nsys.meta_path.append(PyshieldImporter())\n'
'old_init_runtime(0, 0, 0, 0)\n')
prikey = os.path.join(output, 'private.key')
if os.path.exists(prikey):
logging.info('Remove private key %s in the output', prikey)
os.remove(prikey)
if mode not in (7, 8, 9, 10, 11, 12, 13, 14):
for name in mainname:
n = name.find(':')
if n == -1:
script = os.path.join(output, name + '.py')
else:
script = os.path.join(output, name[n+1:])
name = name[:n]
logging.info('Writing script wrapper %s ...', script)
ch = 'c' if mode == 1 or mode == 3 else ext_char
with open(script, 'w') as f:
f.write(wrap_runner % (name + '.py' + ch))
logging.info('Write script wrapper OK.')
filelist = _parse_file_args(args, srcpath=srcpath)
if manifest is not None:
logging.info('Write filelist to %s', manifest)
with open(manifest, 'w') as fp:
fp.write('\n'.join([x[0] for x in filelist]))
if len(filelist[:1]) == 0:
logging.info('Generate extra files OK.')
else:
prokey = os.path.join(output, 'product.key')
if not os.path.exists(prokey):
raise RuntimeError('Missing project key %s' % prokey)
logging.info('Encrypt files ...')
encrypt_files(filelist, prokey, mode, None if inplace else output)
if mode in (7, 8, 9, 10, 11, 12, 13, 14):
for name in mainname:
script = os.path.join(
output, name + ('' if name.endswith('.py') else '.py'))
with open(script, 'r') as f:
source = f.read()
logging.info('Patch entry script %s.', script)
with open(script, 'w') as f:
f.write('import pyimcore\n')
f.write(source)
logging.info('Encrypt files OK.')
@checklicense
def do_license(argv):
'''
Usage: pyarmor license [Options] [CODE]
Generate a registration code for project capsule, save it to "license.txt"
by default.
Available options:
-O, --output=DIR Path used to save license file.
-B, --bind-disk="XX" [optional] Generate license file bind to
harddisk of one machine.
--bind-mac="XX:YY" [optional] Generate license file bind to
mac address of one machine.
--bind-ip="a.b.c.d" [optional] Generate license file bind to
ipv4 of one machine.
--bind-domain="domain" [optional] Generate license file bind to
domain of one machine.
-F, --bind-file=FILENAME [option] Generate license file bind to
fixed file, for example, ssh private key.
-e, --expired-date=YYYY-MM-NN [option] Generate expired license file.
It could be combined with "--bind"
-C, --with-capsule=FILENAME [required] Specify the filename of capsule
generated before.
For example,
- Generate a license file "license.lic" for project capsule "project.zip":
pyarmor license --wth-capsule=project.zip MYPROJECT-0001
- Generate a license file "license.lic" expired in 05/30/2015:
pyarmor license --wth-capsule=project.zip -e 2015-05-30 MYPROJECT-0001
- Generate a license file "license.lic" bind to machine whose harddisk's
serial number is "PBN2081SF3NJ5T":
pyarmor license --wth-capsule=project.zip --bind-disk PBN2081SF3NJ5T
- Generate a license file "license.lic" bind to ssh key file id_rsa:
pyarmor license --wth-capsule=project.zip \
--bind-file src/id_rsa ~/.ssh/my_id_rsa
File "src/id_rsa" is in the develop machine, pyarmor will read data
from this file when generating license file.
Argument "~/.ssh/id_rsa" means full path filename in target machine,
pyarmor will find this file as key file when decrypting python scripts.
You shuold copy "license.lic" to target machine, at the same time,
copy "src/id_rsa" to target machine as "~/.ssh/my_id_rsa"
'''
opts, args = getopt.getopt(
argv, 'B:C:e:F:O:',
['bind-disk=', 'bind-mac=', 'bind-ip=', 'bind-domain=',
'expired-date=', 'bind-file=', 'with-capsule=', 'output=']
)
filename = 'license.lic.txt'
bindfile = None
capsule = 'project.zip'
bindfileflag = False
binddisk = None
bindip = None
bindmac = None
binddomain = None
expired = None
for o, a in opts:
if o in ('-C', '--with-capsule'):
capsule = a
elif o in ('-B', '--bind-disk'):
binddisk = a
elif o in ('-B', '--bind-mac'):
bindmac = a
elif o in ('-B', '--bind-ip'):
bindip = a
elif o in ('-B', '--bind-domain'):
binddomain = a
elif o in ('-F', '--bind-file'):
bindfileflag = True
bindfile = a
elif o in ('-e', '--expired-date'):
expired = a
elif o in ('-O', '--output'):
if os.path.exists(a) and os.path.isdir(a):
filename = os.path.join(a, 'license.lic.txt')
else:
filename = a
if len(args) == 0:
key = 'POWERD-BY-PYARMOR'
else:
key = args[0]
if expired is None:
fmt = ''
else:
logging.info('License file expired at %s', expired)
fmt = '*TIME:%.0f\n' % time.mktime(time.strptime(expired, '%Y-%m-%d'))
# Fix bootstrap restrict issue from v5.7.0
if key.find('FLAGS') == -1:
fmt = '%s*FLAGS:A' % fmt
if binddisk:
logging.info('License file bind to harddisk "%s"', binddisk)
fmt = '%s*HARDDISK:%s' % (fmt, binddisk)
if bindmac:
logging.info('License file bind to mac addr "%s"', key)
fmt = '%s*IFMAC:%s' % (fmt, bindmac)
if bindip:
logging.info('License file bind to ip "%s"', key)
fmt = '%s*IFIPV4:%s' % (fmt, bindip)
if binddomain:
logging.info('License file bind to domain "%s"', key)
fmt = '%s*DOMAIN:%s' % (fmt, binddomain)
if bindfileflag:
if os.path.exists(bindfile):
logging.info('You need copy %s to target machine as %s '
'with license file.', bindfile, key)
f = open(bindfile, 'rb')
s = f.read()
f.close()
if sys.version_info[0] == 3:
fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s.decode())
else:
fmt = '%s*FIXKEY:%s;%s' % (fmt, key, s)
else:
raise RuntimeError('Bind file %s not found' % bindfile)
logging.info('Output filename is %s', filename)
make_license(capsule, filename, fmt if fmt else key)
logging.info('Generate license file "%s" OK.', filename)
if __name__ == '__main__':
sys.rootdir = os.path.dirname(os.path.abspath(sys.argv[0]))
logging.basicConfig(
level=logging.INFO,
format='%(levelname)-8s %(message)s',
# filename=os.path.join(sys.rootdir, 'pyarmor.log'),
# filemode='w',
)
# if (len(sys.argv) == 1 or
# sys.argv[1] not in ('help', 'encrypt', 'capsule', 'license')):
# from pyarmor import main as main2
# main2(sys.argv[1:])
# sys.exit(0)
if len(sys.argv) == 1:
usage()
sys.exit(0)
command = sys.argv[1]
if len(sys.argv) >= 3 and sys.argv[2] == 'help':
usage(command)
sys.exit(0)
pytransform = _import_pytransform()
if pytransform is None:
sys.exit(1)
if 'help'.startswith(command) or sys.argv[1].startswith('-h'):
try:
usage(sys.argv[2])
except IndexError:
usage()
elif 'version'.startswith(command) or sys.argv[1].startswith('-v'):
show_version_info()
elif 'capsule'.startswith(command):
do_capsule(sys.argv[2:])
elif 'encrypt'.startswith(command):
do_encrypt(sys.argv[2:])
elif 'license'.startswith(command):
do_license(sys.argv[2:])
elif 'hdinfo'.startswith(command):
show_hd_info()
else:
usage(command)