Commit | Line | Data |
---|---|---|
69ab55f7 MW |
1 | #! /usr/bin/tclsh8.5 |
2 | ### -*-tcl-*- | |
3 | ### | |
4 | ### Insert a certificate request into the database. | |
5 | ### | |
6 | ### (c) 2011 Mark Wooding | |
7 | ### | |
8 | ||
9 | ###----- Licensing notice --------------------------------------------------- | |
10 | ### | |
11 | ### This program is free software; you can redistribute it and/or modify | |
12 | ### it under the terms of the GNU General Public License as published by | |
13 | ### the Free Software Foundation; either version 2 of the License, or | |
14 | ### (at your option) any later version. | |
15 | ### | |
16 | ### This program is distributed in the hope that it will be useful, | |
17 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ### GNU General Public License for more details. | |
20 | ### | |
21 | ### You should have received a copy of the GNU General Public License | |
22 | ### along with this program; if not, write to the Free Software Foundation, | |
23 | ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
24 | ||
25 | ## Find the common utilities. | |
26 | source [file join [file dirname $argv0] "../lib/func.tcl"] | |
27 | ||
28 | ## Parse the command line. | |
29 | set O(replace) false | |
30 | set usage "usage: $argv0 \[-replace\] PROFILE TAG FILE" | |
31 | for {set i 0} {$i < [llength $argv]} {incr i} { | |
32 | switch -glob -- [lindex $argv $i] { | |
33 | "-replace" { | |
34 | set O(replace) true | |
35 | } | |
36 | "--" { | |
37 | incr i | |
38 | break | |
39 | } | |
40 | "-*" { | |
41 | puts stderr $usage | |
42 | exit 1 | |
43 | } | |
44 | default { | |
45 | break | |
46 | } | |
47 | } | |
48 | } | |
49 | set args [lrange $argv $i end] | |
50 | if {[llength $args] != 3} { | |
51 | puts stderr $usage | |
52 | exit 1 | |
53 | } | |
54 | lassign $args profile tag file | |
55 | ||
56 | ## Open the database. | |
57 | sqlite3 db "$CERTROOT/state/ca.db" | |
58 | ||
59 | ## Do most of the work in a transaction. | |
60 | db transaction { | |
61 | with-cleanup { | |
62 | ||
63 | ## Check whether this tag is already taken. | |
64 | if {!$O(replace) && [db exists { | |
65 | SELECT 1 FROM request | |
66 | WHERE tag = $tag AND st = 'active'; | |
67 | }]} { | |
68 | error "request `$tag' already active" | |
69 | } | |
70 | ||
71 | ## Check whether the profile exists. | |
72 | if {![db exists { | |
9e49709b | 73 | SELECT 1 FROM profile WHERE label = $profile AND tombstone = 0; |
69ab55f7 MW |
74 | }]} { |
75 | error "unknown profile `$profile'" | |
76 | } | |
77 | ||
78 | ## Copy the file away. | |
79 | fresh-temp "$CERTROOT/tmp" tmp { | |
7d993891 | 80 | exec openssl req -text -in $file -out $tmp |
69ab55f7 MW |
81 | } |
82 | cleanup { file delete $tmp } | |
83 | ||
84 | ## Get lots of information about the request. | |
85 | set dn [req-dn $tmp] | |
86 | set hash [req-key-hash $tmp] | |
87 | ||
88 | ## Get an id number for the new request. | |
89 | db eval { | |
90 | UPDATE meta | |
91 | SET request_seq = request_seq + 1; | |
92 | } | |
93 | set id [db eval { | |
94 | SELECT request_seq FROM meta; | |
95 | }] | |
96 | ||
97 | ## Insert the new record into the request table. | |
98 | db eval { | |
99 | UPDATE request SET st = 'withdrawn' WHERE tag = $tag AND st = 'active'; | |
100 | INSERT INTO request(id, tag, dn, hash, st, profile) | |
101 | VALUES ($id, $tag, $dn, @hash, 'active', $profile); | |
102 | } | |
103 | ||
104 | ## Link the file into the right place. | |
105 | file link -hard "$CERTROOT/req/by-id/$id" $tmp | |
106 | exec ln -sf "../by-id/$id" "$CERTROOT/req/active/$tag" | |
107 | } | |
108 | ||
109 | ## Issue a shiny new certificate. | |
110 | issue-cert $id [now] | |
111 | } | |
52caecdc MW |
112 | |
113 | ## Publish any necessary changes. | |
114 | update-hook |