1*9781SMoriah.Waterland@Sun.COM /* 2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START 3*9781SMoriah.Waterland@Sun.COM * 4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 7*9781SMoriah.Waterland@Sun.COM * 8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 11*9781SMoriah.Waterland@Sun.COM * and limitations under the License. 12*9781SMoriah.Waterland@Sun.COM * 13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9781SMoriah.Waterland@Sun.COM * 19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END 20*9781SMoriah.Waterland@Sun.COM */ 21*9781SMoriah.Waterland@Sun.COM 22*9781SMoriah.Waterland@Sun.COM /* 23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 25*9781SMoriah.Waterland@Sun.COM */ 26*9781SMoriah.Waterland@Sun.COM 27*9781SMoriah.Waterland@Sun.COM 28*9781SMoriah.Waterland@Sun.COM #include <stdio.h> 29*9781SMoriah.Waterland@Sun.COM #include <stdarg.h> 30*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 31*9781SMoriah.Waterland@Sun.COM #include <string.h> 32*9781SMoriah.Waterland@Sun.COM #include <sys/types.h> 33*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 34*9781SMoriah.Waterland@Sun.COM #include <signal.h> 35*9781SMoriah.Waterland@Sun.COM #include <locale.h> 36*9781SMoriah.Waterland@Sun.COM #include <sys/param.h> 37*9781SMoriah.Waterland@Sun.COM #include <openssl/bio.h> 38*9781SMoriah.Waterland@Sun.COM 39*9781SMoriah.Waterland@Sun.COM #include <libinst.h> 40*9781SMoriah.Waterland@Sun.COM #include <pkglib.h> 41*9781SMoriah.Waterland@Sun.COM #include <pkgerr.h> 42*9781SMoriah.Waterland@Sun.COM #include <keystore.h> 43*9781SMoriah.Waterland@Sun.COM #include "pkgadm.h" 44*9781SMoriah.Waterland@Sun.COM #include "pkgadm_msgs.h" 45*9781SMoriah.Waterland@Sun.COM 46*9781SMoriah.Waterland@Sun.COM /* 47*9781SMoriah.Waterland@Sun.COM * Name: removecert 48*9781SMoriah.Waterland@Sun.COM * Desc: Removes a user certificate and associated private key, 49*9781SMoriah.Waterland@Sun.COM * or a trusted certificate, from the keystore. 50*9781SMoriah.Waterland@Sun.COM * Syntax: addcert [-a app] [-k keystore] -n name [-P passarg] [-R altroot] 51*9781SMoriah.Waterland@Sun.COM */ 52*9781SMoriah.Waterland@Sun.COM int 53*9781SMoriah.Waterland@Sun.COM removecert(int argc, char **argv) 54*9781SMoriah.Waterland@Sun.COM { 55*9781SMoriah.Waterland@Sun.COM int i; 56*9781SMoriah.Waterland@Sun.COM char keystore_file[MAXPATHLEN] = ""; 57*9781SMoriah.Waterland@Sun.COM char *keystore_base = NULL; 58*9781SMoriah.Waterland@Sun.COM char *homedir; 59*9781SMoriah.Waterland@Sun.COM char *passarg = NULL; 60*9781SMoriah.Waterland@Sun.COM char *altroot = NULL; 61*9781SMoriah.Waterland@Sun.COM char *prog = NULL; 62*9781SMoriah.Waterland@Sun.COM char *alias = NULL; 63*9781SMoriah.Waterland@Sun.COM int ret = 1; 64*9781SMoriah.Waterland@Sun.COM PKG_ERR *err = NULL; 65*9781SMoriah.Waterland@Sun.COM keystore_handle_t keystore = NULL; 66*9781SMoriah.Waterland@Sun.COM 67*9781SMoriah.Waterland@Sun.COM while ((i = getopt(argc, argv, ":a:k:n:P:R:")) != EOF) { 68*9781SMoriah.Waterland@Sun.COM switch (i) { 69*9781SMoriah.Waterland@Sun.COM case 'a': 70*9781SMoriah.Waterland@Sun.COM prog = optarg; 71*9781SMoriah.Waterland@Sun.COM break; 72*9781SMoriah.Waterland@Sun.COM case 'k': 73*9781SMoriah.Waterland@Sun.COM keystore_base = optarg; 74*9781SMoriah.Waterland@Sun.COM break; 75*9781SMoriah.Waterland@Sun.COM case 'n': 76*9781SMoriah.Waterland@Sun.COM alias = optarg; 77*9781SMoriah.Waterland@Sun.COM break; 78*9781SMoriah.Waterland@Sun.COM case 'P': 79*9781SMoriah.Waterland@Sun.COM passarg = optarg; 80*9781SMoriah.Waterland@Sun.COM break; 81*9781SMoriah.Waterland@Sun.COM case 'R': 82*9781SMoriah.Waterland@Sun.COM altroot = optarg; 83*9781SMoriah.Waterland@Sun.COM break; 84*9781SMoriah.Waterland@Sun.COM case ':': 85*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt); 86*9781SMoriah.Waterland@Sun.COM /* fallthrough intentional */ 87*9781SMoriah.Waterland@Sun.COM case '?': 88*9781SMoriah.Waterland@Sun.COM default: 89*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_USAGE); 90*9781SMoriah.Waterland@Sun.COM goto cleanup; 91*9781SMoriah.Waterland@Sun.COM } 92*9781SMoriah.Waterland@Sun.COM } 93*9781SMoriah.Waterland@Sun.COM 94*9781SMoriah.Waterland@Sun.COM /* we require a name */ 95*9781SMoriah.Waterland@Sun.COM if (alias == NULL) { 96*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_USAGE); 97*9781SMoriah.Waterland@Sun.COM goto cleanup; 98*9781SMoriah.Waterland@Sun.COM } 99*9781SMoriah.Waterland@Sun.COM 100*9781SMoriah.Waterland@Sun.COM /* should be no arguments left */ 101*9781SMoriah.Waterland@Sun.COM if ((argc-optind) > 0) { 102*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_USAGE); 103*9781SMoriah.Waterland@Sun.COM goto cleanup; 104*9781SMoriah.Waterland@Sun.COM } 105*9781SMoriah.Waterland@Sun.COM 106*9781SMoriah.Waterland@Sun.COM /* set up proper keystore */ 107*9781SMoriah.Waterland@Sun.COM if (keystore_base == NULL) { 108*9781SMoriah.Waterland@Sun.COM if (geteuid() == 0 || altroot != NULL) { 109*9781SMoriah.Waterland@Sun.COM /* 110*9781SMoriah.Waterland@Sun.COM * If we have an alternate 111*9781SMoriah.Waterland@Sun.COM * root, then we have no choice but to use 112*9781SMoriah.Waterland@Sun.COM * root's keystore on that alternate root, 113*9781SMoriah.Waterland@Sun.COM * since there is no way to resolve a 114*9781SMoriah.Waterland@Sun.COM * user's home dir given an alternate root 115*9781SMoriah.Waterland@Sun.COM */ 116*9781SMoriah.Waterland@Sun.COM if (strlcat(keystore_file, PKGSEC, 117*9781SMoriah.Waterland@Sun.COM MAXPATHLEN) >= MAXPATHLEN) { 118*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_TOO_LONG, 119*9781SMoriah.Waterland@Sun.COM keystore_file); 120*9781SMoriah.Waterland@Sun.COM goto cleanup; 121*9781SMoriah.Waterland@Sun.COM } 122*9781SMoriah.Waterland@Sun.COM } else { 123*9781SMoriah.Waterland@Sun.COM if ((homedir = getenv("HOME")) == NULL) { 124*9781SMoriah.Waterland@Sun.COM /* 125*9781SMoriah.Waterland@Sun.COM * not superuser, but no home dir, so 126*9781SMoriah.Waterland@Sun.COM * use superuser's keystore 127*9781SMoriah.Waterland@Sun.COM */ 128*9781SMoriah.Waterland@Sun.COM if (strlcat(keystore_file, PKGSEC, 129*9781SMoriah.Waterland@Sun.COM MAXPATHLEN) >= MAXPATHLEN) { 130*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_TOO_LONG, 131*9781SMoriah.Waterland@Sun.COM keystore_file); 132*9781SMoriah.Waterland@Sun.COM goto cleanup; 133*9781SMoriah.Waterland@Sun.COM } 134*9781SMoriah.Waterland@Sun.COM } else { 135*9781SMoriah.Waterland@Sun.COM if (strlcat(keystore_file, homedir, 136*9781SMoriah.Waterland@Sun.COM MAXPATHLEN) >= MAXPATHLEN) { 137*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_TOO_LONG, 138*9781SMoriah.Waterland@Sun.COM homedir); 139*9781SMoriah.Waterland@Sun.COM goto cleanup; 140*9781SMoriah.Waterland@Sun.COM } 141*9781SMoriah.Waterland@Sun.COM if (strlcat(keystore_file, "/.pkg/security", 142*9781SMoriah.Waterland@Sun.COM MAXPATHLEN) >= MAXPATHLEN) { 143*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_TOO_LONG, 144*9781SMoriah.Waterland@Sun.COM keystore_file); 145*9781SMoriah.Waterland@Sun.COM goto cleanup; 146*9781SMoriah.Waterland@Sun.COM } 147*9781SMoriah.Waterland@Sun.COM } 148*9781SMoriah.Waterland@Sun.COM } 149*9781SMoriah.Waterland@Sun.COM } else { 150*9781SMoriah.Waterland@Sun.COM if (strlcat(keystore_file, keystore_base, 151*9781SMoriah.Waterland@Sun.COM MAXPATHLEN) >= MAXPATHLEN) { 152*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_TOO_LONG, 153*9781SMoriah.Waterland@Sun.COM keystore_base); 154*9781SMoriah.Waterland@Sun.COM goto cleanup; 155*9781SMoriah.Waterland@Sun.COM } 156*9781SMoriah.Waterland@Sun.COM } 157*9781SMoriah.Waterland@Sun.COM 158*9781SMoriah.Waterland@Sun.COM err = pkgerr_new(); 159*9781SMoriah.Waterland@Sun.COM 160*9781SMoriah.Waterland@Sun.COM /* now load the key store */ 161*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_DEBUG, "Loading keystore <%s>", keystore_file); 162*9781SMoriah.Waterland@Sun.COM 163*9781SMoriah.Waterland@Sun.COM set_passphrase_prompt(MSG_KEYSTORE_PASSPROMPT); 164*9781SMoriah.Waterland@Sun.COM set_passphrase_passarg(passarg); 165*9781SMoriah.Waterland@Sun.COM 166*9781SMoriah.Waterland@Sun.COM if (open_keystore(err, keystore_file, prog, pkg_passphrase_cb, 167*9781SMoriah.Waterland@Sun.COM KEYSTORE_ACCESS_READWRITE | KEYSTORE_PATH_HARD, &keystore) != 0) { 168*9781SMoriah.Waterland@Sun.COM log_pkgerr(LOG_MSG_ERR, err); 169*9781SMoriah.Waterland@Sun.COM goto cleanup; 170*9781SMoriah.Waterland@Sun.COM } 171*9781SMoriah.Waterland@Sun.COM 172*9781SMoriah.Waterland@Sun.COM /* now remove the selected certs */ 173*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_DEBUG, "Removing certificate(s) with name <%s>", 174*9781SMoriah.Waterland@Sun.COM alias); 175*9781SMoriah.Waterland@Sun.COM if (delete_cert_and_keys(err, keystore, alias) != 0) { 176*9781SMoriah.Waterland@Sun.COM log_pkgerr(LOG_MSG_ERR, err); 177*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_NO_REMOVECERT, alias); 178*9781SMoriah.Waterland@Sun.COM goto cleanup; 179*9781SMoriah.Waterland@Sun.COM } 180*9781SMoriah.Waterland@Sun.COM 181*9781SMoriah.Waterland@Sun.COM /* now write it back out */ 182*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_DEBUG, "Closing keystore"); 183*9781SMoriah.Waterland@Sun.COM set_passphrase_prompt(MSG_KEYSTORE_PASSOUTPROMPT); 184*9781SMoriah.Waterland@Sun.COM set_passphrase_passarg(passarg); 185*9781SMoriah.Waterland@Sun.COM if (close_keystore(err, keystore, pkg_passphrase_cb) != 0) { 186*9781SMoriah.Waterland@Sun.COM log_pkgerr(LOG_MSG_ERR, err); 187*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_ERR, MSG_NO_REMOVECERT, alias); 188*9781SMoriah.Waterland@Sun.COM goto cleanup; 189*9781SMoriah.Waterland@Sun.COM } 190*9781SMoriah.Waterland@Sun.COM 191*9781SMoriah.Waterland@Sun.COM log_msg(LOG_MSG_INFO, MSG_REMOVED, alias); 192*9781SMoriah.Waterland@Sun.COM 193*9781SMoriah.Waterland@Sun.COM ret = 0; 194*9781SMoriah.Waterland@Sun.COM /* fallthrough intentional */ 195*9781SMoriah.Waterland@Sun.COM cleanup: 196*9781SMoriah.Waterland@Sun.COM 197*9781SMoriah.Waterland@Sun.COM if (err != NULL) 198*9781SMoriah.Waterland@Sun.COM pkgerr_free(err); 199*9781SMoriah.Waterland@Sun.COM 200*9781SMoriah.Waterland@Sun.COM return (ret); 201*9781SMoriah.Waterland@Sun.COM } 202