bin/add: Don't allow adding requests with defunct profiles.
[ca] / bin / add
CommitLineData
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.
26source [file join [file dirname $argv0] "../lib/func.tcl"]
27
28## Parse the command line.
29set O(replace) false
30set usage "usage: $argv0 \[-replace\] PROFILE TAG FILE"
31for {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}
49set args [lrange $argv $i end]
50if {[llength $args] != 3} {
51 puts stderr $usage
52 exit 1
53}
54lassign $args profile tag file
55
56## Open the database.
57sqlite3 db "$CERTROOT/state/ca.db"
58
59## Do most of the work in a transaction.
60db 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.
114update-hook