Collection of mostly command line tools / PHP scripts. Somewhat out of date.

⌈⌋ ⎇ branch:  scripts + snippets


Check-in [882cff0fe3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:copies disk image around (dd), while luks encoding the partition
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 882cff0fe344aaa351ff58deced7ac2cc40d8794
User & Date: mario 2012-01-09 04:08:52
Context
2012-01-09
04:09
converts smarty templates into plain php check-in: 26da8c8473 user: mario tags: trunk
04:08
copies disk image around (dd), while luks encoding the partition check-in: 882cff0fe3 user: mario tags: trunk
04:07
initial empty check-in check-in: 3733c93d1a user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added luksConvert.







































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/python
#
# utility for in-place partition encryption with LUKS container;
# see also:
#
#   http://help.ubuntu.com/community/EncryptedFilesystemHowto7
#
# milki placed this into the PUBLIC DOMAIN.

import os
import sys
import re
from random import randint as rand
from getopt import gnu_getopt as getopt


class luksConvert:

  def run(self):
    print "\033[31m"+"luksConvert v1.0 - NO WARRANTY. USE AT YOUR OWN RISK."+"\033[0;0m\n"
    self.get_args()
    self.testrun_cryptsetup()
    self.check_sdev()
    self.start()

  def get_args(self):

    opts,files = getopt(sys.argv[1:], "yvc:s:h:", ["cipher=","hash=","key-size="])
    opts = dict(opts)
      
    if len(files) != 1:
      print "syntax: luksConvert /dev/unencrypted [...]"
      print "  further options similar to cryptsetup:"
      print "  [-y] -[v] [-c aes-cbc-essiv:sha256] [-h sha1] [-s 128]\n"
      sys.exit()
    else:
      self.sdev = files[0]
      
    self.hash = opts.get("--hash", opts.get("-h", "sha1"))
    self.keysize = opts.get("--key-size", opts.get("-s", "128"))
    self.cipher = opts.get("--cipher", opts.get("-c", "aes-cbc-essiv:sha256"))

    
  def luksCheck(self, devicename):
    output = self.pipe("LC_ALL=C  cryptsetup luksDump " + devicename)
    return output.find("offset:\t1032") >= 0

    
  def testrun_cryptsetup(self):
    print "* performing cryptsetup test run... ",
    fn = "/tmp/lC-test-"+str(rand(1000,9999))
    os.system("dd if=/dev/zero of="+fn+" bs=1000 count=10000 2>/dev/null")
    os.system("mkfs.vfat "+fn+" >/dev/null")
    loop = self.pipe("losetup -f").strip()
    os.system("losetup "+loop+" "+fn+" >/dev/null")
    ok = 0==os.system("echo passw0rd | cryptsetup luksFormat "+loop+" -q -c "+self.cipher+" -h "+self.hash+" -s "+self.keysize+" 2>/dev/null")
    ok = ok and self.luksCheck(loop)
    os.system("losetup -d "+loop+" ; rm "+fn);
    if ok:
      print "ok\n"
    else:
      print "fail\n  WARNING: cryptsetup test run didn't work as expected\n"
      sys.exit()
    return ok


  def check_sdev(self):
    # read
    f = open(self.sdev, "rb")
    startsector = f.read(2048)
    f.close()
    # check magic numbers
    if startsector[0x438:0x43A] != "\x53\xEF":
      print "* "+self.sdev+" doesn't seem to contain ext2/ext3 system\n"
    if startsector[0:4] == "LUKS":
      print "* Source device already has a LUKS header. Don't run this tool twice!"
      print "  (Or put back the backup on, if the last run of luksConvert failed.)\n"
      sys.exit()
    # check filesystem size < below partition size (-1032)
    print "* Hopefully you have shrunken your filesystem on " + self.sdev + "\n  already - by 1032 sectors / 516KB at least! (Use resize2fs.)\n"
    return 0


  def cmd(self, cmd):
    print cmd
    return not os.system(cmd)
    

  def pipe(self, cmd):
    pc = os.popen(cmd, "r")
    pc_s = ""
    try:
      pc_s = pc.read(4000)
    except:
      0
    return pc_s


  # walks through the cryptsetup and sector copying process
  def start(self):

    # read first 5MB
    source = blockdevice(self.sdev, "rb")
    data1 = source.readBlock()

    # back it up
    fn = "luksconvert.backup."+str(rand(1000,9999))
    f = open(fn, "wb")
    f.write(data1)
    f.close()
    print "* First 5MB of source device " + self.sdev + " backed up into\n  "+fn+"\n"
    
    # create encrypted devmapper node
    cryptnode = "lconvert" + str(rand(1000,9999))
    print "* DO NOT ABORT AFTER THIS POINT"
    print "  first sectors will be overwritten, AFTER you entered a password\n"
    if not self.cmd("cryptsetup luksFormat "+self.sdev+" -v -y -c "+self.cipher+" -h "+self.hash+" -s "+self.keysize):
      print "\nERROR. ABORTING.\n"
      sys.exit()

    # check cryptsetup
    if (not self.luksCheck(self.sdev)):
      print "\n* WARNING: the written LUKS header seems to be larger than 1032 sectors. Unexpected. Read buffer (5MB) might have been too small and data already lost. But proceeding anyway. (If you abort here, be sure to put the backup block onto the source device.)\n"
    
    # init devmapper node, open encrypted target
    print "\n* yes, you have to enter your password once more:\n"
    while not self.cmd("cryptsetup luksOpen "+self.sdev+" "+cryptnode):
      print "* ERROR. If you already forgot the password, you need the sectorbackup."
    dest = blockdevice("/dev/mapper/"+cryptnode, "wb")
    
    # copying process
    print "* now copying everything over... please wait\n"
    # 
    # first block is already read,
    # get a second 5MB, before writing the first,
    # because the last 516K data always overlap
    #
    while (1):
      # info
      print "  " + str(source.pos / 1024) + "K\r",
      # pre-read next block
      data2 = source.readBlock()
      if not len(data2):
        break;
      # write
      dest.writeBlock(data1)
      data1 = data2
    # write remaining
    dest.writeBlock(data1)
    print "            \n"
    
    # close up
    dest.handle.close()
    source.handle.close()
    self.cmd("cryptsetup luksClose "+cryptnode)
    print
    self.cmd("sync")

    # thanks for buying
    print "\n* done        \n"
      

class blockdevice:

  def __init__(self, fn, mode, bsize=5*1024*1024):
    self.fn = fn
    self.handle = open(fn, mode)
    self.bsize = bsize
    self.pos = 0
    
  def readBlock(self):
    try:
      block = self.handle.read(self.bsize)
    except:
      print "eof / read error"
    self.pos += len(block)
    return block
    
  def writeBlock(self, block):
    try:
      self.handle.write(block)
    except Exception, e:
      print
      print e
      print "\n* writing error or device "+self.fn+" full"
      print "  (should in fact occour for the last 1032 sectors from source device)"
    self.pos += len(block)

     


luksConvert().run()