mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
Initial checkin of the PSM server
This commit is contained in:
parent
227679761c
commit
77f8a8b6ac
101
security/psm/server/NSPRerrs.h
Normal file
101
security/psm/server/NSPRerrs.h
Normal file
@ -0,0 +1,101 @@
|
||||
/* General NSPR 2.0 errors */
|
||||
/* Caller must #include "prerror.h" */
|
||||
|
||||
ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
|
||||
ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
|
||||
ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
|
||||
ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
|
||||
ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
|
||||
ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
|
||||
ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
|
||||
ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
|
||||
ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
|
||||
ER2( PR_IO_ERROR, "I/O function error." )
|
||||
ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
|
||||
ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
|
||||
ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
|
||||
ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
|
||||
ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
|
||||
ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
|
||||
ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
|
||||
ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
|
||||
ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
|
||||
ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
|
||||
ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
|
||||
ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
|
||||
ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
|
||||
ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
|
||||
ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
|
||||
ER2( PR_FIND_SYMBOL_ERROR,
|
||||
"Symbol not found in any of the loaded dynamic libraries." )
|
||||
ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
|
||||
ER2( PR_DIRECTORY_LOOKUP_ERROR,
|
||||
"A directory lookup on a network address has failed." )
|
||||
ER2( PR_TPD_RANGE_ERROR,
|
||||
"Attempt to access a TPD key that is out of range." )
|
||||
ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
|
||||
ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
|
||||
ER2( PR_NOT_SOCKET_ERROR,
|
||||
"Network operation attempted on non-network file descriptor." )
|
||||
ER2( PR_NOT_TCP_SOCKET_ERROR,
|
||||
"TCP-specific function attempted on a non-TCP file descriptor." )
|
||||
ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
|
||||
ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
|
||||
ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
|
||||
"The requested operation is not supported by the platform." )
|
||||
ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
|
||||
"The host operating system does not support the protocol requested." )
|
||||
ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
|
||||
ER2( PR_BUFFER_OVERFLOW_ERROR,
|
||||
"The value requested is too large to be stored in the data buffer provided." )
|
||||
ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
|
||||
ER2( PR_RANGE_ERROR, "Unused." )
|
||||
ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
|
||||
ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
|
||||
ER2( PR_FILE_TOO_BIG_ERROR,
|
||||
"Write would result in file larger than the system allows." )
|
||||
ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
|
||||
ER2( PR_PIPE_ERROR, "Unused." )
|
||||
ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
|
||||
ER2( PR_IS_DIRECTORY_ERROR,
|
||||
"Cannot perform a normal file operation on a directory." )
|
||||
ER2( PR_LOOP_ERROR, "Symbolic link loop." )
|
||||
ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
|
||||
ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
|
||||
ER2( PR_NOT_DIRECTORY_ERROR,
|
||||
"Cannot perform directory operation on a normal file." )
|
||||
ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
|
||||
"Cannot write to a read-only file system." )
|
||||
ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
|
||||
"Cannot delete a directory that is not empty." )
|
||||
ER2( PR_FILESYSTEM_MOUNTED_ERROR,
|
||||
"Cannot delete or rename a file object while the file system is busy." )
|
||||
ER2( PR_NOT_SAME_DEVICE_ERROR,
|
||||
"Cannot rename a file to a file system on another device." )
|
||||
ER2( PR_DIRECTORY_CORRUPTED_ERROR,
|
||||
"The directory object in the file system is corrupted." )
|
||||
ER2( PR_FILE_EXISTS_ERROR,
|
||||
"Cannot create or rename a filename that already exists." )
|
||||
ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
|
||||
"Directory is full. No additional filenames may be added." )
|
||||
ER2( PR_INVALID_DEVICE_STATE_ERROR,
|
||||
"The required device was in an invalid state." )
|
||||
ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
|
||||
ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
|
||||
ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
|
||||
ER2( PR_FILE_SEEK_ERROR, "Seek error." )
|
||||
ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
|
||||
ER2( PR_IN_PROGRESS_ERROR,
|
||||
"Operation is still in progress (probably a non-blocking connect)." )
|
||||
ER2( PR_ALREADY_INITIATED_ERROR,
|
||||
"Operation has already been initiated (probably a non-blocking connect)." )
|
||||
|
||||
#ifdef PR_GROUP_EMPTY_ERROR
|
||||
ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
|
||||
#endif
|
||||
|
||||
#ifdef PR_INVALID_STATE_ERROR
|
||||
ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
|
||||
#endif
|
||||
|
||||
ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
|
385
security/psm/server/SECerrs.h
Normal file
385
security/psm/server/SECerrs.h
Normal file
@ -0,0 +1,385 @@
|
||||
/* General security error codes */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/* Caller must #include "secerr.h" */
|
||||
|
||||
|
||||
ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
|
||||
"An I/O error occurred during security authorization.")
|
||||
|
||||
ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
|
||||
"security library failure.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
|
||||
"security library: received bad data.")
|
||||
|
||||
ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
|
||||
"security library: output length error.")
|
||||
|
||||
ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
|
||||
"security library has experienced an input length error.")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
|
||||
"security library: invalid arguments.")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
|
||||
"security library: invalid algorithm.")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
|
||||
"security library: invalid AVA.")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
|
||||
"security library: invalid time.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
|
||||
"security library: improperly formatted DER-encoded message.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
|
||||
"Peer's certificate has an invalid signature.")
|
||||
|
||||
ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
|
||||
"Peer's Certificate has expired.")
|
||||
|
||||
ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
|
||||
"Peer's Certificate has been revoked.")
|
||||
|
||||
ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
|
||||
"Peer's Certificate issuer is not recognized.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
|
||||
"Peer's public key is invalid.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
|
||||
"The security password entered is incorrect.")
|
||||
|
||||
ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
|
||||
"New password entered incorrectly. Please try again.")
|
||||
|
||||
ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
|
||||
"security library: no nodelock.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
|
||||
"security library: bad database.")
|
||||
|
||||
ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
|
||||
"security library: memory allocation failure.")
|
||||
|
||||
ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
|
||||
"Peer's certificate issuer has been marked as not trusted by the user.")
|
||||
|
||||
ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
|
||||
"Peer's certificate has been marked as not trusted by the user.")
|
||||
|
||||
ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
|
||||
"Certificate already exists in your database.")
|
||||
|
||||
ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
|
||||
"Downloaded certificate's name duplicates one already in your database.")
|
||||
|
||||
ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
|
||||
"Error adding certificate to database.")
|
||||
|
||||
ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
|
||||
"Error refiling the key for this certificate.")
|
||||
|
||||
ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
|
||||
"The private key for this certificate cannot be found in key database")
|
||||
|
||||
ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
|
||||
"This certificate is valid.")
|
||||
|
||||
ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
|
||||
"This certificate is not valid.")
|
||||
|
||||
ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
|
||||
"Cert Library: No Response")
|
||||
|
||||
ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
|
||||
"The certificate issuer's certificate has expired. Check your system date and time.")
|
||||
|
||||
ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
|
||||
"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
|
||||
|
||||
ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
|
||||
"The CRL for the certificate's issuer has an invalid signature.")
|
||||
|
||||
ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
|
||||
"New CRL has an invalid format.")
|
||||
|
||||
ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
|
||||
"Certificate extension value is invalid.")
|
||||
|
||||
ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
|
||||
"Certificate extension not found.")
|
||||
|
||||
ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
|
||||
"Issuer certificate is invalid.")
|
||||
|
||||
ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
|
||||
"Certificate path length constraint is invalid.")
|
||||
|
||||
ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
|
||||
"Certificate usages field is invalid.")
|
||||
|
||||
ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
|
||||
"**Internal ONLY module**")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
|
||||
"The key does not support the requested operation.")
|
||||
|
||||
ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
|
||||
"Certificate contains unknown critical extension.")
|
||||
|
||||
ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
|
||||
"New CRL is not later than the current one.")
|
||||
|
||||
ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
|
||||
"Not encrypted or signed: you do not yet have an email certificate.")
|
||||
|
||||
ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
|
||||
"Not encrypted: you do not have certificates for each of the recipients.")
|
||||
|
||||
ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
|
||||
"Cannot decrypt: you are not a recipient, or matching certificate and \
|
||||
private key not found.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
|
||||
"Cannot decrypt: key encryption algorithm does not match your certificate.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
|
||||
"Signature verification failed: no signer found, too many signers found, \
|
||||
or improper or corrupted data.")
|
||||
|
||||
ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
|
||||
"Unsupported or unknown key algorithm.")
|
||||
|
||||
ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
|
||||
"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
|
||||
|
||||
|
||||
/* Fortezza Alerts */
|
||||
ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
|
||||
"Fortezza card has not been properly initialized. \
|
||||
Please remove it and return it to your issuer.")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
|
||||
"No Fortezza cards Found")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
|
||||
"No Fortezza card selected")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
|
||||
"Please select a personality to get more info on")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
|
||||
"Personality not found")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
|
||||
"No more information on that Personality")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
|
||||
"Invalid Pin")
|
||||
|
||||
ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
|
||||
"Couldn't initialize Fortezza personalities.")
|
||||
/* end fortezza alerts. */
|
||||
|
||||
ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
|
||||
"No KRL for this site's certificate has been found.")
|
||||
|
||||
ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
|
||||
"The KRL for this site's certificate has expired.")
|
||||
|
||||
ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
|
||||
"The KRL for this site's certificate has an invalid signature.")
|
||||
|
||||
ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
|
||||
"The key for this site's certificate has been revoked.")
|
||||
|
||||
ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
|
||||
"New KRL has an invalid format.")
|
||||
|
||||
ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
|
||||
"security library: need random data.")
|
||||
|
||||
ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
|
||||
"security library: no security module can perform the requested operation.")
|
||||
|
||||
ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
|
||||
"The security card or token does not exist, needs to be initialized, or has been removed.")
|
||||
|
||||
ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
|
||||
"security library: read-only database.")
|
||||
|
||||
ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
|
||||
"No slot or token was selected.")
|
||||
|
||||
ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
|
||||
"A certificate with the same nickname already exists.")
|
||||
|
||||
ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
|
||||
"A key with the same nickname already exists.")
|
||||
|
||||
ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
|
||||
"error while creating safe object")
|
||||
|
||||
ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
|
||||
"error while creating baggage object")
|
||||
|
||||
ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
|
||||
"Couldn't remove the principal")
|
||||
|
||||
ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
|
||||
"Couldn't delete the privilege")
|
||||
|
||||
ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
|
||||
"This principal doesn't have a certificate")
|
||||
|
||||
ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
|
||||
"Required algorithm is not allowed.")
|
||||
|
||||
ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
|
||||
"Error attempting to export certificates.")
|
||||
|
||||
ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
|
||||
"Error attempting to import certificates.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
|
||||
"Unable to import. Decoding error. File not valid.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
|
||||
"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
|
||||
"Unable to import. MAC algorithm not supported.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
|
||||
"Unable to import. Only password integrity and privacy modes supported.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
|
||||
"Unable to import. File structure is corrupt.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
|
||||
"Unable to import. Encryption algorithm not supported.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
|
||||
"Unable to import. File version not supported.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
|
||||
"Unable to import. Incorrect privacy password.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
|
||||
"Unable to import. Same nickname already exists in database.")
|
||||
|
||||
ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
|
||||
"The user pressed cancel.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
|
||||
"Not imported, already in database.")
|
||||
|
||||
ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
|
||||
"Message not sent.")
|
||||
|
||||
ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
|
||||
"Certificate key usage inadequate for attempted operation.")
|
||||
|
||||
ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
|
||||
"Certificate type not approved for application.")
|
||||
|
||||
ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
|
||||
"Address in signing certificate does not match address in message headers.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
|
||||
"Unable to import. Error attempting to import private key.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
|
||||
"Unable to import. Error attempting to import certificate chain.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
|
||||
"Unable to export. Unable to locate certificate or key by nickname.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
|
||||
"Unable to export. Private Key could not be located and exported.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
|
||||
"Unable to export. Unable to write the export file.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
|
||||
"Unable to import. Unable to read the import file.")
|
||||
|
||||
ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
|
||||
"Unable to export. Key database corrupt or deleted.")
|
||||
|
||||
ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
|
||||
"Unable to generate public/private key pair.")
|
||||
|
||||
ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
|
||||
"Password entered is invalid. Please pick a different one.")
|
||||
|
||||
ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
|
||||
"Old password entered incorrectly. Please try again.")
|
||||
|
||||
ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
|
||||
"Certificate nickname already in use.")
|
||||
|
||||
ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
|
||||
"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
|
||||
|
||||
/* ER3(SEC_ERROR_UNKNOWN, (SEC_ERROR_BASE + 105), */
|
||||
|
||||
ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
|
||||
"Invalid module name.")
|
||||
|
||||
ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
|
||||
"Invalid module path/filename")
|
||||
|
||||
ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
|
||||
"Unable to add module")
|
||||
|
||||
ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
|
||||
"Unable to delete module")
|
||||
|
||||
ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
|
||||
"New KRL is not later than the current one.")
|
||||
|
||||
ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
|
||||
"New CKL has different issuer than current CKL. Delete current CKL.")
|
||||
|
||||
#if 0 /* This was defined AFTER HCL 1.5 was released. */
|
||||
ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
|
||||
"The Certifying Authority for this certifcate is not permitted to issue a \
|
||||
certifcate with this name.")
|
||||
#endif
|
||||
|
||||
|
||||
|
323
security/psm/server/SSLerrs.h
Normal file
323
security/psm/server/SSLerrs.h
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/* SSL-specific security error codes */
|
||||
/* caller must include "sslerr.h" */
|
||||
|
||||
ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
|
||||
"Unable to communicate securely. Peer does not support high-grade encryption.")
|
||||
|
||||
ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
|
||||
"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
|
||||
|
||||
ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
|
||||
"Cannot communicate securely with peer: no common encryption algorithm(s).")
|
||||
|
||||
ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
|
||||
"Unable to find the certificate or key necessary for authentication.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
|
||||
"Unable to communicate securely with peer: peers's certificate was rejected.")
|
||||
|
||||
/* unused (SSL_ERROR_BASE + 5),*/
|
||||
|
||||
ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
|
||||
"The server has encountered bad data from the client.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
|
||||
"The client has encountered bad data from the server.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
|
||||
"Unsupported certificate type.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
|
||||
"Peer using unsupported version of security protocol.")
|
||||
|
||||
/* unused (SSL_ERROR_BASE + 10),*/
|
||||
|
||||
ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
|
||||
"Client authentication failed: private key in key database does not match public key in certificate database.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
|
||||
"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
|
||||
|
||||
/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
|
||||
defined in sslerr.h
|
||||
*/
|
||||
|
||||
ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
|
||||
"Peer only supports SSL version 2, which is locally disabled.")
|
||||
|
||||
|
||||
ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
|
||||
"SSL received a record with an incorrect Message Authentication Code.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
|
||||
"SSL peer reports incorrect Message Authentication Code.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
|
||||
"SSL peer cannot verify your certificate.")
|
||||
|
||||
ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
|
||||
"SSL peer rejected your certificate as revoked.")
|
||||
|
||||
ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
|
||||
"SSL peer rejected your certificate as expired.")
|
||||
|
||||
ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
|
||||
"Cannot connect: SSL is disabled.")
|
||||
|
||||
ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
|
||||
"Cannot connect: SSL peer is in another FORTEZZA domain.")
|
||||
|
||||
|
||||
ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
|
||||
"An unknown SSL cipher suite has been requested.")
|
||||
|
||||
ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
|
||||
"No cipher suites are present and enabled in this program.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
|
||||
"SSL received a record with bad block padding.")
|
||||
|
||||
ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
|
||||
"SSL received a record that exceeded the maximum permissible length.")
|
||||
|
||||
ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
|
||||
"SSL attempted to send a record that exceeded the maximum permissible length.")
|
||||
|
||||
/*
|
||||
* Received a malformed (too long or short or invalid content) SSL handshake.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
|
||||
"SSL received a malformed Hello Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
|
||||
"SSL received a malformed Client Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
|
||||
"SSL received a malformed Server Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
|
||||
"SSL received a malformed Certificate handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
|
||||
"SSL received a malformed Server Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
|
||||
"SSL received a malformed Certificate Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
|
||||
"SSL received a malformed Server Hello Done handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
|
||||
"SSL received a malformed Certificate Verify handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
|
||||
"SSL received a malformed Client Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
|
||||
"SSL received a malformed Finished handshake message.")
|
||||
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL record.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
|
||||
"SSL received a malformed Change Cipher Spec record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
|
||||
"SSL received a malformed Alert record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
|
||||
"SSL received a malformed Handshake record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
|
||||
"SSL received a malformed Application Data record.")
|
||||
|
||||
/*
|
||||
* Received an SSL handshake that was inappropriate for the state we're in.
|
||||
* E.g. Server received message from server, or wrong state in state machine.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
|
||||
"SSL received an unexpected Hello Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
|
||||
"SSL received an unexpected Client Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
|
||||
"SSL received an unexpected Server Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
|
||||
"SSL received an unexpected Certificate handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
|
||||
"SSL received an unexpected Server Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
|
||||
"SSL received an unexpected Certificate Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
|
||||
"SSL received an unexpected Server Hello Done handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
|
||||
"SSL received an unexpected Certificate Verify handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
|
||||
"SSL received an unexpected Cllient Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
|
||||
"SSL received an unexpected Finished handshake message.")
|
||||
|
||||
/*
|
||||
* Received an SSL record that was inappropriate for the state we're in.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
|
||||
"SSL received an unexpected Change Cipher Spec record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
|
||||
"SSL received an unexpected Alert record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
|
||||
"SSL received an unexpected Handshake record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
|
||||
"SSL received an unexpected Application Data record.")
|
||||
|
||||
/*
|
||||
* Received record/message with unknown discriminant.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
|
||||
"SSL received a record with an unknown content type.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
|
||||
"SSL received a handshake message with an unknown message type.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
|
||||
"SSL received an alert record with an unknown alert description.")
|
||||
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts above)
|
||||
*/
|
||||
ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
|
||||
"SSL peer has closed this connection.")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
|
||||
"SSL peer was not expecting a handshake message it received.")
|
||||
|
||||
ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
|
||||
"SSL peer was unable to succesfully decompress an SSL record it received.")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
|
||||
"SSL peer was unable to negotiate an acceptable set of security parameters.")
|
||||
|
||||
ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
|
||||
"SSL peer rejected a handshake message for unacceptable content.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
|
||||
"SSL peer does not support certificates of the type it received.")
|
||||
|
||||
ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
|
||||
"SSL peer had some unspecified issue with the certificate it received.")
|
||||
|
||||
|
||||
ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
|
||||
"SSL experienced a failure of its random number generator.")
|
||||
|
||||
ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
|
||||
"Unable to digitally sign data required to verify your certificate.")
|
||||
|
||||
ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
|
||||
"SSL was unable to extract the public key from the peer's certificate.")
|
||||
|
||||
ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
|
||||
"Unspecified failure while processing SSL Server Key Exchange handshake.")
|
||||
|
||||
ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
|
||||
"Unspecified failure while processing SSL Client Key Exchange handshake.")
|
||||
|
||||
ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
|
||||
"Bulk data encryption algorithm failed in selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
|
||||
"Bulk data decryption algorithm failed in selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
|
||||
"Attempt to write encrypted data to underlying socket failed.")
|
||||
|
||||
ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
|
||||
"MD5 digest function failed.")
|
||||
|
||||
ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
|
||||
"SHA-1 digest function failed.")
|
||||
|
||||
ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
|
||||
"MAC computation failed.")
|
||||
|
||||
ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
|
||||
"Failure to create Symmetric Key context.")
|
||||
|
||||
ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
|
||||
"Failure to unwrap the Symmetric key in Client Key Exchange message.")
|
||||
|
||||
ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
|
||||
"SSL Server attempted to use domestic-grade public key with export cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
|
||||
"PKCS11 code failed to translate an IV into a param.")
|
||||
|
||||
ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
|
||||
"Failed to initialize the selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
|
||||
"Client failed to generate session keys for SSL session.")
|
||||
|
||||
ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
|
||||
"Server has no key for the attempted key exchange algorithm.")
|
||||
|
||||
ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
|
||||
"PKCS#11 token was inserted or removed while operation was in progress.")
|
||||
|
||||
ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
|
||||
"No PKCS#11 token could be found to do a required operation.")
|
||||
|
||||
ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
|
||||
"Cannot communicate securely with peer: no common compression algorithm(s).")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
|
||||
"Cannot initiate another SSL handshake until current handshake is complete.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
|
||||
"Received incorrect handshakes hash values from peer.")
|
||||
|
||||
ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
|
||||
"The certificate provided cannot be used with the selected key exchange algorithm.")
|
||||
|
3038
security/psm/server/advisor.c
Normal file
3038
security/psm/server/advisor.c
Normal file
File diff suppressed because it is too large
Load Diff
165
security/psm/server/advisor.h
Normal file
165
security/psm/server/advisor.h
Normal file
@ -0,0 +1,165 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __ADVISOR_H__
|
||||
#define __ADVISOR_H__
|
||||
/*
|
||||
Security advisor object. We create this in order to determine what to show
|
||||
in the generic "Security Info" pane, and to convey the right URL back to
|
||||
the client for loading.
|
||||
|
||||
Created by mwelch 1999 February
|
||||
*/
|
||||
#include "resource.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "certres.h"
|
||||
#include "p7cinfo.h"
|
||||
#include "slist.h"
|
||||
#include "sslskst.h"
|
||||
|
||||
typedef struct InfoSecAdvisor
|
||||
{
|
||||
PRInt32 infoContext;
|
||||
PRInt32 resID;
|
||||
char *hostname;
|
||||
char *senderAddr;
|
||||
PRUint32 encryptedP7CInfo;
|
||||
PRUint32 signedP7CInfo;
|
||||
PRInt32 decodeError;
|
||||
PRInt32 verifyError;
|
||||
PRInt32 encryptthis;
|
||||
PRInt32 signthis;
|
||||
PRInt32 numRecipients;
|
||||
char **recipients;
|
||||
} InfoSecAdvisor;
|
||||
|
||||
typedef struct SSMSecurityAdvisorContext
|
||||
{
|
||||
SSMResource super;
|
||||
|
||||
/* Reference to Cartman object which we use to display
|
||||
"Security Info" pane */
|
||||
SSMResource *m_infoSource;
|
||||
|
||||
/* Width and height of the security advisor window,
|
||||
loaded from resource file */
|
||||
PRUint32 m_width, m_height;
|
||||
|
||||
/* Cached URL which we send back to client upon request */
|
||||
char *m_url;
|
||||
|
||||
SSMSortedList *m_certhash;
|
||||
PRIntn m_certsIncluded;
|
||||
|
||||
char *m_nickname;
|
||||
PRInt32 infoContext;
|
||||
PRInt32 resID;
|
||||
char *hostname;
|
||||
char *senderAddr;
|
||||
PRUint32 encryptedP7CInfo;
|
||||
PRUint32 signedP7CInfo;
|
||||
PRInt32 decodeError;
|
||||
PRInt32 verifyError;
|
||||
PRInt32 encryptthis;
|
||||
PRInt32 signthis;
|
||||
PRInt32 numRecipients;
|
||||
char **recipients;
|
||||
char *selectedItemPage;
|
||||
PRInt32 encrypted_b;
|
||||
PRInt32 signed_b;
|
||||
SSMP7ContentInfo * encryptedP7CInfoRes;
|
||||
SSMP7ContentInfo * signedP7CInfoRes;
|
||||
SSMSSLSocketStatus * socketStatus;
|
||||
#if 0
|
||||
/* data for Java principals */
|
||||
char* m_principalsData;
|
||||
#endif
|
||||
} SSMSecurityAdvisorContext;
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_Create(SSMControlConnection *ctrl,
|
||||
InfoSecAdvisor *info,
|
||||
SSMResource **res);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_Destroy(SSMResource *res, PRBool doFree);
|
||||
|
||||
void SSMSecurityAdvisorContext_Invariant(SSMSecurityAdvisorContext *ct);
|
||||
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_FormSubmitHandler(SSMResource *res,
|
||||
HTTPRequest *req);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_Print(SSMResource *res,
|
||||
char *fmt, PRIntn numParam,
|
||||
char **value, char **resultStr);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_DoPKCS12Response(HTTPRequest *req,
|
||||
const char *responseKey);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_DoPKCS12Restore(SSMSecurityAdvisorContext *res,
|
||||
HTTPRequest *req);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_DoPKCS12Backup(SSMSecurityAdvisorContext *cx,
|
||||
HTTPRequest *req);
|
||||
|
||||
SSMStatus SSMSecurityAdvisorContext_Process_cert_mine_form(SSMSecurityAdvisorContext *res,
|
||||
HTTPRequest *req);
|
||||
SSMStatus SSMSecurityAdvisorContext_sa_selected_item(SSMTextGenContext* cx);
|
||||
|
||||
SSMStatus SSM_FreeTarget(SSMTextGenContext *cx);
|
||||
|
||||
SSMStatus
|
||||
SSMSecurityAdvisorContext_GetPrefListKeywordHandler(SSMTextGenContext* cx);
|
||||
SSMStatus SSM_SetDBPasswordHandler(HTTPRequest * req);
|
||||
#if 0
|
||||
SSMStatus SSM_JavaPrincipalsKeywordHandler(SSMTextGenContext* cx);
|
||||
void SSM_HandleGetJavaPrincipalsReply(SSMControlConnection* ctrl,
|
||||
SECItem* message);
|
||||
#endif
|
||||
SSMStatus SSM_RemovePrivilegesHandler(HTTPRequest* req);
|
||||
SSMStatus SSM_OCSPResponderList(SSMTextGenContext* cx);
|
||||
char* SSM_GetOCSPURL(CERTCertificate *cert, PrefSet *prefs);
|
||||
PRBool SSM_IsOCSPEnabled(SSMControlConnection *connection);
|
||||
#endif
|
548
security/psm/server/autorenewal.c
Normal file
548
security/psm/server/autorenewal.c
Normal file
@ -0,0 +1,548 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "ctrlconn.h"
|
||||
#include "cert.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include "xconst.h"
|
||||
#include "secerr.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "certres.h"
|
||||
#include "pk11func.h"
|
||||
#include "secoid.h"
|
||||
|
||||
typedef struct CERTRenewalWindow {
|
||||
SECItem begin;
|
||||
SECItem end;
|
||||
} CERTRenewalWindow;
|
||||
|
||||
const static SEC_ASN1Template CERT_RenewalWindowTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTRenewalWindow) },
|
||||
{ SEC_ASN1_GENERALIZED_TIME,
|
||||
offsetof(CERTRenewalWindow,begin) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_GENERALIZED_TIME,
|
||||
offsetof(CERTRenewalWindow,end) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
PRBool CERT_HasRenewalExtension(CERTCertificate *cert)
|
||||
{
|
||||
int rv;
|
||||
SECItem *derWindow = NULL;
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
/* Allocate from the heap, so that we can free eveything later */
|
||||
derWindow = SECITEM_AllocItem(NULL, NULL, 0);
|
||||
if (derWindow == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the renewal window extension */
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME,
|
||||
derWindow);
|
||||
if (rv == SECSuccess) {
|
||||
ret = PR_TRUE;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (derWindow) {
|
||||
SECITEM_FreeItem(derWindow, PR_TRUE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRBool CERT_InRenewalWindow(CERTCertificate *cert, int64 t)
|
||||
{
|
||||
int rv;
|
||||
int64 begin, end;
|
||||
CERTRenewalWindow *window = NULL;
|
||||
SECItem *derWindow = NULL;
|
||||
PRArenaPool *arena = NULL;
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
/* Allocate from the heap, so that we can free eveything later */
|
||||
derWindow = SECITEM_AllocItem(NULL, NULL, 0);
|
||||
if (derWindow == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the renewal window extension */
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME,
|
||||
derWindow);
|
||||
if (rv == SECFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
goto loser;
|
||||
|
||||
window = (CERTRenewalWindow*)PORT_ArenaZAlloc(arena,
|
||||
sizeof(CERTRenewalWindow));
|
||||
if (window == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the extension */
|
||||
rv = SEC_ASN1DecodeItem(arena, window, CERT_RenewalWindowTemplate, derWindow);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the times */
|
||||
rv = DER_GeneralizedTimeToTime(&begin, &window->begin);
|
||||
if (window->end.data) {
|
||||
rv = DER_GeneralizedTimeToTime(&end, &window->end);
|
||||
} else {
|
||||
rv = DER_UTCTimeToTime(&end, &cert->validity.notAfter);
|
||||
}
|
||||
|
||||
/* Is this cert in the renewal window */
|
||||
if (LL_CMP(t,>,begin) && LL_CMP(t,<,end)) {
|
||||
ret = PR_TRUE;
|
||||
} else {
|
||||
ret = PR_FALSE;
|
||||
}
|
||||
loser:
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
if (derWindow) {
|
||||
SECITEM_FreeItem(derWindow, PR_TRUE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRBool CERT_RenewalWindowExpired(CERTCertificate *cert, int64 t)
|
||||
{
|
||||
int rv;
|
||||
int64 begin, end;
|
||||
CERTRenewalWindow *window = NULL;
|
||||
SECItem *derWindow = NULL;
|
||||
PRArenaPool *arena = NULL;
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
/* Allocate from the heap, so that we can free eveything later */
|
||||
derWindow = SECITEM_AllocItem(NULL, NULL, 0);
|
||||
if (derWindow == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the renewal window extension */
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME,
|
||||
derWindow);
|
||||
if (rv == SECFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
goto loser;
|
||||
|
||||
window = (CERTRenewalWindow*)PORT_ArenaZAlloc(arena,
|
||||
sizeof(CERTRenewalWindow));
|
||||
if (window == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the extension */
|
||||
rv = SEC_ASN1DecodeItem(arena, window, CERT_RenewalWindowTemplate, derWindow);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the times */
|
||||
rv = DER_GeneralizedTimeToTime(&begin, &window->begin);
|
||||
if (window->end.data) {
|
||||
rv = DER_GeneralizedTimeToTime(&end, &window->end);
|
||||
} else {
|
||||
rv = DER_UTCTimeToTime(&end, &cert->validity.notAfter);
|
||||
}
|
||||
|
||||
/* Has the renewal window expired */
|
||||
if (LL_CMP(t,>,end)) {
|
||||
ret = PR_TRUE;
|
||||
} else {
|
||||
ret = PR_FALSE;
|
||||
}
|
||||
loser:
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
if (derWindow) {
|
||||
SECITEM_FreeItem(derWindow, PR_TRUE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char * CERT_GetAuthorityInfoAccessLocation(CERTCertificate *cert, int method)
|
||||
{
|
||||
CERTGeneralName *locname = NULL;
|
||||
SECItem *location = NULL;
|
||||
SECItem *encodedAuthInfoAccess = NULL;
|
||||
CERTAuthInfoAccess **authInfoAccess = NULL;
|
||||
char *locURI = NULL;
|
||||
PRArenaPool *arena = NULL;
|
||||
SECStatus rv;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Allocate this one from the heap because it will get filled in
|
||||
* by CERT_FindCertExtension which will also allocate from the heap,
|
||||
* and we can free the entire thing on our way out.
|
||||
*/
|
||||
encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
|
||||
if (encodedAuthInfoAccess == NULL)
|
||||
goto loser;
|
||||
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
|
||||
encodedAuthInfoAccess);
|
||||
if (rv == SECFailure)
|
||||
goto loser;
|
||||
|
||||
/*
|
||||
* The rest of the things allocated in the routine will come out of
|
||||
* this arena, which is temporary just for us to decode and get at the
|
||||
* AIA extension. The whole thing will be destroyed on our way out,
|
||||
* after we have copied the location string (url) itself (if found).
|
||||
*/
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
goto loser;
|
||||
|
||||
authInfoAccess = cert_DecodeAuthInfoAccessExtension(arena,
|
||||
encodedAuthInfoAccess);
|
||||
if (authInfoAccess == NULL)
|
||||
goto loser;
|
||||
|
||||
for (i = 0; authInfoAccess[i] != NULL; i++) {
|
||||
if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == method)
|
||||
locname = authInfoAccess[i]->location;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found an AIA extension, but it did not include an OCSP method,
|
||||
* that should look to our caller as if we did not find the extension
|
||||
* at all, because it is only an OCSP method that we care about.
|
||||
* So set the same error that would be set if the AIA extension was
|
||||
* not there at all.
|
||||
*/
|
||||
if (locname == NULL) {
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is just a pointer back into locname (i.e. not a copy);
|
||||
* thus it should not be freed.
|
||||
*/
|
||||
location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE);
|
||||
if (location == NULL) {
|
||||
/*
|
||||
* XXX Appears that CERT_GetGeneralNameByType does not set an
|
||||
* error if there is no name by that type. For lack of anything
|
||||
* better, act as if the extension was not found. In the future
|
||||
* this should probably be something more like the extension was
|
||||
* badly formed.
|
||||
*/
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* That location is really a string, but it has a specified length
|
||||
* without a null-terminator. We need a real string that does have
|
||||
* a null-terminator, and we need a copy of it anyway to return to
|
||||
* our caller -- so allocate and copy.
|
||||
*/
|
||||
locURI = PORT_Alloc(location->len + 1);
|
||||
if (locURI == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(locURI, location->data, location->len);
|
||||
locURI[location->len] = '\0';
|
||||
|
||||
loser:
|
||||
if (arena != NULL)
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
|
||||
if (encodedAuthInfoAccess != NULL)
|
||||
SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE);
|
||||
|
||||
return locURI;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SendRenewalUIEvent(SSMControlConnection *conn,
|
||||
char *url)
|
||||
{
|
||||
SECItem event;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMResourceID rid = 0;
|
||||
UIEvent reply;
|
||||
|
||||
if (!conn->m_doesUI) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
||||
/* Generate the actual message to send to the client. */
|
||||
reply.resourceID = rid;
|
||||
reply.width = 715;
|
||||
reply.height = 545;
|
||||
reply.isModal = CM_FALSE;
|
||||
reply.url = url;
|
||||
reply.clientContext.len = 0;
|
||||
reply.clientContext.data = NULL;
|
||||
|
||||
if (CMT_EncodeMessage(UIEventTemplate, (CMTItem*)&event, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Post the message on the outgoing control channel. */
|
||||
rv = SSM_SendQMessage(conn->m_controlOutQ, SSM_PRIORITY_NORMAL,
|
||||
SSM_EVENT_MESSAGE | SSM_UI_EVENT,
|
||||
(int) event.len, (char *) event.data, PR_FALSE);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
PR_FREEIF(event.data);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus CheckCertificate(CERTCertificate * cert, void * arg)
|
||||
{
|
||||
char *url = NULL;
|
||||
SSMControlConnection *ctrl = (SSMControlConnection *)arg;
|
||||
SSMStatus rv;
|
||||
SSMResourceID certID;
|
||||
SSMResourceCert * certRes = NULL;
|
||||
CERTCertificate *otherCert = NULL;
|
||||
CERTCertList *certs = NULL;
|
||||
CERTCertListNode *node;
|
||||
|
||||
/* Is this cert in the renewal window */
|
||||
if (CERT_InRenewalWindow(cert, PR_Now()) == PR_FALSE) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get the AIA */
|
||||
url = CERT_GetAuthorityInfoAccessLocation(cert, SEC_OID_CERT_RENEWAL_LOCATOR);
|
||||
if (!url) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Should we renew this cert? Check the case where it has already been renewed */
|
||||
/* but the old cert is still there waith a valid renewal window */
|
||||
certs = PK11_FindCertsFromNickname(cert->nickname, ctrl);
|
||||
if (!cert) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Interate through the certs */
|
||||
node = CERT_LIST_HEAD(certs);
|
||||
|
||||
while (!CERT_LIST_END(node, certs)) {
|
||||
otherCert = node->cert;
|
||||
|
||||
/* This is the cert we are renewing */
|
||||
if (otherCert == cert) {
|
||||
goto endloop;
|
||||
}
|
||||
|
||||
/* This cert has expired */
|
||||
if (CERT_CheckCertValidTimes(otherCert, PR_Now(), PR_FALSE) != secCertTimeValid) {
|
||||
goto endloop;
|
||||
}
|
||||
|
||||
/* This cert has different key usage */
|
||||
if (cert->keyUsage != otherCert->keyUsage) {
|
||||
goto endloop;
|
||||
}
|
||||
|
||||
/* This cert renewal window has not expired - don't renew our cert */
|
||||
if (CERT_HasRenewalExtension(otherCert) && !CERT_RenewalWindowExpired(otherCert, PR_Now())) {
|
||||
goto done;
|
||||
}
|
||||
endloop:
|
||||
node = CERT_LIST_NEXT(node);
|
||||
}
|
||||
|
||||
/* Create a resource for this cert and get an id */
|
||||
rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
|
||||
cert,
|
||||
ctrl,
|
||||
&certID,
|
||||
(SSMResource**)&certRes);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
SSM_LockUIEvent((SSMResource*)certRes);
|
||||
|
||||
/* Send a UI event to client */
|
||||
rv = SSMControlConnection_SendUIEvent(ctrl, "get",
|
||||
"cert_renewal",
|
||||
&(certRes->super), NULL, &(&(ctrl->super.super))->m_clientContext);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSM_WaitUIEvent((SSMResource*)certRes, PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
if ((certRes->super.m_buttonType == SSM_BUTTON_OK) && (certRes->m_renewCert == PR_TRUE)) {
|
||||
/* Send a UI event asking about renewal */
|
||||
/* Send UI prompting the user */
|
||||
SendRenewalUIEvent(ctrl, url);
|
||||
}
|
||||
loser:
|
||||
done:
|
||||
if (certs) {
|
||||
CERT_DestroyCertList(certs);
|
||||
}
|
||||
if (certRes) {
|
||||
SSM_FreeResource(certRes);
|
||||
}
|
||||
PR_FREEIF(url);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void SSM_CertificateRenewalThread(void * arg)
|
||||
{
|
||||
int series, slotSeries[255], i = 0;
|
||||
PK11SlotList * slots = NULL;
|
||||
PK11SlotListElement * le = NULL;
|
||||
SSMControlConnection *ctrl = (SSMControlConnection *)arg;
|
||||
|
||||
/* Initialize slot series array to zero */
|
||||
memset(slotSeries, 0, sizeof(slotSeries));
|
||||
|
||||
/* Get a list of tokens installed */
|
||||
slots = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, ctrl);
|
||||
if (!slots) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* Interate over the list of slots */
|
||||
for (le = slots->head, i= 0; le; le = le->next, i++) {
|
||||
|
||||
/* If there is no token present then we are no interested */
|
||||
if (!PK11_IsPresent(le->slot)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If token not logged in, then we are not interested */
|
||||
if (!PK11_IsLoggedIn(le->slot, ctrl)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If token is read-only, then we are not interested */
|
||||
if (PK11_IsReadOnly(le->slot)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the series and mark as checked */
|
||||
series = PK11_GetSlotSeries(le->slot);
|
||||
if (slotSeries[i] == series) {
|
||||
continue;
|
||||
}
|
||||
slotSeries[i] = series;
|
||||
|
||||
/* Interate all the certs on the token */
|
||||
PK11_TraverseCertsInSlot(le->slot, CheckCertificate, ctrl);
|
||||
}
|
||||
|
||||
/* Sleep for one minute */
|
||||
PR_Sleep(PR_TicksPerSecond()*60);
|
||||
}
|
||||
|
||||
if (slots) {
|
||||
PK11_FreeSlotList(slots);
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus SSM_RenewalCertInfoHandler(SSMTextGenContext* cx)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSMResource* target = NULL;
|
||||
SSMResourceCert* renewalCertRes = NULL;
|
||||
CERTCertificate* renewalCert = NULL;
|
||||
char *fmt = NULL, *issuerCN = NULL;
|
||||
char *validNotBefore = NULL, *validNotAfter = NULL;
|
||||
|
||||
PR_ASSERT(cx != NULL);
|
||||
PR_ASSERT(cx->m_request != NULL);
|
||||
PR_ASSERT(cx->m_params != NULL);
|
||||
PR_ASSERT(cx->m_result != NULL);
|
||||
|
||||
/* retrieve the renewal cert */
|
||||
target = SSMTextGen_GetTargetObject(cx);
|
||||
renewalCertRes = (SSMResourceCert*)target;
|
||||
|
||||
renewalCert = renewalCertRes->cert;
|
||||
if (renewalCert == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the info */
|
||||
/* This is: Name, issuer, valid from and valid to */
|
||||
issuerCN = CERT_GetCommonName(&renewalCert->issuer),
|
||||
validNotBefore = DER_UTCDayToAscii(&renewalCert->validity.notBefore);
|
||||
validNotAfter = DER_UTCDayToAscii(&renewalCert->validity.notAfter);
|
||||
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "cert_renewal_cert_info", &fmt);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
cx->m_result = PR_smprintf(fmt, renewalCert->nickname, validNotBefore, validNotAfter, issuerCN);
|
||||
|
||||
PR_FREEIF(fmt);
|
||||
PR_FREEIF(issuerCN);
|
||||
PR_FREEIF(validNotBefore);
|
||||
PR_FREEIF(validNotAfter);
|
||||
return SSM_SUCCESS;
|
||||
|
||||
loser:
|
||||
PR_FREEIF(fmt);
|
||||
PR_FREEIF(issuerCN);
|
||||
PR_FREEIF(validNotBefore);
|
||||
PR_FREEIF(validNotAfter);
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
1088
security/psm/server/certlist.c
Normal file
1088
security/psm/server/certlist.c
Normal file
File diff suppressed because it is too large
Load Diff
71
security/psm/server/certlist.h
Normal file
71
security/psm/server/certlist.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "textgen.h"
|
||||
#include "minihttp.h"
|
||||
#include "certres.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
certHashRemove = (int) -1,
|
||||
certHashAdd = 1
|
||||
} ssmCertHashAction;
|
||||
|
||||
/* Since there isn't a strict 1-1 match between SSLCA and SECCertUsage
|
||||
(we lump SSL and SSL-with-step-up certs together at the moment, for eg),
|
||||
we have an enum of our own to indicate what to get from the cert db. */
|
||||
typedef enum
|
||||
{
|
||||
clNoUsage = -1,
|
||||
clAllMine = 0,
|
||||
clSSLClient,
|
||||
clEmailSigner,
|
||||
clMyObjSigning,
|
||||
clSSLServer,
|
||||
clEmailRecipient,
|
||||
clAllCA
|
||||
} ssmCLCertUsage;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char * certEntry;
|
||||
ssmCLCertUsage usage;
|
||||
PRBool isEmailSigner;
|
||||
} ssmCertData;
|
||||
|
||||
SSMStatus SSM_CertListKeywordHandler(SSMTextGenContext *cx);
|
||||
SSMStatus SSM_SetLocaleCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_ReloadTextCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_ChangeCertSecAdvisorList(HTTPRequest * req, char * nickname,
|
||||
ssmCertHashAction action);
|
||||
|
||||
PRIntn certlist_compare_strings(const void * v1, const void *v2);
|
2496
security/psm/server/certres.c
Normal file
2496
security/psm/server/certres.c
Normal file
File diff suppressed because it is too large
Load Diff
134
security/psm/server/certres.h
Normal file
134
security/psm/server/certres.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __NSM_CERTRES_H__
|
||||
#define __NSM_CERTRES_H__
|
||||
|
||||
#include "servimpl.h"
|
||||
#include "resource.h"
|
||||
#include "cert.h"
|
||||
#include "certdb.h"
|
||||
#include "secder.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "minihttp.h"
|
||||
#include "textgen.h"
|
||||
|
||||
struct _ssm_resource_cert;
|
||||
|
||||
typedef SSMStatus (*SSMCertResourceVerifyFunc)
|
||||
(struct _ssm_resource_cert * resource,
|
||||
SECCertUsage certUsage);
|
||||
typedef SSMStatus (*SSMCertResourceDeleteCertFunc)
|
||||
(struct _ssm_resource_cert * resource);
|
||||
|
||||
|
||||
typedef struct _ssm_resource_cert
|
||||
{
|
||||
SSMResource super;
|
||||
CERTCertificate * cert;
|
||||
SSMCertResourceVerifyFunc m_verify_func;
|
||||
SSMCertResourceDeleteCertFunc m_deletecert_func;
|
||||
PRBool m_markedForDeletion;
|
||||
PRBool m_renewCert;
|
||||
} SSMResourceCert;
|
||||
|
||||
/*
|
||||
* Cert resource can be created from a CERTCertificate or when unpickling.
|
||||
*/
|
||||
typedef enum {
|
||||
SSM_RESOURCE_CERT_CREATE_NEW = 0L,
|
||||
SSM_RESOURCE_CERT_CREATE_UNPICKLE
|
||||
} SSMResourceCertCreate;
|
||||
|
||||
/* Functions of the certResource class */
|
||||
SSMStatus SSMResourceCert_Create(void * arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMResourceCert_Init(SSMResourceCert * certResource,
|
||||
SSMControlConnection * conn,
|
||||
void * arg);
|
||||
|
||||
SSMStatus SSMResourceCert_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMResourceCert_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
SSMStatus SSMResourceCert_Destroy(SSMResource *res, PRBool doFree);
|
||||
SSMStatus SSMResourceCert_Pickle(SSMResource *res, PRIntn *len, void ** rdata);
|
||||
SSMStatus SSMResourceCert_Verify(SSMResourceCert * resource,
|
||||
SECCertUsage certUsage);
|
||||
SSMStatus SSMResourceCert_DeleteCert(SSMResourceCert * resource);
|
||||
|
||||
SSMStatus SSMResourceCert_Unpickle(SSMResource ** resource,
|
||||
SSMControlConnection * conn, PRInt32 len,
|
||||
void * value);
|
||||
SSMStatus SSMResourceCert_HTML(SSMResource *res, PRIntn * len, void ** value);
|
||||
|
||||
SSMStatus SSMResourceCert_FormSubmitHandler(SSMResource *res, HTTPRequest *req);
|
||||
|
||||
|
||||
/* Other cert resource functions */
|
||||
SSMStatus SSM_VerifyCert(SSMResourceCert * resource,
|
||||
SECCertUsage certUsage);
|
||||
SSMStatus SSM_DeleteCert(SSMResourceCert * resource);
|
||||
SSMStatus SSM_DeleteCertHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_HTTPCertListHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_ViewCertInfoKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_VerifyCertKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_SelectCertKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_ChooseCertUsageHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_EditCertKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_EditCertificateTrustHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_DeleteCertHelpKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_DeleteCertWarnKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_ObtainNewCertSite(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_ProcessLDAPRequestHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_LDAPServerListKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_ProcessLDAPWindow(HTTPRequest * req);
|
||||
|
||||
SSMStatus
|
||||
SSM_ProcessCertUIAction(HTTPRequest * req, CERTCertificate * cert);
|
||||
SSMStatus SSM_ProcessCertDeleteButton(HTTPRequest * req);
|
||||
|
||||
int SSM_CertListCount(CERTCertList *certList);
|
||||
|
||||
SSMStatus SSM_OCSPOptionsKeywordHandler(SSMTextGenContext *cx);
|
||||
SSMStatus SSM_OCSPDefaultResponderKeywordHandler(SSMTextGenContext *cx);
|
||||
|
||||
SSMStatus
|
||||
SSM_CompleteLDAPLookup(SSMControlConnection *ctrl, char * ldapserver,
|
||||
char * emailaddr);
|
||||
char * SSM_GetCAPolicyString(char * org, unsigned long noticeNum, void * arg);
|
||||
|
||||
#endif
|
251
security/psm/server/certsearch.c
Normal file
251
security/psm/server/certsearch.c
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/* LDAP Cert Search */
|
||||
#include <ldap.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "certsearch.h"
|
||||
|
||||
/* XXX TRUE & FALSE is not defined (on Unix): get by for now by using this
|
||||
* macro */
|
||||
#define SSM_LDAP_TRUE 1
|
||||
#define SSM_LDAP_FALSE 0
|
||||
|
||||
|
||||
int LDAPCertSearch (const char * rcpt_address, const char * server_name,
|
||||
const char * baseDN, int port, int connect_type,
|
||||
const char * certdb_path, const char * auth_dn,
|
||||
const char * auth_password, const char * mail_attribs,
|
||||
const char * cert_attribs, cert_struct * certs[])
|
||||
{
|
||||
int rtnval;
|
||||
LDAP * ld;
|
||||
|
||||
char *filter, *tstr, *tmpstr, *tmpstr1;
|
||||
int addr_len, attr_count = 0, filter_length = 0;
|
||||
char mail_array[3][80];
|
||||
|
||||
char **cert_attrib_array, **tmp_cert_array;
|
||||
|
||||
LDAPMessage *reslt, *entry;
|
||||
int attrib_name_count, entry_count;
|
||||
void * cert;
|
||||
|
||||
/* First some simple param checking */
|
||||
if (!server_name || !*server_name)
|
||||
return 1;
|
||||
if (!rcpt_address || !*rcpt_address)
|
||||
return 2;
|
||||
if (connect_type < CLEAR_ANON || connect_type > SSL_CERTAUTH)
|
||||
return 3;
|
||||
|
||||
if (!cert_attribs || !*cert_attribs)
|
||||
return 2;
|
||||
|
||||
/* Okay, try to init connection to LDAP Server */
|
||||
if (connect_type == CLEAR_ANON || connect_type == CLEAR_AUTH)
|
||||
ld = ldap_init(server_name, 389);
|
||||
#if 0
|
||||
/* don't bother with SSL yet */
|
||||
else { /* SSL Connection */
|
||||
/* First init Client connection to db files needed */
|
||||
if (connect_type == SSL_CERTAUTH) {
|
||||
/* don't bother yet. keydbpath is full path of key3.db file (e.g. ...users/bruces)
|
||||
if (ldapssl_clientauth_init(certdb_path, NULL, needkeydb, keydbpath,
|
||||
NULL) < 0)
|
||||
return 4; */
|
||||
} else {
|
||||
if (ldapssl_client_init(certdb_path, NULL) < 0)
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* Now attempt SSL connection to LDAP Server */
|
||||
ld = ldapssl_init(server_name, port, 1);
|
||||
}
|
||||
#endif
|
||||
if (!ld) /* failed to init connection to LDAP server */
|
||||
return 4;
|
||||
|
||||
/* Now bind to server (NULL/Anon bind if not AUTH type connection) */
|
||||
if (connect_type == CLEAR_ANON || connect_type == SSL_ANON)
|
||||
rtnval = ldap_simple_bind_s(ld, NULL, NULL);
|
||||
else if (connect_type == CLEAR_AUTH || connect_type == SSL_AUTH)
|
||||
rtnval = ldap_simple_bind_s(ld, auth_dn, auth_password);
|
||||
/* else if (connect_type == SSL_CERTAUTH)
|
||||
rtnval = ldap_sasl_bind_s(ld, auth_dn, [mechanism], [cred], NULL,
|
||||
NULL, servercredp) */
|
||||
if (rtnval != LDAP_SUCCESS)
|
||||
return 5;
|
||||
|
||||
/*
|
||||
// Now ready to search
|
||||
*/
|
||||
|
||||
/* First create the filter from attrib(s) and rcpt_address */
|
||||
|
||||
/* first compute size of filter to create, and collect mail attribs */
|
||||
addr_len = strlen(rcpt_address);
|
||||
tmpstr1 = (char *)PR_Malloc(strlen(mail_attribs)+1);
|
||||
strcpy(tmpstr1, mail_attribs);
|
||||
tmpstr = tmpstr1;
|
||||
while (tstr = strchr(tmpstr, ',')) {
|
||||
*tstr = '\0';
|
||||
filter_length += addr_len + strlen(tmpstr) + 5;
|
||||
strcpy(mail_array[attr_count++], tmpstr);
|
||||
tmpstr = tstr+1;
|
||||
}
|
||||
/* and get last mail attribute */
|
||||
filter_length += addr_len + strlen(tmpstr) + 5;
|
||||
strcpy(mail_array[attr_count++], tmpstr);
|
||||
filter = (char *)PR_Malloc(filter_length);
|
||||
PR_Free(tmpstr1);
|
||||
|
||||
/* should figure out way to generalize this :-( */
|
||||
if (attr_count == 1)
|
||||
sprintf(filter, "(%s=%s)", mail_array[0], rcpt_address);
|
||||
else if (attr_count == 2)
|
||||
sprintf(filter, "(|(%s=%s)(%s=%s))", mail_array[0], rcpt_address,
|
||||
mail_array[1], rcpt_address);
|
||||
else if (attr_count == 3)
|
||||
sprintf(filter, "(|(%s=%s)(%s=%s)(%s=%s))", mail_array[0], rcpt_address,
|
||||
mail_array[1], rcpt_address, mail_array[2], rcpt_address);
|
||||
else
|
||||
return 6; /* too many mail attribs (should fix this eventually) */
|
||||
|
||||
/* Also get list of Cert attribs */
|
||||
cert_attrib_array = (char **)PR_Malloc(50); /* space for array of ptrs */
|
||||
tmp_cert_array = cert_attrib_array;
|
||||
|
||||
tmpstr = (char *)PR_Malloc(strlen(cert_attribs)+1);
|
||||
strcpy(tmpstr, cert_attribs);
|
||||
tmpstr1 = tmpstr;
|
||||
while (tstr = strchr(tmpstr, ',')) {
|
||||
*tstr = '\0';
|
||||
*tmp_cert_array = (char *)PR_Malloc(strlen(tmpstr)+1);
|
||||
strcpy(*tmp_cert_array, tmpstr);
|
||||
*tmp_cert_array++;
|
||||
tmpstr = tstr+1;
|
||||
}
|
||||
/* get last attribute, and put in NULL entry as end */
|
||||
*tmp_cert_array = (char *)PR_Malloc(strlen(tmpstr)+1);
|
||||
strcpy(*tmp_cert_array, tmpstr);
|
||||
*tmp_cert_array++;
|
||||
*tmp_cert_array = NULL;
|
||||
PR_Free(tmpstr1);
|
||||
|
||||
/* Now perform the search and check response */
|
||||
rtnval = ldap_search_s(ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
|
||||
cert_attrib_array, SSM_LDAP_FALSE, &reslt);
|
||||
PR_Free(filter);
|
||||
if (rtnval != LDAP_SUCCESS) {
|
||||
for (tmp_cert_array = cert_attrib_array; *tmp_cert_array;
|
||||
tmp_cert_array++)
|
||||
PR_Free(*tmp_cert_array);
|
||||
PR_Free(cert_attrib_array);
|
||||
return 7; /* LDAP Failure */
|
||||
}
|
||||
|
||||
entry_count = ldap_count_entries(ld, reslt);
|
||||
if (entry_count == 0) {
|
||||
for (tmp_cert_array = cert_attrib_array; *tmp_cert_array;
|
||||
tmp_cert_array++)
|
||||
PR_Free(*tmp_cert_array);
|
||||
PR_Free(cert_attrib_array);
|
||||
ldap_msgfree(reslt);
|
||||
ldap_unbind(ld);
|
||||
return -1; /* no entry found for rcpt */
|
||||
}
|
||||
if (entry_count > 1) {
|
||||
for (tmp_cert_array = cert_attrib_array; *tmp_cert_array;
|
||||
tmp_cert_array++)
|
||||
PR_Free(*tmp_cert_array);
|
||||
PR_Free(cert_attrib_array);
|
||||
ldap_msgfree(reslt);
|
||||
ldap_unbind(ld);
|
||||
return 8; /* multiple entries found for rcpt */
|
||||
}
|
||||
|
||||
/*
|
||||
*Okay, got an entry, check for Cert
|
||||
*/
|
||||
|
||||
rtnval = 9; /* default is to return no attrib found */
|
||||
|
||||
/* Now check each cert attribute type */
|
||||
entry = ldap_first_entry(ld, reslt);
|
||||
attrib_name_count = 0;
|
||||
tmp_cert_array = cert_attrib_array;
|
||||
while (*tmp_cert_array) {
|
||||
struct berval cert_attrib_struct;
|
||||
struct berval **cert_out_list;
|
||||
struct cert_struct_def * cert_ptr;
|
||||
int valcount=0;
|
||||
|
||||
cert_out_list = ldap_get_values_len(ld, entry, *tmp_cert_array);
|
||||
if (cert_out_list) { /* Values found for this cert attr */
|
||||
while (SSM_LDAP_TRUE) { /* just get count for malloc first */
|
||||
if (!cert_out_list[valcount++])
|
||||
break;
|
||||
}
|
||||
certs[attrib_name_count] = PR_Malloc(valcount * sizeof(cert_struct));
|
||||
cert_ptr = certs[attrib_name_count];
|
||||
|
||||
valcount =0;
|
||||
while (SSM_LDAP_TRUE) {
|
||||
if (!cert_out_list[valcount])
|
||||
break;
|
||||
cert_attrib_struct = *cert_out_list[valcount++];
|
||||
cert = PR_Malloc(cert_attrib_struct.bv_len);
|
||||
memcpy(cert, cert_attrib_struct.bv_val,
|
||||
cert_attrib_struct.bv_len);
|
||||
cert_ptr->cert = cert;
|
||||
cert_ptr->cert_len = cert_attrib_struct.bv_len;
|
||||
cert_ptr++;
|
||||
rtnval = 0; /* found at least one Cert */
|
||||
}
|
||||
cert_ptr->cert_len = 0; /* end list */
|
||||
}
|
||||
ldap_value_free_len(cert_out_list);
|
||||
*tmp_cert_array++;
|
||||
attrib_name_count++;
|
||||
}
|
||||
for (tmp_cert_array = cert_attrib_array; *tmp_cert_array;
|
||||
tmp_cert_array++)
|
||||
PR_Free(*tmp_cert_array);
|
||||
PR_Free(cert_attrib_array);
|
||||
ldap_msgfree(reslt);
|
||||
ldap_unbind(ld);
|
||||
return rtnval;
|
||||
}
|
54
security/psm/server/certsearch.h
Normal file
54
security/psm/server/certsearch.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef CERTSEARCH_H
|
||||
#define CERTSEARCH_H
|
||||
|
||||
#define CLEAR_ANON 1
|
||||
#define CLEAR_AUTH 2
|
||||
#define SSL_ANON 3
|
||||
#define SSL_AUTH 4
|
||||
#define SSL_CERTAUTH 5
|
||||
|
||||
typedef struct cert_struct_def {
|
||||
int cert_len;
|
||||
void * cert;
|
||||
} cert_struct;
|
||||
|
||||
|
||||
int LDAPCertSearch (const char * rcpt_address, const char * server_name,
|
||||
const char * baseDN, int port, int connect_type,
|
||||
const char * certdb_path, const char * auth_dn,
|
||||
const char * auth_password, const char * mail_attribs,
|
||||
const char * cert_attribs, cert_struct * certs[]);
|
||||
|
||||
#endif
|
373
security/psm/server/collectn.c
Normal file
373
security/psm/server/collectn.c
Normal file
@ -0,0 +1,373 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "collectn.h"
|
||||
#include "prerror.h"
|
||||
#include "prmem.h"
|
||||
#include "seccomon.h"
|
||||
#include "serv.h"
|
||||
|
||||
|
||||
SSMCollection *
|
||||
SSM_NewCollection(void)
|
||||
{
|
||||
SSMCollection *coll;
|
||||
|
||||
coll = PR_NEWZAP(SSMCollection);
|
||||
if (coll == NULL)
|
||||
goto loser;
|
||||
|
||||
coll->lock = PR_NewMonitor();
|
||||
if (coll->lock == NULL)
|
||||
goto loser;
|
||||
|
||||
PR_INIT_CLIST(&coll->list);
|
||||
|
||||
return coll;
|
||||
|
||||
loser:
|
||||
SSM_DestroyCollection(coll);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_DestroyCollection(SSMCollection *victim)
|
||||
{
|
||||
if (victim == NULL)
|
||||
return PR_SUCCESS;
|
||||
|
||||
PR_ASSERT(victim->nItems == 0);
|
||||
if (victim->nItems != 0)
|
||||
return PR_FAILURE;
|
||||
|
||||
if (victim->lock)
|
||||
PR_DestroyMonitor(victim->lock);
|
||||
|
||||
PR_Free(victim);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static SSMListItem *
|
||||
new_list_item(PRIntn priority, void *data)
|
||||
{
|
||||
SSMListItem *item;
|
||||
|
||||
item = PR_NEWZAP(SSMListItem);
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
|
||||
item->priority = priority;
|
||||
item->data = data;
|
||||
return item;
|
||||
}
|
||||
|
||||
static SSMListItem *
|
||||
find_list_item(SSMCollection *list, void *which)
|
||||
{
|
||||
PRCList *link;
|
||||
|
||||
for(link = PR_LIST_HEAD(&list->list); link != &list->list;
|
||||
link = PR_NEXT_LINK(link))
|
||||
{
|
||||
|
||||
SSMListItem *item = (SSMListItem *) link;
|
||||
if (item->data == which)
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Insert (item) into the list before (before).
|
||||
If (before) is NULL, append to the list. */
|
||||
SSMStatus
|
||||
ssm_InsertSafe(SSMCollection *list, PRIntn priority, void *data, void *before)
|
||||
{
|
||||
SSMListItem *beforeItem = NULL, *item;
|
||||
|
||||
if ((data == NULL) || (list == NULL))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/* Find (before) in the list if it's here. */
|
||||
if (before == NULL)
|
||||
beforeItem = (SSMListItem *) &list->list;
|
||||
else
|
||||
beforeItem = find_list_item(list, before);
|
||||
|
||||
/* Create a new list item. */
|
||||
item = new_list_item(priority, data);
|
||||
if (item == NULL)
|
||||
return PR_FAILURE;
|
||||
|
||||
PR_INSERT_BEFORE(&item->link, &beforeItem->link);
|
||||
list->nItems++;
|
||||
list->priorityCount[priority]++;
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Insert (data) into the list before (before).
|
||||
If (before) is NULL, append to the list. */
|
||||
SSMStatus
|
||||
SSM_Insert(SSMCollection *list, PRIntn priority, void *data, void *before)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(list->lock);
|
||||
rv = ssm_InsertSafe(list, priority, data, before);
|
||||
PR_Notify(list->lock);
|
||||
PR_ExitMonitor(list->lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Remove (data) from the list. */
|
||||
SSMStatus
|
||||
ssm_RemoveSafe(SSMCollection *list, void *data)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMListItem *item;
|
||||
|
||||
if ((data == NULL) || (list == NULL))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
item = find_list_item(list, data);
|
||||
if (item == NULL)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if ((item->priority >= 0) && (item->priority < SSM_PRIORITY_MAX))
|
||||
list->priorityCount[item->priority]--;
|
||||
|
||||
PR_REMOVE_LINK(&item->link);
|
||||
PR_Free(item);
|
||||
list->nItems--;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Remove (item) from the list. */
|
||||
SSMStatus
|
||||
SSM_Remove(SSMCollection *list, void *item)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(list->lock);
|
||||
rv = ssm_RemoveSafe(list, item);
|
||||
PR_Notify(list->lock);
|
||||
PR_ExitMonitor(list->lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Count the number of items in the list. */
|
||||
PRIntn
|
||||
ssm_CountSafe(SSMCollection *list, PRIntn priority)
|
||||
{
|
||||
PRIntn result = 0;
|
||||
PRIntn i;
|
||||
|
||||
if (priority == SSM_PRIORITY_ANY)
|
||||
result = list->nItems;
|
||||
else
|
||||
{
|
||||
for(i=priority; i <= SSM_PRIORITY_MAX; i++)
|
||||
result += list->priorityCount[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Count the number of items in the list. */
|
||||
PRIntn
|
||||
SSM_CountPriority(SSMCollection *list, PRIntn priority)
|
||||
{
|
||||
int count;
|
||||
|
||||
if ((list == NULL)
|
||||
|| (priority < SSM_PRIORITY_ANY)
|
||||
|| (priority > SSM_PRIORITY_MAX))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(list->lock);
|
||||
count = ssm_CountSafe(list, priority);
|
||||
PR_ExitMonitor(list->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
PRIntn
|
||||
SSM_Count(SSMCollection *list)
|
||||
{
|
||||
return SSM_CountPriority(list, SSM_PRIORITY_ANY);
|
||||
}
|
||||
|
||||
/* Get (which)th item from the list. zero-based index. */
|
||||
void *
|
||||
SSM_At(SSMCollection *list, PRIntn which)
|
||||
{
|
||||
PRCList *link;
|
||||
|
||||
if ((list == NULL) || (which >= list->nItems)) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(list->lock);
|
||||
|
||||
link = PR_LIST_HEAD(&list->list);
|
||||
for ( ; which > 0 ; which--) {
|
||||
link = PR_NEXT_LINK(link);
|
||||
}
|
||||
|
||||
PR_ExitMonitor(list->lock);
|
||||
|
||||
return ((SSMListItem *) link)->data;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSM_Enqueue(SSMCollection *list, PRIntn priority, void *item)
|
||||
{
|
||||
/* Insert this element at the end. */
|
||||
return SSM_Insert(list, priority, item, NULL);
|
||||
}
|
||||
|
||||
SSMListItem *
|
||||
ssm_FirstAtPriority(SSMCollection *list, PRIntn priority)
|
||||
{
|
||||
SSMListItem *result;
|
||||
SSMListItem *link;
|
||||
|
||||
result = NULL; /* in case we fail */
|
||||
|
||||
if ((list == NULL) || (priority > SSM_PRIORITY_MAX))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PR_CLIST_IS_EMPTY(&list->list))
|
||||
result = NULL;
|
||||
else if (priority == SSM_PRIORITY_ANY)
|
||||
result = (SSMListItem *) PR_LIST_HEAD(&list->list);
|
||||
else /* asked for priority and list not empty */
|
||||
{
|
||||
/* Find the first element from the list at (priority). */
|
||||
link = (SSMListItem *) PR_LIST_HEAD(&list->list);
|
||||
while((link != (SSMListItem *) &list->list) &&
|
||||
(link->priority < priority))
|
||||
link = (SSMListItem *) PR_NEXT_LINK(&link->link);
|
||||
|
||||
if (link != (SSMListItem *) &list->list)
|
||||
result = link;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_Dequeue(SSMCollection *list, PRIntn priority,
|
||||
void **result, PRBool doBlock)
|
||||
{
|
||||
void *data = NULL;
|
||||
SSMListItem *link;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
*result = NULL; /* in case we fail */
|
||||
|
||||
if (list == NULL) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(list->lock);
|
||||
|
||||
while(doBlock && (ssm_CountSafe(list, priority) == 0)) {
|
||||
rv = PR_Wait(list->lock, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (rv == PR_PENDING_INTERRUPT_ERROR)
|
||||
{
|
||||
/* We got interrupted, bail */
|
||||
return rv;
|
||||
}
|
||||
/* SSM_DEBUG("ssm_CountSafe (prio %d) is %d.\n",
|
||||
priority, ssm_CountSafe(list, priority));*/
|
||||
}
|
||||
|
||||
/* Pop the first element from the list at (priority). */
|
||||
if (!PR_CLIST_IS_EMPTY(&list->list)) {
|
||||
link = ssm_FirstAtPriority(list, priority);
|
||||
if (link)
|
||||
{
|
||||
data = link->data;
|
||||
|
||||
if ((link->priority >= 0) && (link->priority < SSM_PRIORITY_MAX))
|
||||
list->priorityCount[link->priority]--;
|
||||
|
||||
PR_REMOVE_LINK(&link->link);
|
||||
PR_Free(link);
|
||||
|
||||
list->nItems--;
|
||||
}
|
||||
}
|
||||
|
||||
PR_Notify(list->lock);
|
||||
PR_ExitMonitor(list->lock);
|
||||
|
||||
*result = data;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
203
security/psm/server/collectn.h
Normal file
203
security/psm/server/collectn.h
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __COLLECTN_H__
|
||||
#define __COLLECTN_H__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "prmon.h"
|
||||
#include "prclist.h"
|
||||
#include "ssmdefs.h"
|
||||
|
||||
/* definitions for priority */
|
||||
#define SSM_PRIORITY_ANY -1
|
||||
#define SSM_PRIORITY_NORMAL 0
|
||||
#define SSM_PRIORITY_UI 1
|
||||
#define SSM_PRIORITY_SHUTDOWN 30 /* always pull this if it's available */
|
||||
#define SSM_PRIORITY_MAX 31
|
||||
|
||||
/* This is an ordered collection of items without repetition. */
|
||||
/* This is to be used as a link in a PRCList.
|
||||
* You can cast any of the PRCList *'s in the list to one of these.
|
||||
* See prclist.h for details.
|
||||
*/
|
||||
typedef struct _SSMListItem
|
||||
{
|
||||
PRCList link;
|
||||
PRIntn priority;
|
||||
void *data;
|
||||
} SSMListItem;
|
||||
|
||||
/* An ordered collection, implemented in terms of PRCList. */
|
||||
struct _SSMCollection
|
||||
{
|
||||
PRMonitor *lock;
|
||||
PRIntn nItems;
|
||||
PRIntn priorityCount[SSM_PRIORITY_MAX+1];
|
||||
PRCList list;
|
||||
};
|
||||
|
||||
typedef struct _SSMCollection SSMCollection;
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_NewCollection
|
||||
** RETURNS:
|
||||
** SSMCollection *
|
||||
** returns a pointer to a new SSMCollection.
|
||||
** return NULL on error.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMCollection *SSM_NewCollection(void);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_DestroyCollection
|
||||
** INPUTS:
|
||||
** victim
|
||||
** The collection to be destroyed.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure. This can't happen (yet).
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_DestroyCollection(SSMCollection *victim);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_Enqueue
|
||||
** DESCRIPTION: Append (item) to (list).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be added to.
|
||||
** priority
|
||||
** The priority of the new item in the queue.
|
||||
** item
|
||||
** The data item to be enqueued.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_Enqueue(SSMCollection *list, PRIntn priority, void *item);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_Dequeue
|
||||
** DESCRIPTION: Retrieve a data item from the head of (list).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be retrieved from.
|
||||
** priority
|
||||
** The priority level of items to be removed from the queue.
|
||||
** Anything below the given priority level is ignored.
|
||||
** Pass SSM_PRIORITY_ANY to fetch the first item from the
|
||||
** queue regardless of priority.
|
||||
** doBlock
|
||||
** PR_TRUE if the function should block on an empty collection.
|
||||
** PR_FALSE if the function should not block.
|
||||
** OUTPUTS:
|
||||
** item
|
||||
** A pointer to the void * to hold the retrieved item.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_Dequeue(SSMCollection *list, PRIntn priority, void **item, PRBool doBlock);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_Insert
|
||||
** DESCRIPTION: Insert a new data item into (list) before (before).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be retrieved from.
|
||||
** priority
|
||||
** The priority of the item to be inserted.
|
||||
** item
|
||||
** The data item to insert.
|
||||
** before
|
||||
** The list member before which to insert.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_Insert(SSMCollection *list, PRIntn priority,
|
||||
void *item, void *before);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_Remove
|
||||
** DESCRIPTION: Remove (item) from (list).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be removed from.
|
||||
** item
|
||||
** The data item to be removed.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_Remove(SSMCollection *list, void *item);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_Count
|
||||
** DESCRIPTION: Returns the number of items in (list).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be counted.
|
||||
** priority
|
||||
** Only count items at or above (priority). Pass SSM_PRIORITY_ANY
|
||||
** to count all items in the list.
|
||||
** RETURNS:
|
||||
** The number of items in the list.
|
||||
**
|
||||
*************************************************************/
|
||||
PRIntn SSM_Count(SSMCollection *list);
|
||||
PRIntn SSM_CountPriority(SSMCollection *list, PRIntn priority);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_At
|
||||
** DESCRIPTION: Get the (which)'th item in (list).
|
||||
** INPUTS:
|
||||
** list
|
||||
** The collection to be indexed.
|
||||
** which
|
||||
** Index of item to retrieve. Zero is first item.
|
||||
**
|
||||
*************************************************************/
|
||||
void *SSM_At(SSMCollection *list, PRIntn which);
|
||||
|
||||
#endif /* __COLLECTN_H__ */
|
366
security/psm/server/connect.c
Normal file
366
security/psm/server/connect.c
Normal file
@ -0,0 +1,366 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "connect.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "prinrval.h"
|
||||
#include "crmf.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define SSMRESOURCE(conn) (&(conn)->super)
|
||||
|
||||
/*
|
||||
ssm_ConnectionCreate creates an SSMConnection object.
|
||||
The value argument is ignored.
|
||||
*/
|
||||
SSMStatus
|
||||
SSMConnection_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMConnection *conn;
|
||||
SSMControlConnection * owner;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMConnection *) PR_CALLOC(sizeof(SSMConnection));
|
||||
if (!conn)
|
||||
goto loser;
|
||||
if (connection)
|
||||
owner = connection;
|
||||
else
|
||||
owner = (SSMControlConnection *)conn;
|
||||
rv = SSMConnection_Init(owner, (SSMConnection *) arg,
|
||||
SSM_RESTYPE_CONNECTION);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMConnection_Invariant(conn);
|
||||
|
||||
*res = &conn->super;
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
|
||||
SSM_FreeResource(&conn->super);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* As a sanity check, make sure we have data structures consistent
|
||||
with our type. */
|
||||
void SSMConnection_Invariant(SSMConnection *conn)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (conn)
|
||||
{
|
||||
SSMResource_Invariant(&(conn->super));
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn), SSM_RESTYPE_CONNECTION));
|
||||
PR_ASSERT(conn->m_children != NULL);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
#if 0
|
||||
if (conntype == SSM_DATA_CONNECTION)
|
||||
{
|
||||
PR_ASSERT(!conn->m_children);
|
||||
PR_ASSERT(!conn->m_readThread);
|
||||
PR_ASSERT(!conn->m_writeThread);
|
||||
PR_ASSERT(!conn->m_controlOutQ);
|
||||
}
|
||||
else /* control connection */
|
||||
{
|
||||
PR_ASSERT(conn->m_children);
|
||||
PR_ASSERT(!conn->m_readClientThread);
|
||||
PR_ASSERT(!conn->m_writeClientThread);
|
||||
PR_ASSERT(!conn->m_readTargetThread);
|
||||
PR_ASSERT(!conn->m_writeTargetThread);
|
||||
PR_ASSERT(!conn->m_incomingQ);
|
||||
PR_ASSERT(!conn->m_outgoingQ);
|
||||
PR_ASSERT(conn->m_resourceID == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_DetachChild(SSMConnection *parent, SSMConnection *child)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSM_LockResource(&parent->super);
|
||||
|
||||
/* Remove the child from the parent's collection of children. */
|
||||
rv = SSM_Remove(parent->m_children, child);
|
||||
child->m_parent = NULL;
|
||||
|
||||
/* If the parent is detaching (due to destruction), free the child. */
|
||||
if (&parent->super.m_refCount == 0)
|
||||
SSM_FreeResource(&child->super);
|
||||
|
||||
SSM_UnlockResource(&parent->super);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_AttachChild(SSMConnection *parent, SSMConnection *child)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSM_LockResource(&parent->super);
|
||||
rv = SSM_Insert(parent->m_children, SSM_PRIORITY_NORMAL, child, NULL);
|
||||
SSM_UnlockResource(&parent->super);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_Shutdown(SSMResource *res, SSMStatus status)
|
||||
{
|
||||
SSMConnection *conn = (SSMConnection *) res;
|
||||
SSMStatus rv;
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
rv = SSMResource_Shutdown(res, status);
|
||||
|
||||
if (SSMRESOURCE(conn)->m_threadCount == 0)
|
||||
{
|
||||
SSMConnection *child;
|
||||
|
||||
/* Shut down child connections. */
|
||||
SSM_Dequeue(conn->m_children, SSM_PRIORITY_ANY,
|
||||
(void **) &child, PR_FALSE);
|
||||
while(child != NULL)
|
||||
{
|
||||
SSM_ShutdownResource(&child->super, (SSMStatus) PR_PENDING_INTERRUPT_ERROR);
|
||||
SSMConnection_DetachChild(conn, child);
|
||||
child = NULL;
|
||||
}
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
SSMConnection *conn = (SSMConnection *) res;
|
||||
SSMResource *child = NULL;
|
||||
|
||||
/* Destroy the collection of child connections. */
|
||||
if (conn->m_children)
|
||||
{
|
||||
/* Detach all children. */
|
||||
do
|
||||
{
|
||||
SSM_Dequeue(conn->m_children, SSM_PRIORITY_ANY,
|
||||
(void **) &child, PR_FALSE);
|
||||
if (child && (child != SSMRESOURCE(conn)))
|
||||
{
|
||||
SSM_DEBUG("Freeing child connection %lx.\n",
|
||||
(unsigned long) child);
|
||||
SSM_FreeResource(child);
|
||||
|
||||
}
|
||||
}
|
||||
while (child != NULL);
|
||||
PR_ASSERT(SSM_Count(conn->m_children) == 0);
|
||||
SSM_DestroyCollection(conn->m_children);
|
||||
}
|
||||
/* If we're attached to a parent, detach from the parent's collection. */
|
||||
if (conn->m_parent)
|
||||
SSMConnection_DetachChild(conn->m_parent, conn);
|
||||
|
||||
SSMResource_Destroy(res, PR_FALSE);
|
||||
|
||||
if (doFree) {
|
||||
PR_Free(res);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMResource_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 2) * sizeof(SSMResourceID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_CONN_ALIVE;
|
||||
(*ids)[*count++] = SSM_FID_CONN_PARENT;
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMConnection *conn = (SSMConnection *) res;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_CONN_ALIVE:
|
||||
value->u.numeric = (PRUint32) (conn->super.m_threadCount > 0);
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
break;
|
||||
|
||||
case SSM_FID_CONN_PARENT:
|
||||
rv = SSM_ClientGetResourceReference(SSMRESOURCE(conn->m_parent),
|
||||
&value->u.rid);
|
||||
value->type = SSM_RID_ATTRIBUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMResource_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
/* we own nothing, defer to superclass */
|
||||
rv = SSMResource_SetAttr(res,attrID,value);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMConnection_Init(SSMControlConnection *ctrl, SSMConnection *connection,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMControlConnection * owner;
|
||||
|
||||
if (type == SSM_RESTYPE_CONTROL_CONNECTION)
|
||||
owner = (SSMControlConnection *)connection;
|
||||
else owner = ctrl;
|
||||
|
||||
rv = SSMResource_Init(owner, &connection->super, type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Attach ourselves to the parent first, then set the member */
|
||||
if (ctrl != NULL) {
|
||||
rv = SSMConnection_AttachChild(&(ctrl->super), connection);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
connection->m_parent = &(ctrl->super);
|
||||
|
||||
|
||||
connection->m_children = SSM_NewCollection();
|
||||
if (!connection->m_children) goto loser;
|
||||
|
||||
/* hang our hooks */
|
||||
connection->m_auth_func = SSMConnection_Authenticate;
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMConnection_Authenticate(SSMConnection *conn, char *nonce)
|
||||
{
|
||||
/* Abstract method, report failure by default */
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
||||
/* Given a RID and a proposed nonce, see if the connection exists
|
||||
and if the nonce matches. */
|
||||
SSMStatus SSM_AuthenticateConnection(SSMControlConnection * ctrl,
|
||||
SSMResourceID rid, char *nonce)
|
||||
{
|
||||
SSMResource *obj = NULL;
|
||||
SSMConnection *conn;
|
||||
SSMStatus rv;
|
||||
|
||||
/* Find the connection object. */
|
||||
rv = (SSMStatus) SSMControlConnection_GetResource(ctrl, rid, &obj);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
PR_ASSERT(obj);
|
||||
|
||||
SSM_LockResource(obj);
|
||||
|
||||
if (!SSM_IsAKindOf(obj, SSM_RESTYPE_CONNECTION))
|
||||
goto loser;
|
||||
|
||||
conn = (SSMConnection *) obj;
|
||||
if (!conn->m_auth_func)
|
||||
goto loser;
|
||||
|
||||
rv = (*conn->m_auth_func)(conn, nonce);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
if (obj) SSM_UnlockResource(obj);
|
||||
return rv;
|
||||
}
|
||||
|
154
security/psm/server/connect.h
Normal file
154
security/psm/server/connect.h
Normal file
@ -0,0 +1,154 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_CONNECT_H__
|
||||
#define __SSM_CONNECT_H__
|
||||
|
||||
#include "ssmdefs.h"
|
||||
#include "collectn.h"
|
||||
#include "hashtbl.h"
|
||||
#include "resource.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "plarena.h"
|
||||
#include "mcom_db.h"
|
||||
#include "seccomon.h"
|
||||
#include "secmodt.h"
|
||||
#include "prinrval.h"
|
||||
|
||||
/* Cartman password policy */
|
||||
#define SSM_MIN_PWD_LEN 0
|
||||
#define SSM_MAX_PWD_LEN 64
|
||||
|
||||
typedef struct SSMConnection SSMConnection;
|
||||
typedef SSMStatus (*SSMConnectionAuthenticateFunc)(SSMConnection *conn,
|
||||
char *nonce);
|
||||
|
||||
struct SSMConnection
|
||||
{
|
||||
SSMResource super;
|
||||
/*
|
||||
---------------------------------------------
|
||||
Generic fields, applicable to all connections
|
||||
---------------------------------------------
|
||||
*/
|
||||
|
||||
/* ### mwelch - children/parent should perhaps be put in subclasses,
|
||||
but we may use these in multiple ways in the future */
|
||||
|
||||
/* Parent connection object. If this is a data object, m_parent points
|
||||
to the control connection which spawned it. */
|
||||
SSMConnection * m_parent;
|
||||
|
||||
/* Child connection objects. If this is a control object, the collection
|
||||
is filled with data connection objects. */
|
||||
SSMCollection *m_children;
|
||||
|
||||
/* The function to call when we want to validate an incoming connection */
|
||||
SSMConnectionAuthenticateFunc m_auth_func;
|
||||
};
|
||||
|
||||
/*
|
||||
* Information for authenticated tokens.
|
||||
*/
|
||||
#define SSM_MINUTES_WAIT_PASSWORD 10
|
||||
#define SSM_PASSWORD_WAIT_TIME (SSM_MINUTES_WAIT_PASSWORD*PR_TicksPerSecond()*60)
|
||||
#define SSM_NO_PASSWORD 0x99999999
|
||||
#define SSM_CANCEL_PASSWORD 0x99999998
|
||||
|
||||
struct _SSM_TokenInfoStr {
|
||||
PK11SlotInfo * slot;
|
||||
PRInt32 tokenID;
|
||||
char * encrypted;
|
||||
PRInt32 encryptedLen;
|
||||
PK11SymKey * symKey;
|
||||
};
|
||||
typedef struct _SSM_TokenInfoStr SSM_TokenInfo;
|
||||
|
||||
|
||||
/* Password callback */
|
||||
char * SSM_GetPasswdCallback(PK11SlotInfo *slot, PRBool retry, void *arg);
|
||||
PRBool SSM_VerifyPasswdCallback(PK11SlotInfo * slot, void * arg);
|
||||
|
||||
#ifdef ALLOW_STANDALONE
|
||||
/* For standalone mode only */
|
||||
char * SSM_StandaloneGetPasswdCallback(PK11SlotInfo *slot, PRBool retry,
|
||||
void *arg);
|
||||
PRBool SSM_StandaloneVerifyPasswdCallback(PK11SlotInfo * slot, void * arg);
|
||||
#endif
|
||||
|
||||
char * SSM_GetAuthentication(PK11SlotInfo * slot, PRBool retry, PRBool init,
|
||||
SSMResource * conn);
|
||||
SSMStatus SSM_SetUserPassword(PK11SlotInfo * slot, SSMResource * ct);
|
||||
|
||||
SSMStatus SSMConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMConnection_Init(SSMControlConnection *ctrl,
|
||||
SSMConnection *conn, SSMResourceType type);
|
||||
SSMStatus SSMConnection_Shutdown(SSMResource *conn, SSMStatus status);
|
||||
SSMStatus SSMConnection_Destroy(SSMResource *conn, PRBool doFree);
|
||||
void SSMConnection_Invariant(SSMConnection *conn);
|
||||
|
||||
SSMStatus SSMConnection_AttachChild(SSMConnection *parent, SSMConnection *child);
|
||||
SSMStatus SSMConnection_DetachChild(SSMConnection *parent, SSMConnection *child);
|
||||
|
||||
SSMStatus SSMConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMConnection_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
/* Given a RID and a proposed nonce, see if the connection exists
|
||||
and if the nonce matches. */
|
||||
SSMStatus SSMConnection_Authenticate(SSMConnection *conn, char *nonce);
|
||||
/* Function to encrypt password to storing it in Cartman */
|
||||
SSMStatus SSM_EncryptPasswd(PK11SlotInfo * slot, char * passwd,
|
||||
SSM_TokenInfo ** info);
|
||||
SSMStatus SSMControlConnection_WaitPassword(SSMConnection * conn,
|
||||
PRInt32 key, char ** str);
|
||||
SSMStatus SSM_AskUserPassword(SSMResource * conn,
|
||||
PK11SlotInfo * slot, PRInt32 retry, PRBool init);
|
||||
/* Function returning user prompt */
|
||||
char * SSM_GetPrompt(PK11SlotInfo *slot, PRBool retry, PRBool init);
|
||||
|
||||
#define XP_SEC_ERROR_PWD "Successive login failures may disable this card or database. Password is invalid. Retry?\n %s\n"
|
||||
|
||||
#define XP_SEC_ENTER_PWD "Please enter the password or the pin for\n%s."
|
||||
#define XP_SEC_SET_PWD "Please enter the password or the pin for\n%s. Remember this password, you will need \nit to access your certificates."
|
||||
#endif
|
113
security/psm/server/createBomb.c
Normal file
113
security/psm/server/createBomb.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* We really do have 'long long' on the Mac, but NSPR doesn't yet know this.
|
||||
Need to define this before including NSPR to get the right defn of PRInt64. */
|
||||
#if 0
|
||||
#ifdef XP_MAC
|
||||
#define HAVE_LONG_LONG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "prtime.h"
|
||||
#include "prenv.h"
|
||||
#include "prlong.h"
|
||||
|
||||
char * timebombVar = "NSM_TIMEBOMB";
|
||||
#define SSM_SEC_PER_24HRS (60 * 60 * 24)
|
||||
|
||||
int main()
|
||||
{
|
||||
FILE * headerFile, * timeFile;
|
||||
int daysToLive;
|
||||
char * tmp = PR_GetEnv(timebombVar);
|
||||
PRTime timeNow, lifeTime, expire, tmpVal, days, tmpMilli;
|
||||
PRInt32 timeHi, timeLow;
|
||||
|
||||
daysToLive = atoi(tmp);
|
||||
timeNow = PR_Now();
|
||||
|
||||
LL_I2L(tmpVal, SSM_SEC_PER_24HRS);
|
||||
LL_I2L(days, daysToLive);
|
||||
LL_MUL(tmpMilli, days, tmpVal);
|
||||
LL_MUL(lifeTime, tmpMilli, PR_USEC_PER_SEC);
|
||||
|
||||
LL_ADD(expire, timeNow, lifeTime);
|
||||
LL_SHR(tmpVal, expire, 32);
|
||||
LL_L2UI(timeHi, tmpVal);
|
||||
LL_L2UI(timeLow, expire);
|
||||
|
||||
|
||||
timeFile = fopen("timestamp.h", "w");
|
||||
if (!timeFile) {
|
||||
printf("Can't create timestamp.h.\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
fprintf(timeFile, "/*\n * Created automatically, do not edit!\n */\n\n");
|
||||
fprintf(timeFile, "/* This build of Cartman will expire at this time. */ \n");
|
||||
fprintf(timeFile, "static PRTime expirationTime = LL_INIT(0x%lx, 0x%lx);\n", timeHi,
|
||||
timeLow);
|
||||
|
||||
fclose(timeFile);
|
||||
|
||||
headerFile = fopen("timebomb.h", "w");
|
||||
if (!headerFile) {
|
||||
printf("Can't open timebomb.h for writing!\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
fprintf(headerFile,
|
||||
"/* This file is generated automatically by createBomb.c, do not edit! */\n\n\n");
|
||||
|
||||
/*
|
||||
* Function declarations that are used for the timebomb.
|
||||
* Definitions are in timebomb.c, included in frontend.c.
|
||||
*/
|
||||
fprintf(headerFile,
|
||||
"\n\n/* Functions used in Cartman for the timebomb. */\n");
|
||||
fprintf(headerFile,
|
||||
"/*\n * Set SSMTimeBombExpired to PR_TRUE if Cartman has expired. \n */\n");
|
||||
fprintf(headerFile, "void SSM_CheckTimeBomb();\n\n");
|
||||
fprintf(headerFile,
|
||||
"/*\n * Run this function from frontend thread of control connection\n * if Cartman has expired. \n */\n");
|
||||
fprintf(headerFile, "void SSM_CartmanHasExpired(SSMControlConnection * control);\n\n");
|
||||
|
||||
fclose(headerFile);
|
||||
|
||||
loser:
|
||||
return 0;
|
||||
}
|
1309
security/psm/server/crmfres.c
Normal file
1309
security/psm/server/crmfres.c
Normal file
File diff suppressed because it is too large
Load Diff
404
security/psm/server/crmfres.h
Normal file
404
security/psm/server/crmfres.h
Normal file
@ -0,0 +1,404 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _CRMFRES_H_
|
||||
#define _CRMFRES_H_
|
||||
#include "cmmf.h"
|
||||
#include "keyres.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "ctrlconn.h"
|
||||
|
||||
/*
|
||||
* FILE: crmfres.h
|
||||
* ---------------
|
||||
* This file defines the public interface for the class SSMCRMFRequest
|
||||
* which is to be used in Cartman to implement all necessary CRMF
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
/*
|
||||
* STRUCTURE: SSMCRMFRequest
|
||||
* -------------------------
|
||||
* This is the structure used to implement the SSMCRMFRequest
|
||||
* class. This class will be used to create CRMF Requests within
|
||||
* Cartman. SSMCRMFRequest sub-classess off of SSMResource so it
|
||||
* must always follow any guidelines for naming and defining presented
|
||||
* by the SSMResource class.
|
||||
*
|
||||
* The fields:
|
||||
*
|
||||
* super The mandatory first member for any class sub-classing
|
||||
* from SSMResource.
|
||||
*
|
||||
* m_KeyGenType An enumerated type indicating what type of key pair
|
||||
* we are creating a request for. This value is used
|
||||
* to set the appropriate keyUsage extensions and also
|
||||
* determining the proper method to set for
|
||||
* Proof-Of-Possession. Look at the file
|
||||
* ns/security/ssm/lib/protocol/ssmders.h for valid values.
|
||||
* This value is set by the client.
|
||||
*
|
||||
* m_KeyPair A pointer to a key pair associated with the instantiation
|
||||
* of the CRMF request. The members mPrivKey and mPubKey
|
||||
* must be non-NULL values when a new request is created.
|
||||
*
|
||||
* m_CRMFRequest This is the member that holds all of the state information
|
||||
* about the CRMF request.
|
||||
*
|
||||
* m_Connection This is the control connection associated with the
|
||||
* request.
|
||||
*/
|
||||
typedef struct SSMCRMFRequest {
|
||||
SSMResource super; /* This must always be the first member of the
|
||||
* structure. Don't even think of adding another
|
||||
* field before it or removing it.
|
||||
*/
|
||||
|
||||
SSMKeyGenType m_KeyGenType;
|
||||
SSMKeyPair *m_KeyPair;
|
||||
CRMFCertRequest *m_CRMFRequest;
|
||||
SSMControlConnection *m_Connection;
|
||||
} SSMCRMFRequest;
|
||||
|
||||
/*
|
||||
* STRUCTURE: SSMCRMFRequestArg
|
||||
* ----------------------------
|
||||
* This structure will be used to pass the initialization information
|
||||
* to the SSMCRMFRequest_Init function.
|
||||
*
|
||||
* keyPair The key pair that will be associated with the
|
||||
* new CRMF request.
|
||||
*
|
||||
* connection The control connection to be associated with the
|
||||
* new CRMF request. The SSMCRMFRequest object will
|
||||
* use to get to the certificate and key databases.
|
||||
*/
|
||||
typedef struct SSMCRMFRequestArgStr {
|
||||
SSMKeyPair *keyPair;
|
||||
SSMControlConnection *connection;
|
||||
} SSMCRMFRequestArg;
|
||||
|
||||
/*
|
||||
* FUNCTION:SSM_CreateNewCRMFRequest
|
||||
* ---------------------------------
|
||||
* INPUTS:
|
||||
* msg
|
||||
* The message from the client requesting a new CRMF request.
|
||||
* connection
|
||||
* The control connection to be associated with the new request.
|
||||
* destID
|
||||
* Pointer to a pre-allocated chunk of memory where the function
|
||||
* will place the ID of the newly created SSMCRMFRequest Object.
|
||||
*
|
||||
* NOTES:
|
||||
* This function takes the message received by the client, interprets
|
||||
* the message, creates a new SSMCRMFObject, adds it to the Global Resource
|
||||
* table, and places the resource id of the new object at *destID. To free
|
||||
* the returned object, call SSM_FreeResource and pass in the object object
|
||||
* ID placed at *destID by this function.
|
||||
*
|
||||
* RETURN:
|
||||
* The function returns PR_SUCCESS when successful. Any other return value
|
||||
* should be interpreted as an error.
|
||||
*/
|
||||
SSMStatus SSM_CreateNewCRMFRequest(SECItem *msg,
|
||||
SSMControlConnection *connection,
|
||||
SSMResourceID *destID);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMCRMFRequest_Create
|
||||
* -------------------------------
|
||||
* INPUTS:
|
||||
* arg
|
||||
* The creation argument for the SSMCRMFRequest class. This should
|
||||
* be a pointer to SSMKeyPair resource.
|
||||
* res
|
||||
* Pointer to a pre-allocated chunk of memory where the function can
|
||||
* place the value of the pointer to the newly created SSMCRMFRequest
|
||||
* object
|
||||
*
|
||||
* NOTES:
|
||||
* This function serves as the constructor for the SSMCRMFRequest class. This
|
||||
* function over-rides the function SSMResource_Create which is the super
|
||||
* class for SSMCRMFRequest.
|
||||
*
|
||||
* RETURN:
|
||||
* Returns PR_SUCCESS upon successful creation. Any other error indicates an
|
||||
* error.
|
||||
*/
|
||||
SSMStatus SSMCRMFRequest_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMCRMFRequest_Init
|
||||
* -----------------------------
|
||||
* INPUTS:
|
||||
* inCRMFReq
|
||||
* A pointer to a newly allocated SSMCRMFRequest which needs to be
|
||||
* initialized.
|
||||
* type
|
||||
* The type for the class that is being initialized. This value should
|
||||
* always be SSM_RESTYPE_CRMFREQ. (Unless one day someone decides to
|
||||
* sub-class off of SSMCRMFRequest.)
|
||||
* inKeyPair
|
||||
* The Key Pair to associate with the CRMF request being initialized.
|
||||
* inConnection
|
||||
* The control connection to be associated with the request being
|
||||
* initialized.
|
||||
*
|
||||
* NOTES:
|
||||
* This function intializes a new SSMCRMFRequest object. This function will
|
||||
* initialize its super-class member and make sure the passed in key pair has
|
||||
* non-NULL values for mPrivKey and mPubKey before getting a reference to the
|
||||
* passed in key pair. Finally, the function creates a
|
||||
* new NSS based CRMF request and sets the following fields in the request:
|
||||
* 1) version is set v3 Cert
|
||||
* 2) The Public Key value in the request
|
||||
*
|
||||
* RETURN:
|
||||
* The function returns PR_SUCCESS upon successful initialization. Any other
|
||||
* return value should be interpreted as an error.
|
||||
*/
|
||||
SSMStatus SSMCRMFRequest_Init(SSMCRMFRequest *inCRMFReq,
|
||||
SSMControlConnection * conn,
|
||||
SSMResourceType type,
|
||||
SSMKeyPair *inKeyPair,
|
||||
SSMControlConnection *inConnection);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMCRMFRequest_Destroy
|
||||
* --------------------------------
|
||||
* INPUTS:
|
||||
* inRequest
|
||||
* A pointer to a SSMResource of type SSM_RESTYPE_CRMFREQ to be
|
||||
* destroyed.
|
||||
* doFree
|
||||
* Until the day when someone creates a sub-class of SSMCRMFRequest,
|
||||
* this value should always be PR_TRUE.
|
||||
*
|
||||
* NOTES:
|
||||
* This function takes of freeing up all memory associated with the
|
||||
* SSMCRMFRequest. First the funciton will release the reference obtained
|
||||
* for the member mKeyPair in the function SSMCRMFRequest_Init. The function
|
||||
* then calls CRMF_DestroyCertRequest to free the memory used by mCRMFRequest.
|
||||
* Finally, the function calls SSMResource_Destroy to free up the SSMResource
|
||||
* member before calling free on the pointer passed in.
|
||||
*
|
||||
* RETURN:
|
||||
* Function returns PR_SUCCESS upon successful destruction of the object. Any
|
||||
* other return value should be interpreted as an error.
|
||||
*/
|
||||
SSMStatus SSMCRMFRequest_Destroy(SSMResource *inRequest, PRBool doFree);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMCRMFRequest_SetAttr
|
||||
* --------------------------------
|
||||
* INPUTS:
|
||||
* res
|
||||
* A pointer to a SSMResource of type SSM_RESTYPE_CRMFREQ
|
||||
* attrID
|
||||
* The attribute to set in the request.
|
||||
* value
|
||||
* The data to use when setting the desired attribute.
|
||||
*
|
||||
* NOTES:
|
||||
* This function over-rides SSMResource_SetAttr which all classes inherit
|
||||
* from the SSMResource class. This function will set the following
|
||||
* attributes (these attributes are defined in
|
||||
* ns/security/ssm/lib/protocol/rsrcids.h):
|
||||
*
|
||||
* SSMAttributeID SSMResourceAttrType Value(s)
|
||||
* -------------- ------------------- --------
|
||||
* SSM_FID_CRMFREQ_KEY_TYPE SSM_NUMERIC_ATTRIBUTE A pointer to any
|
||||
* enumerated value
|
||||
* with type of
|
||||
* SSMKeyGenType.
|
||||
*
|
||||
* SSM_FID_CRMFREQ_DN SSM_STRING_ATTRIBUTE An RFC1485
|
||||
* formatted DN.
|
||||
*
|
||||
* SSM_FID_REGTOKEN SSM_STRING_ATTRIBUTE A string to place
|
||||
* as the Registration
|
||||
* token for the
|
||||
* request.
|
||||
*
|
||||
* SSM_FID_AUTHENTICATOR SSM_STRING_ATTRIBUTE A string to place
|
||||
* as the
|
||||
* Authenticator token
|
||||
* in the request.
|
||||
*
|
||||
* SSM_FID_CRMFREQ_ESCROW_AUTHORITY SSM_STRING_ATTRIBUTE A base64 encoded
|
||||
* DER cert to use for
|
||||
* creating the
|
||||
* PKIArchiveOptions
|
||||
* control.
|
||||
*
|
||||
* NOTES:
|
||||
* The function return PR_SUCCESS if setting the field with the given data
|
||||
* was successful. Any other return value should be considered an error.
|
||||
*
|
||||
*/
|
||||
|
||||
SSMStatus SSMCRMFRequest_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMCRMFRequest_SetEscrowAuthority
|
||||
* -------------------------------------------
|
||||
* INPUTS:
|
||||
* crmfReq
|
||||
* The CRMFRequest resource to add the escrow authority to.
|
||||
* eaCert
|
||||
* The Certificate that belongs to the CA that wants to
|
||||
* escrow the private key associated with the request.
|
||||
* NOTES:
|
||||
* This function will wrap the private key in an EncryptedKey type
|
||||
* defined by CRMF and include in the CRMF request that is generated.
|
||||
*
|
||||
* RETURN:
|
||||
* PR_SUCCESS indicates the private key associated with the requested
|
||||
* was successfully wrapped and made a part of the CRMF request. Any
|
||||
* other return value indicates an error in trying to wrap the private
|
||||
* and include it in the CRMF request.
|
||||
*/
|
||||
SSMStatus SSMCRMFRequest_SetEscrowAuthority(SSMCRMFRequest *crmfReq,
|
||||
CERTCertificate *eaCert);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSM_EncodeCRMFRequests
|
||||
* --------------------------------
|
||||
* INPUTS:
|
||||
* msg
|
||||
* The message received from the client requesting CRMF messages to
|
||||
* be encoded.
|
||||
* destDER
|
||||
* Pointer to a pre-allocated chunk of memory where the function can
|
||||
* place a pointer to the base64 encoded CRMF CertReqMessages
|
||||
* destLen
|
||||
* Pointer to a pre-allocated piece of memory where the function can
|
||||
* place the length of the string returned in *destDER.
|
||||
*
|
||||
* NOTES:
|
||||
* This function takes a message request from the client to encode CRMF
|
||||
* requests. The output will be base64 DER-formatted bytes of the type
|
||||
* CertReqMessages as defined by the CRMF Internet Draft. The function
|
||||
* will allocate a buffer in memory to store the DER using PORT_Alloc and
|
||||
* place a pointer to the buffer at *destDER.
|
||||
*
|
||||
* RETURN:
|
||||
* The function will return PR_SUCCESS if encoding the requests was successful.
|
||||
* Any other return value should be treated as an error and the values at
|
||||
* *destDER and *destLen should be ignored.
|
||||
*/
|
||||
|
||||
SSMStatus SSM_EncodeCRMFRequests(SSMControlConnection * ctrl, SECItem *msg,
|
||||
char **destDER, SSMPRUint32 *destLen);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSM_ProcessCMMFCertResponse
|
||||
* -------------------------------------
|
||||
* INPUTS:
|
||||
* msg
|
||||
* The message received from the client requesting Cartman to
|
||||
* process a CMMF response.
|
||||
* connection
|
||||
* The control connection associated with the CMMF response.
|
||||
* The connection is necessary so that the function can find
|
||||
* the appropriate cetificate database for placing the decoded
|
||||
* certificates.
|
||||
*
|
||||
* NOTES:
|
||||
* This function serves as the back-end for the JavaScript method
|
||||
* crypto.importUserCertificates. It will decode the base64 DER blob passed
|
||||
* in and process it. Eventually this function will also start the process
|
||||
* of backing up the certificate when Cartman supports that feature.
|
||||
* View the document at http://warp/hardcore/library/arch/cert-issue.html
|
||||
* to see a detailed explanation for what this function doess.
|
||||
*
|
||||
*/
|
||||
SSMStatus SSM_ProcessCMMFCertResponse(SECItem *msg,
|
||||
SSMControlConnection *connection);
|
||||
|
||||
/*
|
||||
* FUNCTION: SSM_RespondToPOPChallenge
|
||||
* -----------------------------------
|
||||
* INPUTS:
|
||||
* msg
|
||||
* The message received from the client requesting that Cartman
|
||||
* respond to a challenge.
|
||||
* ctrl
|
||||
* The Control Connection associated with the message to process.
|
||||
* challengeResponse
|
||||
* A pointer to a pre-allocated pointer where the function can place
|
||||
* a copy of the base64 encoded response to the challenge. The
|
||||
* response will be a POPODecKeyRespContent defined in the CMMF
|
||||
* internet draft.
|
||||
* responseLen
|
||||
* A pointer to a pre-allocated PRUint32 where the function can place
|
||||
* the length of the response returned via the challengeResponse input
|
||||
* parameter.
|
||||
*
|
||||
* NOTES:
|
||||
* This function servers as the back-end for the JavaScript method
|
||||
* crypto.popChallengeRespone. The function will decode the base64 DER blob
|
||||
* passed in and process it. The function
|
||||
*/
|
||||
SSMStatus SSM_RespondToPOPChallenge(SECItem *msg,
|
||||
SSMControlConnection *ctrl,
|
||||
char **challengeResponse,
|
||||
PRUint32 *responseLen);
|
||||
|
||||
typedef struct SSMCRMFThreadArgStr {
|
||||
SSMControlConnection *ctrl;
|
||||
SECItem *msg;
|
||||
} SSMCRMFThreadArg;
|
||||
|
||||
/*
|
||||
* FUNCTION: SSM_CRMFEncodeThread
|
||||
* ------------------------------
|
||||
* INPUTS:
|
||||
* arg
|
||||
* A pointer to a structure of type SSMCRMFThreadArg which the function
|
||||
* will use to encode a CRMF request.
|
||||
* NOTES:
|
||||
* This function is intended to encode a CRMF request taking a message from
|
||||
* the client as its argument along with the associated control thread. This
|
||||
* function will send the reply back to the client in case of success or
|
||||
* failure so the client may proceed with its operations.
|
||||
* RETURN:
|
||||
* No return value.
|
||||
*/
|
||||
void SSM_CRMFEncodeThread(void *arg);
|
||||
#endif /* _CRMFRES_H_ */
|
||||
|
2804
security/psm/server/ctrlconn.c
Normal file
2804
security/psm/server/ctrlconn.c
Normal file
File diff suppressed because it is too large
Load Diff
255
security/psm/server/ctrlconn.h
Normal file
255
security/psm/server/ctrlconn.h
Normal file
@ -0,0 +1,255 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_CTRLCONN_H__
|
||||
#define __SSM_CTRLCONN_H__
|
||||
|
||||
#include "connect.h"
|
||||
#include "cert.h"
|
||||
#include "key.h"
|
||||
#include "hashtbl.h"
|
||||
#include "obscure.h"
|
||||
#include "prefs.h"
|
||||
|
||||
/*
|
||||
Control connections.
|
||||
*/
|
||||
extern SSMHashTable * ctrlConnections;
|
||||
|
||||
struct SSMControlConnection
|
||||
{
|
||||
SSMConnection super;
|
||||
|
||||
/*
|
||||
---------------------------------------------
|
||||
Control connection-specific fields
|
||||
---------------------------------------------
|
||||
*/
|
||||
|
||||
PRUint32 m_version; /* Protocol version supported by client */
|
||||
char * m_nonce; /* Nonce used for verifying data connections */
|
||||
|
||||
PRFileDesc * m_socket; /* Socket serviced by this connection object */
|
||||
PRThread * m_writeThread;/* Write Control thread (writes m_socket) */
|
||||
PRThread * m_frontEndThread; /* Front end thread - reads m_socket */
|
||||
PRThread * m_certRenewalThread; /* Front end thread - reads m_socket */
|
||||
|
||||
char * m_profileName; /* Name of user profile (where to find
|
||||
certs etc) */
|
||||
char * m_dirRoot; /* Path to directory for certs for control connection */
|
||||
|
||||
/* Queue for outgoing messages */
|
||||
SSMCollection *m_controlOutQ; /* Control msg queue: from readMsg thread
|
||||
to writeMsg thread */
|
||||
|
||||
CERTCertDBHandle *m_certdb;
|
||||
SECKEYKeyDBHandle *m_keydb;
|
||||
|
||||
/* Fields used for out-of-band password requests */
|
||||
SSMHashTable * m_passwdTable;
|
||||
PRMonitor * m_passwdLock;
|
||||
SSMHashTable * m_encrPasswdTable;
|
||||
PRMonitor * m_encrPasswdLock;
|
||||
PRInt32 m_waiting;
|
||||
|
||||
SSMHashTable *m_resourceDB;
|
||||
SSMHashTable *m_classRegistry;
|
||||
|
||||
SSMHashTable * m_resourceIdDB;
|
||||
SSMResourceID m_lastRID;
|
||||
SSMHashTable * m_certIdDB;
|
||||
SECItem * m_secAdvisorList;
|
||||
PRInt32 m_certNext;
|
||||
/* Data socket and port */
|
||||
PRFileDesc * m_dataSocket;
|
||||
PRIntn m_dataPort;
|
||||
|
||||
PRBool m_doesUI;
|
||||
|
||||
PrefSet* m_prefs;
|
||||
PRBool m_pkcs11Init;
|
||||
};
|
||||
|
||||
SSMStatus SSM_InitPolicyHandler(void);
|
||||
|
||||
SSMStatus SSMControlConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMControlConnection_Init(SSMControlConnection *res,
|
||||
SSMResourceType type,
|
||||
PRFileDesc *socket);
|
||||
SSMStatus SSMControlConnection_Shutdown(SSMResource *conn, SSMStatus status);
|
||||
SSMStatus SSMControlConnection_Destroy(SSMResource *res, PRBool doFree);
|
||||
SSMStatus SSMControlConnection_GetAttrIDs(SSMResource* res, SSMAttributeID** ids,
|
||||
PRIntn* count);
|
||||
SSMStatus SSMControlConnection_GetAttr(SSMResource *res, SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
void SSMControlConnection_Invariant(SSMControlConnection *conn);
|
||||
|
||||
SSMStatus SSMControlConnection_ProcessMessage(SSMControlConnection* control,
|
||||
SECItem* msg);
|
||||
void SSM_WriteCtrlThread(void * arg);
|
||||
void SSM_FrontEndThread(void * arg);
|
||||
void SSM_CertificateRenewalThread(void * arg);
|
||||
|
||||
SSMStatus SSMControlConnection_Authenticate(SSMConnection *arg, char *nonce);
|
||||
void SSMControlConnection_CertLookUp(SSMControlConnection * connection,
|
||||
void * arg, SSMResource ** res);
|
||||
|
||||
SSMStatus SSMControlConnection_SendUIEvent(SSMControlConnection *conn,
|
||||
char *command,
|
||||
char *baseRef,
|
||||
SSMResource *target, /* can pass NULL */
|
||||
char *otherParams /* can pass NULL */,
|
||||
CMTItem * clientContext /* can pass NULL */);
|
||||
|
||||
/*
|
||||
* NOTES
|
||||
* These functions save the pref change properly in memory and in client file.
|
||||
* They check first whether the value has changed and perform saving
|
||||
* operations.
|
||||
* These functions do not belong to the prefs API because these specifically
|
||||
* send the changes to the plugin. Once we have our own prefs library ready
|
||||
* and complete the migration, these functions should be called only when
|
||||
* application-specific prefs are saved back to client pref file.
|
||||
* Since these functions pack one item only, if you have to send a lot of
|
||||
* pref changes and performance is critical, it is not recommended to call
|
||||
* these functions repeatedly.
|
||||
*
|
||||
*/
|
||||
SSMStatus SSMControlConnection_SaveStringPref(SSMControlConnection* ctrl,
|
||||
char* key, char* value);
|
||||
SSMStatus SSMControlConnection_SaveBoolPref(SSMControlConnection* ctrl,
|
||||
char* key, PRBool value);
|
||||
SSMStatus SSMControlConnection_SaveIntPref(SSMControlConnection* ctrl,
|
||||
char* key, PRIntn value);
|
||||
|
||||
void SSMControlConnection_CertLookUp(SSMControlConnection * connection,
|
||||
void * arg, SSMResource ** res);
|
||||
void SSM_LockPasswdTable(SSMConnection * conn);
|
||||
SSMStatus SSM_UnlockPasswdTable(SSMConnection *conn);
|
||||
SSMStatus SSM_WaitPasswdTable(SSMConnection * conn);
|
||||
SSMStatus SSM_NotifyAllPasswdTable(SSMConnection * conn);
|
||||
|
||||
|
||||
SSMStatus SSMControlConnection_AddResource(SSMResource * res, SSMResourceID rid);
|
||||
|
||||
SSMStatus SSMControlConnection_GetResource(SSMControlConnection * connection,
|
||||
SSMResourceID rid,
|
||||
SSMResource ** res);
|
||||
SSMStatus SSMControlConnection_GetGlobalResourceID(SSMControlConnection
|
||||
*connection,
|
||||
SSMResource * res,
|
||||
SSMResourceID * rid);
|
||||
SSMResourceID SSMControlConnection_GenerateResourceID(SSMControlConnection *conn);
|
||||
SSMStatus SSM_GetControlConnection(SSMResourceID rid,
|
||||
SSMControlConnection **connection);
|
||||
SSMStatus SSMControlConnection_FormSubmitHandler(SSMResource* res,
|
||||
HTTPRequest* req);
|
||||
void SSMControlConnection_RecycleItem(SECItem* msg);
|
||||
SSMStatus SSMControlConnection_GenerateNonce(SSMControlConnection *conn);
|
||||
|
||||
/* from processmsg.c */
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessVerifyCertRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessImportCertRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessConserveRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessPickleRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessUnpickleRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessCertRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
PRStatus
|
||||
SSMControlConnection_ProcessKeygenTag(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessPKCS11Request(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessCRMFRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessMiscRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessFormSigningRequest(SSMControlConnection * ctrl,
|
||||
SECItem *msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessTLSRequest(SSMControlConnection * ctrl,
|
||||
SECItem *msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessProxyStepUpRequest(SSMControlConnection* ctrl,
|
||||
SECItem* msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessSecCfgRequest(SSMControlConnection * ctrl,
|
||||
SECItem *msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessGenKeyOldStyleToken(SSMControlConnection * ctrl,
|
||||
SECItem *msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessGenKeyPassword(SSMControlConnection * ctrl,
|
||||
SECItem *msg);
|
||||
SSMStatus
|
||||
SSM_CertCAImportCommandHandler2(HTTPRequest * req);
|
||||
void
|
||||
ssm_ShutdownNSS(SSMControlConnection *ctrl);
|
||||
|
||||
SSMStatus
|
||||
SSM_UseAsDefaultEmailIfNoneSet(SSMControlConnection *ctrl,
|
||||
CERTCertificate *cert, PRBool onFrontEndThread);
|
||||
|
||||
CERTCertList *
|
||||
SSMControlConnection_CreateCertListByNickname(SSMControlConnection * ctrl,
|
||||
char * nick, PRBool email);
|
||||
|
||||
SSMStatus
|
||||
ssmcontrolconnection_encode_err_reply(SECItem *msg, SSMStatus rv);
|
||||
SSMStatus
|
||||
ssmcontrolconnection_send_message_to_client(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
#endif /* __SSM_CTRLCONN_H__ */
|
439
security/psm/server/dataconn.c
Normal file
439
security/psm/server/dataconn.c
Normal file
@ -0,0 +1,439 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "connect.h"
|
||||
#include "dataconn.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "servimpl.h"
|
||||
#include "serv.h"
|
||||
#include "ssmerrs.h"
|
||||
|
||||
#define SSMCONNECTION(p) (&(p)->super)
|
||||
#define SSMRESOURCE(p) (&(p)->super.super)
|
||||
|
||||
/* How many milliseconds to wait for client input */
|
||||
#define SSM_READCLIENT_POKE_INTERVAL 30000
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMDataConnection *conn;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMDataConnection *) PR_CALLOC(sizeof(SSMDataConnection));
|
||||
if (!conn) goto loser;
|
||||
|
||||
rv = SSMDataConnection_Init(conn, (SSMControlConnection *) arg,
|
||||
SSM_RESTYPE_DATA_CONNECTION);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMDataConnection_Invariant(conn);
|
||||
|
||||
*res = SSMRESOURCE(conn);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMDataConnection_Init(SSMDataConnection *conn,
|
||||
SSMControlConnection *parent,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMResourceType parentType = RESOURCE_CLASS(parent);
|
||||
|
||||
PR_ASSERT(parent != NULL);
|
||||
PR_ASSERT((parentType == SSM_RESTYPE_CONTROL_CONNECTION) || (parentType == SSM_RESTYPE_CONNECTION));
|
||||
if (!parent) goto loser;
|
||||
rv = SSMConnection_Init(parent, SSMCONNECTION(conn), type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Initialize data shutdown queue. */
|
||||
conn->m_shutdownQ = SSM_NewCollection();
|
||||
if (conn->m_shutdownQ == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Hang our shutdown func. */
|
||||
SSMCONNECTION(conn)->m_auth_func = SSMDataConnection_Authenticate;
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMDataConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMDataConnection *conn = (SSMDataConnection *) res;
|
||||
|
||||
/* We should be shut down. */
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Drain and destroy the queue. */
|
||||
if (conn->m_shutdownQ) {
|
||||
ssm_DrainAndDestroyQueue(&(conn->m_shutdownQ));
|
||||
}
|
||||
|
||||
/* Destroy superclass fields. */
|
||||
SSMConnection_Destroy(&(conn->super.super), PR_FALSE);
|
||||
|
||||
/* Free the connection object if asked. */
|
||||
if (doFree)
|
||||
PR_DELETE(conn);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMDataConnection_Invariant(SSMDataConnection *conn)
|
||||
{
|
||||
if (conn)
|
||||
{
|
||||
SSMConnection_Invariant(&conn->super);
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn), SSM_RESTYPE_DATA_CONNECTION));
|
||||
PR_ASSERT(conn->m_shutdownQ != NULL);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMConnection_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 1) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_CONN_DATA_PENDING;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_CONN_DATA_PENDING:
|
||||
/* this is not used: will set it to zero for now */
|
||||
*(PRUint32*)value->u.numeric = (PRUint32)0;
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMConnection_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_SetupClientSocket(SSMDataConnection* conn)
|
||||
{
|
||||
SSMControlConnection* parent = NULL;
|
||||
char* pNonce;
|
||||
char* temp = NULL; /* for nonce verification */
|
||||
PRFileDesc* socket = NULL; /* client socket */
|
||||
PRNetAddr clientAddr;
|
||||
SSMStatus status = PR_FAILURE;
|
||||
PRIntn read;
|
||||
|
||||
PR_ASSERT(conn != NULL);
|
||||
|
||||
/* Allocate a nonce-sized chunk of memory to read into.
|
||||
(See below.) */
|
||||
parent = (SSMControlConnection*)(conn->super.m_parent);
|
||||
PR_ASSERT(parent != NULL);
|
||||
pNonce = parent->m_nonce;
|
||||
PR_ASSERT(pNonce != NULL);
|
||||
SSM_DEBUG("I think my parent's nonce is `%s'.\n", pNonce);
|
||||
|
||||
temp = (char*)PORT_ZAlloc(strlen(pNonce));
|
||||
|
||||
while ((socket == NULL) && (SSMRESOURCE(conn)->m_status == PR_SUCCESS)) {
|
||||
SSM_DEBUG("accepting next connect.\n");
|
||||
|
||||
/* Wait forever for a connection. (for now) */
|
||||
socket = PR_Accept(SSMRESOURCE(conn)->m_connection->m_dataSocket,
|
||||
&clientAddr, PR_INTERVAL_NO_TIMEOUT);
|
||||
SSM_DEBUG("accepted connection.\n");
|
||||
|
||||
if ((SSMRESOURCE(conn)->m_status != PR_SUCCESS) && socket) {
|
||||
/* May have gotten a socket, but we're shutting down.
|
||||
Close and zero out the socket. */
|
||||
PR_Close(socket);
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
socket = conn->m_clientSocket = NULL;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
if (socket && !SSM_SocketPeerCheck(socket, PR_FALSE))
|
||||
{
|
||||
/*
|
||||
Failed peer check. Close socket and listen again.
|
||||
### mwelch - Could have a denial of service attack here if
|
||||
someone keeps trying to connect to this port.
|
||||
*/
|
||||
PR_Close(socket);
|
||||
socket = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (socket) {
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
conn->m_clientSocket = socket;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
SSM_DEBUG("reading/verifying nonce.\n");
|
||||
status = PR_SUCCESS;
|
||||
|
||||
/* Read the nonce from the client. If we didn't get the right
|
||||
nonce, reject the connection. */
|
||||
if ((temp) && (pNonce != NULL)) {
|
||||
read = SSM_ReadThisMany(socket, temp, strlen(pNonce));
|
||||
if ((unsigned int)read != strlen(pNonce)) {
|
||||
status = PR_GetError();
|
||||
}
|
||||
}
|
||||
|
||||
if ((status != PR_SUCCESS) || (memcmp(temp, pNonce,
|
||||
strlen(pNonce)))) {
|
||||
#ifdef DEBUG
|
||||
char thing1[255];
|
||||
char thing2[255];
|
||||
|
||||
strncpy(thing1, temp, strlen(pNonce));
|
||||
strncpy(thing2, temp, strlen(pNonce));
|
||||
/* Bad nonce, no biscuit! Shut down connection
|
||||
and wait for another on the data port. */
|
||||
SSM_DEBUG("Bad nonce, no biscuit!\n");
|
||||
SSM_DEBUG("(`%s' != `%s')\n", thing1, thing2);
|
||||
#endif
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_Close(conn->m_clientSocket);
|
||||
conn->m_clientSocket = socket = NULL;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Tear everything down, didn't get a connection. */
|
||||
SSM_DEBUG("Shutdown during connection setup.\n");
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
SSM_DEBUG("Nonce is valid.\n");
|
||||
|
||||
/* We have a socket. Close the data port. */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
SSM_DEBUG("Socket is %ld.\n", socket);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
loser:
|
||||
if (temp != NULL) {
|
||||
PR_Free(temp);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_ReadFromSocket(SSMDataConnection* conn,
|
||||
PRInt32* read,
|
||||
char* buffer)
|
||||
{
|
||||
SSMStatus status;
|
||||
#if 0
|
||||
SSMStatus osStat;
|
||||
char statBuf[256];
|
||||
#endif
|
||||
|
||||
PR_ASSERT(conn != NULL);
|
||||
PR_ASSERT(buffer != NULL);
|
||||
|
||||
/* Attempt to read LINESIZE bytes from the socket. */
|
||||
do {
|
||||
SSM_DEBUG("Attempting to read %ld bytes.\n", *read);
|
||||
*read = PR_Recv(conn->m_clientSocket, buffer, *read, 0,
|
||||
PR_MillisecondsToInterval(SSM_READCLIENT_POKE_INTERVAL));
|
||||
if (*read < 0) {
|
||||
status = PR_GetError(); /* save status for later use */
|
||||
#if 0
|
||||
osStat = PR_GetOSError(); /* just for fun */
|
||||
PR_GetErrorText(statBuf);
|
||||
#endif
|
||||
}
|
||||
SSM_DEBUG("Got %ld bytes of data, status == %ld.\n", (long)(*read),
|
||||
(long)status);
|
||||
}
|
||||
while ((*read == -1) && (status == PR_IO_TIMEOUT_ERROR) &&
|
||||
SSMRESOURCE(conn)->m_status == PR_SUCCESS);
|
||||
|
||||
/* Don't mask an error if we got one, but set it if we didn't get any
|
||||
* data (because that indicates a socket closure).
|
||||
*/
|
||||
if ((*read < 0) && (status == PR_SUCCESS)) {
|
||||
status = PR_FAILURE;
|
||||
}
|
||||
else if (*read >= 0) {
|
||||
status = PR_SUCCESS; /* clear the error from when we waited */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Null terminate the buffer so that we can dump it. */
|
||||
if (*read >= 0) {
|
||||
buffer[*read] = '\0';
|
||||
}
|
||||
#endif
|
||||
if (*read > 0) {
|
||||
SSM_DEBUG("got %ld bytes of data: <%s>\n", *read, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_Shutdown(SSMResource *res, SSMStatus status)
|
||||
{
|
||||
SSMStatus rv, trv;
|
||||
PRThread *closer = PR_GetCurrentThread();
|
||||
|
||||
SSMDataConnection *conn = (SSMDataConnection *) res;
|
||||
/* SSMDataConnection_Invariant(conn); -- could be called from loser */
|
||||
|
||||
/* Lock down the resource before shutting it down */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
|
||||
/* If we're called from a service thread, clear that thread's
|
||||
place in the connection object so it doesn't get interrupted */
|
||||
if ((closer == conn->m_dataServiceThread) && (closer != NULL)) {
|
||||
conn->m_dataServiceThread = NULL;
|
||||
|
||||
/* Decrement living thread counter */
|
||||
SSMRESOURCE(conn)->m_threadCount--;
|
||||
}
|
||||
|
||||
/* shut down base class */
|
||||
rv = SSMConnection_Shutdown(res, status);
|
||||
|
||||
if ((SSMRESOURCE(conn)->m_status != PR_SUCCESS) &&
|
||||
(rv != SSM_ERR_ALREADY_SHUT_DOWN) &&
|
||||
(conn->m_clientSocket != NULL))
|
||||
{
|
||||
SSM_DEBUG("Shutting down data connection abnormally (rv == %d).\n",
|
||||
SSMRESOURCE(conn)->m_status);
|
||||
SSM_DEBUG("shutting down client socket.\n");
|
||||
PR_Shutdown(conn->m_clientSocket, PR_SHUTDOWN_SEND);
|
||||
|
||||
/* if this is called by a control thread, send a message to the
|
||||
* data service thread to shut down
|
||||
*/
|
||||
if ((closer != conn->m_dataServiceThread) &&
|
||||
(conn->m_shutdownQ != NULL)) {
|
||||
SSM_DEBUG("Send shutdown msg to data Q.\n");
|
||||
trv = SSM_SendQMessage(conn->m_shutdownQ, SSM_PRIORITY_SHUTDOWN,
|
||||
SSM_DATA_PROVIDER_SHUTDOWN, 0, NULL,
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
if (conn->m_dataServiceThread) {
|
||||
PR_Interrupt(conn->m_dataServiceThread);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the client sockets is/are now unused, close them. */
|
||||
if (SSMRESOURCE(conn)->m_threadCount == 0)
|
||||
{
|
||||
/* Close the client socket with linger */
|
||||
if (conn->m_clientSocket)
|
||||
{
|
||||
SSM_DEBUG("Close data socket.\n");
|
||||
trv = PR_Close(conn->m_clientSocket);
|
||||
conn->m_clientSocket = NULL;
|
||||
SSM_DEBUG("Closed client socket (rv == %d).\n",trv);
|
||||
}
|
||||
}
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
return rv; /* so that subclasses know to perform shutdown */
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_Authenticate(SSMConnection *arg, char *nonce)
|
||||
{
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SSMConnection *parent = arg->m_parent;
|
||||
|
||||
/* Parent has the nonce, so authenticate there. */
|
||||
if (parent &&
|
||||
SSM_IsAKindOf(&(parent->super), SSM_RESTYPE_CONTROL_CONNECTION))
|
||||
rv = SSMControlConnection_Authenticate(parent, nonce);
|
||||
|
||||
return rv;
|
||||
}
|
141
security/psm/server/dataconn.h
Normal file
141
security/psm/server/dataconn.h
Normal file
@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_DATACONN_H__
|
||||
#define __SSM_DATACONN_H__
|
||||
|
||||
#include "connect.h"
|
||||
#include "ctrlconn.h"
|
||||
|
||||
/*
|
||||
Cartman data connection/thread architecture:
|
||||
|
||||
Data connections are opened by the control connection in response
|
||||
to a Request {SSL,etc.} Data message. There is one thread per data
|
||||
connection that handles the data traffic, and there is one queue that
|
||||
receives a shutdown message from a control thread.
|
||||
|
||||
If an exception or other termination occurs on either side, the
|
||||
m_status flag is changed to the specific exception code, and sockets
|
||||
are closed on either side (after final thread shutdown).
|
||||
(### mwelch This has the effect of setting SO_LINGER on the outgoing
|
||||
data stream, is this an issue?)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Data connection objects.
|
||||
*/
|
||||
|
||||
typedef struct SSMDataConnection
|
||||
{
|
||||
SSMConnection super;
|
||||
|
||||
/*
|
||||
---------------------------------------------
|
||||
Data connection-specific fields - need to
|
||||
merge with control fields or do something more
|
||||
elegant in the long term.
|
||||
---------------------------------------------
|
||||
*/
|
||||
PRUint32 m_dataType; /* What type of service are we
|
||||
providing to client? */
|
||||
|
||||
PRThread* m_dataServiceThread; /* one and only data thread */
|
||||
|
||||
SSMCollection* m_shutdownQ; /* data queue that delivers a shutdown
|
||||
message to the data service thread */
|
||||
|
||||
PRFileDesc *m_clientSocket; /* Client socket */
|
||||
|
||||
PRBool m_sendResult; /* When this connection shuts down,
|
||||
send a result back to the client
|
||||
(usage depends on subclass) */
|
||||
} SSMDataConnection;
|
||||
|
||||
SSMStatus SSMDataConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMDataConnection_Init(SSMDataConnection *conn,
|
||||
SSMControlConnection *parent,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMDataConnection_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMDataConnection_Invariant(SSMDataConnection *conn);
|
||||
|
||||
SSMStatus SSMDataConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMDataConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMDataConnection_Shutdown(SSMResource *arg, SSMStatus status);
|
||||
SSMStatus SSMDataConnection_Authenticate(SSMConnection *arg, char *nonce);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSMDataConnection_SetupClientSocket()
|
||||
* Purpose: sets up the client data socket and authenticates the connection.
|
||||
* (blocking I/O)
|
||||
* Arguments and return values:
|
||||
* - conn: data connection object
|
||||
* - returns: PR_SUCCESS if successful, error code otherwise
|
||||
*/
|
||||
SSMStatus SSMDataConnection_SetupClientSocket(SSMDataConnection* conn);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSMDataConnection_ReadFromSocket()
|
||||
* Purpose: reads data from the client data socket and fill the buffer. When
|
||||
* particular write target threads read data from the data socket,
|
||||
* it is recommended that they use this function with the notable
|
||||
* exception of SSL connections.
|
||||
* Arguments and return values:
|
||||
* - conn: data connection object
|
||||
* - read: this is a value-result argument. It should be set to the data
|
||||
* chunk size. One should always use LINESIZE unless there is a
|
||||
* compelling reason to do otherwise. On return, this value will be
|
||||
* filled with the actual size of the data (or 0 if EOF or < 0 if
|
||||
* error).
|
||||
* - buffer: data buffer. The memory should have been allocated before this
|
||||
* function is called. The buffer size should be at least equal to
|
||||
* the read size (thus the reason for specifying read value upon
|
||||
* input).
|
||||
* - returns: PR_SUCCESS if successful, error code otherwise
|
||||
*
|
||||
* Note: this is a blocking I/O operation.
|
||||
*/
|
||||
SSMStatus SSMDataConnection_ReadFromSocket(SSMDataConnection* conn,
|
||||
PRInt32* read,
|
||||
char* buffer);
|
||||
|
||||
#endif
|
244
security/psm/server/frontend.c
Normal file
244
security/psm/server/frontend.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "ctrlconn.h"
|
||||
#include "dataconn.h"
|
||||
#include "sslconn.h"
|
||||
#include "p7cinfo.h"
|
||||
#include "hashconn.h"
|
||||
#include "servimpl.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "serv.h"
|
||||
#include "advisor.h"
|
||||
#include "ssmerrs.h"
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
#include "timebomb.h"
|
||||
#include "timebomb.c"
|
||||
#endif
|
||||
|
||||
/* The ONLY reason why we can use these macros for both control and
|
||||
data connections is that they inherit from the same superclass.
|
||||
Do NOT try this at home. */
|
||||
#define SSMCONNECTION(c) (&(c)->super)
|
||||
#define SSMRESOURCE(c) (&(c)->super.super)
|
||||
|
||||
extern long ssm_ctrl_count;
|
||||
|
||||
|
||||
/* This thread reads the control connection socket and
|
||||
* forwards messages to appropriate queues.
|
||||
*/
|
||||
|
||||
void SSM_FrontEndThread(void * arg)
|
||||
{
|
||||
PRFileDesc * socket = NULL;
|
||||
SECItem * message = NULL;
|
||||
SSMControlConnection * control = NULL;
|
||||
PRIntn read;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
char * passwd = NULL;
|
||||
char * tmp;
|
||||
PasswordReply reply;
|
||||
CMTMessageHeader header;
|
||||
|
||||
control = (SSMControlConnection *)arg;
|
||||
SSM_RegisterNewThread("ctrl frontend", (SSMResource *) arg);
|
||||
SSM_DEBUG("initializing.\n");
|
||||
if (!control || !control->m_socket)
|
||||
{
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
goto loser;
|
||||
}
|
||||
control->m_frontEndThread = PR_GetCurrentThread();
|
||||
socket = control->m_socket;
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
if (SSMTimeBombExpired)
|
||||
SSM_CartmanHasExpired(control);
|
||||
#endif
|
||||
|
||||
/* start a write thread for this connection */
|
||||
SSM_DEBUG("creating accompanying write thread.\n");
|
||||
control->m_writeThread = SSM_CreateThread(SSMRESOURCE(control),
|
||||
SSM_WriteCtrlThread);
|
||||
if (!control->m_writeThread)
|
||||
{
|
||||
rv = PR_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* initialize connection outgoing queue */
|
||||
SSM_DEBUG("Initialize OUT queue for control connection\n");
|
||||
SSM_SendQMessage(control->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
SSM_DATA_PROVIDER_OPEN, 0, NULL,
|
||||
PR_TRUE);
|
||||
|
||||
while ((SSMRESOURCE(control)->m_status == PR_SUCCESS)
|
||||
&& (rv == PR_SUCCESS))
|
||||
{
|
||||
/* read and process data here
|
||||
*/
|
||||
|
||||
SSM_DEBUG("waiting for new message from socket.\n");
|
||||
read = SSM_ReadThisMany(socket, &header, sizeof(CMTMessageHeader));
|
||||
if (read != sizeof(CMTMessageHeader))
|
||||
{
|
||||
SSM_DEBUG("Bytes read (%ld) != bytes expected (%ld). (hdr)\n",
|
||||
(long) read,
|
||||
(long) sizeof(CMTMessageHeader));
|
||||
rv = PR_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message = SSM_ConstructMessage(PR_ntohl(header.len));
|
||||
if (!message)
|
||||
{
|
||||
SSM_DEBUG("Missing message.\n");
|
||||
rv = PR_OUT_OF_MEMORY_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
message->type = (SECItemType) PR_ntohl(header.type);
|
||||
|
||||
/* Read the message body */
|
||||
SSM_DEBUG("reading %ld more from socket.\n", message->len);
|
||||
read = SSM_ReadThisMany(socket, (void *)message->data, message->len);
|
||||
if ((unsigned int) read != message->len)
|
||||
{
|
||||
SSM_DEBUG("Bytes read (%ld) != bytes expected (%ld). (msg)\n",
|
||||
(long) read,
|
||||
(long) message->len);
|
||||
rv = PR_GetError();
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* Message successfully received, now file it to appropriate queue
|
||||
*//*
|
||||
if ((message->type & SSM_CATEGORY_MASK) == SSM_EVENT_MESSAGE) {
|
||||
*/
|
||||
switch (message->type &SSM_CATEGORY_MASK) {
|
||||
case SSM_EVENT_MESSAGE:
|
||||
switch (message->type & SSM_TYPE_MASK) {
|
||||
case SSM_AUTH_EVENT:
|
||||
/* deal with authentication message */
|
||||
|
||||
/* Decode the the password reply message */
|
||||
if (CMT_DecodeMessage(PasswordReplyTemplate, &reply, (CMTItem*)message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the lock for the password hash table */
|
||||
SSM_LockPasswdTable((SSMConnection *) control);
|
||||
rv = SSM_HashRemove(control->m_passwdTable, reply.tokenID, (void **)&tmp);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("Passwd request for token %d hasn't been registered.\n",
|
||||
reply.tokenID);
|
||||
SSM_DEBUG("Drop the message, continue waiting...\n");
|
||||
PR_Free(passwd);
|
||||
passwd = NULL;
|
||||
goto done_auth;
|
||||
}
|
||||
if (reply.result != 0) {
|
||||
SSM_DEBUG("Error getting password %d.\n", reply.result);
|
||||
reply.passwd = (char*)SSM_CANCEL_PASSWORD;
|
||||
}
|
||||
|
||||
if (!reply.passwd) {
|
||||
/* user entered a zero length password, which is valid */
|
||||
reply.passwd = "";
|
||||
}
|
||||
|
||||
rv = SSM_HashInsert(control->m_passwdTable, reply.tokenID,
|
||||
reply.passwd);
|
||||
if (rv != PR_SUCCESS)
|
||||
SSM_DEBUG("%ld: can't enter passwd in hash table.\n", control);
|
||||
|
||||
passwd = NULL; /* passwd is now pointed to the hash table entry */
|
||||
/* notify all waiting threads that the password has arrived */
|
||||
SSM_DEBUG("%ld : notify password table that passwd is available\n",
|
||||
control);
|
||||
rv = SSM_NotifyAllPasswdTable((SSMConnection *)control);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("Error on NotifyAll on the password table:%d.\n",
|
||||
PR_GetError());
|
||||
goto done_auth;
|
||||
}
|
||||
done_auth:
|
||||
/* We are done, release the lock */
|
||||
SSM_UnlockPasswdTable((SSMConnection *)control);
|
||||
break;
|
||||
case SSM_FILE_PATH_EVENT:
|
||||
SSM_HandleFilePathReply(control, message);
|
||||
break;
|
||||
case SSM_PROMPT_EVENT:
|
||||
SSM_HandleUserPromptReply(control, message);
|
||||
break;
|
||||
#if 0
|
||||
case SSM_GET_JAVA_PRINCIPALS_EVENT:
|
||||
SSM_HandleGetJavaPrincipalsReply(control, message);
|
||||
break;
|
||||
#endif
|
||||
case SSM_MISC_EVENT:
|
||||
if ((message->type & SSM_SUBTYPE_MASK) == SSM_MISC_PUT_RNG_DATA)
|
||||
{
|
||||
/* Got fodder for the RNG. Seed it. */
|
||||
SSM_DEBUG("Got %ld bytes of RNG seed data.\n", message->len);
|
||||
rv = RNG_RandomUpdate(message->data, message->len)
|
||||
== SECSuccess ? SSM_SUCCESS : SSM_FAILURE;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* process the message */
|
||||
rv = SSMControlConnection_ProcessMessage(control, message);
|
||||
}
|
||||
|
||||
/* Free the message */
|
||||
SSM_FreeMessage(message);
|
||||
message = NULL;
|
||||
} /* end of the read-socket loop */
|
||||
loser:
|
||||
SSM_DEBUG("shutting down, status = %ld.\n", rv);
|
||||
if (control)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(control), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(control));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
413
security/psm/server/hashconn.c
Normal file
413
security/psm/server/hashconn.c
Normal file
@ -0,0 +1,413 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "hashconn.h"
|
||||
#include "dataconn.h"
|
||||
#include "serv.h"
|
||||
#include "servimpl.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "collectn.h"
|
||||
|
||||
/* Shorthand macros for inherited classes */
|
||||
#define SSMRESOURCE(sslconn) (&(sslconn)->super.super.super)
|
||||
#define SSMCONNECTION(sslconn) (&(sslconn)->super.super)
|
||||
#define SSMDATACONNECTION(sslconn) (&(sslconn)->super)
|
||||
|
||||
void SSMHashConnection_ServiceThread(void * arg);
|
||||
SSMStatus SSMHashConnection_StartHashing(SSMHashConnection *conn);
|
||||
SSMStatus SSMHashConnection_FinishHashing(SSMHashConnection *conn);
|
||||
|
||||
SSMStatus SSMHashConnection_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMHashConnection *conn;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMHashConnection *) PR_CALLOC(sizeof(SSMHashConnection));
|
||||
if (!conn) goto loser;
|
||||
|
||||
SSMRESOURCE(conn)->m_connection = connection;
|
||||
rv = SSMHashConnection_Init(conn, (SSMHashInitializer *) arg,
|
||||
SSM_RESTYPE_HASH_CONNECTION);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMHashConnection_Invariant(conn);
|
||||
|
||||
*res = SSMRESOURCE(conn);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv); /* force destroy */
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMHashConnection_Init(SSMHashConnection *conn,
|
||||
SSMHashInitializer *init,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMControlConnection *parent = init->m_parent;
|
||||
|
||||
rv = SSMDataConnection_Init(SSMDATACONNECTION(conn), parent, type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Add the hash type. */
|
||||
conn->m_type = init->m_hashtype;
|
||||
|
||||
/* Verify that the hash type is something we can work with. */
|
||||
SSMHashConnection_StartHashing(conn);
|
||||
rv = (conn->m_context) ? PR_SUCCESS : PR_INVALID_ARGUMENT_ERROR;
|
||||
SSMHashConnection_FinishHashing(conn);
|
||||
conn->m_resultLen = 0;
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Spin the service thread to set up the SSL connection. */
|
||||
SSM_DEBUG("Creating hash service thread.\n");
|
||||
|
||||
SSM_GetResourceReference(SSMRESOURCE(conn));
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread =
|
||||
SSM_CreateThread(SSMRESOURCE(conn),
|
||||
SSMHashConnection_ServiceThread);
|
||||
if (SSMDATACONNECTION(conn)->m_dataServiceThread == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMHashConnection_FinishHashing(SSMHashConnection *conn)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
/* If we have a context, end the hash. */
|
||||
if (conn->m_context)
|
||||
{
|
||||
HASH_End(conn->m_context, conn->m_result, &conn->m_resultLen,
|
||||
SSM_HASH_RESULT_LEN);
|
||||
|
||||
if (conn->m_resultLen == 0)
|
||||
rv = SSM_FAILURE;
|
||||
|
||||
HASH_Destroy(conn->m_context);
|
||||
conn->m_context = NULL;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMHashConnection_StartHashing(SSMHashConnection *conn)
|
||||
{
|
||||
PR_ASSERT(conn->m_context == NULL);
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
|
||||
if (conn->m_context)
|
||||
SSMHashConnection_FinishHashing(conn);
|
||||
conn->m_resultLen = 0;
|
||||
conn->m_context = HASH_Create(conn->m_type);
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
return (conn->m_context ? PR_SUCCESS : PR_FAILURE);
|
||||
}
|
||||
|
||||
SSMStatus SSMHashConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMHashConnection *conn = (SSMHashConnection *) res;
|
||||
|
||||
if (doFree)
|
||||
SSM_DEBUG("SSMHashConnection_Destroy called.\n");
|
||||
/* We should be shut down. */
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Destroy our fields. */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context)
|
||||
SSMHashConnection_FinishHashing(conn);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
/* Destroy superclass fields. */
|
||||
SSMDataConnection_Destroy(SSMRESOURCE(conn), PR_FALSE);
|
||||
|
||||
/* Free the connection object if asked. */
|
||||
if (doFree)
|
||||
PR_DELETE(conn);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMHashConnection_Invariant(SSMHashConnection *conn)
|
||||
{
|
||||
SSMDataConnection_Invariant(SSMDATACONNECTION(conn));
|
||||
/* our specific invariants */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
/* we should not be simultaneously hashed and hashing */
|
||||
if (conn->m_context)
|
||||
PR_ASSERT(conn->m_resultLen == 0);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMHashConnection_Shutdown(SSMResource *arg, SSMStatus status)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
PR_ASSERT(SSM_IsAKindOf(arg, SSM_RESTYPE_HASH_CONNECTION));
|
||||
|
||||
/* Call our superclass shutdown. Thread control is handled there. */
|
||||
rv = SSMDataConnection_Shutdown(arg, status);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Hashing is performed by a single service thread. This thread
|
||||
feeds data from the outgoing queue into the hash context.
|
||||
*/
|
||||
void SSMHashConnection_ServiceThread(void * arg)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMHashConnection * conn;
|
||||
SSMControlConnection *ctrl;
|
||||
SECItem *msg;
|
||||
PRIntn read;
|
||||
char buffer[LINESIZE+1] = {0};
|
||||
|
||||
|
||||
SSM_RegisterNewThread("hash service", (SSMResource *) arg);
|
||||
conn = (SSMHashConnection *)arg;
|
||||
SSM_DEBUG("initializing.\n");
|
||||
if (!arg)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread = PR_GetCurrentThread();
|
||||
|
||||
/* set up the client data socket and authenticate it with nonce */
|
||||
rv = SSMDataConnection_SetupClientSocket(SSMDATACONNECTION(conn));
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Start hashing. */
|
||||
SSM_DEBUG("creating hash context.\n");
|
||||
SSMHashConnection_StartHashing(conn);
|
||||
|
||||
/* Loop for as long as we have data. */
|
||||
while ((SSMRESOURCE(conn)->m_status == PR_SUCCESS) &&
|
||||
(SSM_Count(SSMDATACONNECTION(conn)->m_shutdownQ) == 0) &&
|
||||
(rv == PR_SUCCESS)) {
|
||||
read = LINESIZE; /* set the read size to the default line size */
|
||||
rv = SSMDataConnection_ReadFromSocket(SSMDATACONNECTION(conn),
|
||||
(PRInt32*)&read, buffer);
|
||||
|
||||
if (read > 0) {
|
||||
/* there is data, add it to hash */
|
||||
SSM_DEBUG("Received %ld bytes of data for hasher.\n", read);
|
||||
PR_ASSERT(conn->m_context);
|
||||
HASH_Update(conn->m_context, (unsigned char *) buffer, (unsigned int)read);
|
||||
}
|
||||
else {
|
||||
/* either EOF or an error condition */
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
SSM_DEBUG("Got shutdown msg.\n");
|
||||
|
||||
/* Lock the resource object, so that we know that attribute requests
|
||||
won't be pending while we work. */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
|
||||
/* SSM_ShutdownResource(SSMRESOURCE(conn), PR_SUCCESS);*/
|
||||
SSMHashConnection_FinishHashing(conn);
|
||||
|
||||
/* If we've been asked to return the result, do it now. */
|
||||
if (SSMDATACONNECTION(conn)->m_sendResult) {
|
||||
SSM_DEBUG("Responding to deferred hash result request.\n");
|
||||
|
||||
msg = (SECItem*)PORT_ZAlloc(sizeof(SECItem));
|
||||
PR_ASSERT(msg != NULL); /* need to have some preallocated
|
||||
failure to send */
|
||||
if (conn->m_result) {
|
||||
SSMAttributeValue value;
|
||||
GetAttribReply reply;
|
||||
|
||||
value.type = SSM_STRING_ATTRIBUTE;
|
||||
value.u.string.len = conn->m_resultLen;
|
||||
value.u.string.data = conn->m_result;
|
||||
msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE);
|
||||
reply.result = rv;
|
||||
reply.value = value;
|
||||
if (CMT_EncodeMessage(GetAttribReplyTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated a reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
value.u.string.data = NULL;
|
||||
SSM_DestroyAttrValue(&value, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
SingleNumMessage reply;
|
||||
|
||||
msg->type = (SECItemType) (SSM_REPLY_ERR_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE);
|
||||
reply.value = SSM_ERR_ATTRIBUTE_MISSING;
|
||||
if (CMT_EncodeMessage(GetAttribReplyTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated error reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
}
|
||||
/* Post this message to the parent's control queue
|
||||
for delivery back to the client. */
|
||||
ctrl = (SSMControlConnection*)SSMCONNECTION(conn)->m_parent;
|
||||
PR_ASSERT(SSM_IsAKindOf(&ctrl->super.super, SSM_RESTYPE_CONTROL_CONNECTION));
|
||||
rv = SSM_SendQMessage(ctrl->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
msg->type, msg->len,
|
||||
(char*)msg->data, PR_TRUE);
|
||||
SSM_FreeMessage(msg);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
loser:
|
||||
SSM_DEBUG("** Thread shutting down ** (%ld)\n", rv);
|
||||
if (conn != NULL) {
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMHashConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMDataConnection_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 1) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_HASHCONN_RESULT;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMHashConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMHashConnection *hc = (SSMHashConnection *) res;
|
||||
if (! hc)
|
||||
return PR_INVALID_ARGUMENT_ERROR;
|
||||
|
||||
SSMHashConnection_Invariant(hc);
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(hc));
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_HASHCONN_RESULT:
|
||||
if (hc->m_resultLen == 0)
|
||||
{
|
||||
/* Still waiting on hashing to finish.
|
||||
Set the flag which tells us to return the attribute
|
||||
when we finish. */
|
||||
SSMDATACONNECTION(hc)->m_sendResult = PR_TRUE;
|
||||
rv = SSM_ERR_DEFER_RESPONSE;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* XXX Fix this. Return the hash result in a string. */
|
||||
value->type = SSM_STRING_ATTRIBUTE;
|
||||
value->u.string.len = hc->m_resultLen;
|
||||
value->u.string.data = (unsigned char *) PR_CALLOC(hc->m_resultLen);
|
||||
if (value->u.string.data)
|
||||
memcpy(value->u.string.data, hc->m_result, hc->m_resultLen);
|
||||
else
|
||||
value->u.string.len = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMDataConnection_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
SSM_UnlockResource(SSMRESOURCE(hc));
|
||||
return rv;
|
||||
}
|
85
security/psm/server/hashconn.h
Normal file
85
security/psm/server/hashconn.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_HASHCONN_H__
|
||||
#define __SSM_HASHCONN_H__
|
||||
|
||||
#include "prerror.h"
|
||||
#include "sechash.h"
|
||||
|
||||
#include "ctrlconn.h"
|
||||
#include "dataconn.h"
|
||||
|
||||
#define SSM_HASH_RESULT_LEN 1024
|
||||
|
||||
/* Used to initialize an SSMHashConnection */
|
||||
typedef struct SSMHashInitializer
|
||||
{
|
||||
SSMControlConnection *m_parent;
|
||||
HASH_HashType m_hashtype;
|
||||
} SSMHashInitializer;
|
||||
|
||||
/*
|
||||
Hash connection object
|
||||
*/
|
||||
|
||||
typedef struct SSMHashConnection
|
||||
{
|
||||
SSMDataConnection super;
|
||||
|
||||
HASHContext *m_context;
|
||||
HASH_HashType m_type;
|
||||
PRUint32 m_resultLen;
|
||||
unsigned char m_result[SSM_HASH_RESULT_LEN];
|
||||
} SSMHashConnection;
|
||||
|
||||
SSMStatus SSMHashConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMHashConnection_Init(SSMHashConnection *conn,
|
||||
SSMHashInitializer *init,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMHashConnection_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMHashConnection_Invariant(SSMHashConnection *conn);
|
||||
|
||||
SSMStatus SSMHashConnection_Shutdown(SSMResource *arg, SSMStatus status);
|
||||
|
||||
SSMStatus SSMHashConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMHashConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
#endif
|
418
security/psm/server/hashtbl.c
Normal file
418
security/psm/server/hashtbl.c
Normal file
@ -0,0 +1,418 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
hashtbl.c -- hash tables for Cartman, specifically for use with
|
||||
resources (32-bit integer keys).
|
||||
*/
|
||||
|
||||
#include "hashtbl.h"
|
||||
|
||||
#define BUCKETNUM(key) ((key) & (HASH_NUM_BUCKETS-1))
|
||||
|
||||
/* SSMHashBucket support routines */
|
||||
|
||||
void ssmbucket_invariant(SSMHashBucket *bucket)
|
||||
{
|
||||
PR_ASSERT(bucket->m_size >= 0);
|
||||
PR_ASSERT(bucket->m_allocSize > 0);
|
||||
PR_ASSERT(bucket->m_size <= bucket->m_allocSize);
|
||||
PR_ASSERT(bucket->m_keys != NULL);
|
||||
PR_ASSERT(bucket->m_values != NULL);
|
||||
}
|
||||
|
||||
SSMStatus ssmbucket_remove(SSMHashBucket *bucket, PRIntn whichElem)
|
||||
{
|
||||
SSMHashKey *keyptr;
|
||||
void **valptr;
|
||||
PRIntn numToMove;
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
PR_ASSERT(whichElem < bucket->m_size);
|
||||
|
||||
|
||||
if (whichElem >= bucket->m_size) return PR_FAILURE;
|
||||
|
||||
keyptr = bucket->m_keys + whichElem;
|
||||
valptr = bucket->m_values + whichElem;
|
||||
numToMove = bucket->m_size - (whichElem + 1);
|
||||
memmove(keyptr, keyptr + 1, numToMove * sizeof(SSMHashKey));
|
||||
memmove(valptr, valptr + 1, numToMove * sizeof(void *));
|
||||
bucket->m_size--;
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRIntn ssmbucket_find(SSMHashBucket *bucket, SSMHashKey key)
|
||||
{
|
||||
PRIntn i;
|
||||
for(i=0;i<bucket->m_size; i++)
|
||||
{
|
||||
if (bucket->m_keys[i] == key)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSMStatus ssmbucket_grow(SSMHashBucket *bucket)
|
||||
{
|
||||
size_t newSize;
|
||||
SSMHashKey *newKeys = NULL;
|
||||
void **newValues = NULL;
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
|
||||
/* If we're growing, double the size */
|
||||
newSize = bucket->m_allocSize * 2;
|
||||
|
||||
/* realloc the memory. is this broken? */
|
||||
newKeys = (SSMHashKey *) PR_REALLOC(bucket->m_keys, newSize * sizeof(SSMHashKey));
|
||||
if (!newKeys) goto loser;
|
||||
|
||||
newValues = (void **) PR_REALLOC(bucket->m_values, newSize * sizeof(void *));
|
||||
if (!newValues) goto loser;
|
||||
|
||||
bucket->m_keys = newKeys;
|
||||
bucket->m_values = newValues;
|
||||
bucket->m_allocSize = newSize;
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (newKeys) PR_Free(newKeys);
|
||||
if (newValues) PR_Free(newValues);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus ssmbucket_add(SSMHashBucket *bucket, SSMHashKey key, void *value)
|
||||
{
|
||||
PRIntn newSize = bucket->m_size + 1;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
|
||||
if (bucket->m_size >= bucket->m_allocSize)
|
||||
rv = ssmbucket_grow(bucket);
|
||||
|
||||
if (rv == PR_SUCCESS)
|
||||
{
|
||||
bucket->m_keys[newSize-1] = key;
|
||||
bucket->m_values[newSize-1] = value;
|
||||
bucket->m_size = newSize;
|
||||
}
|
||||
|
||||
ssmbucket_invariant(bucket);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus ssmbucket_free(SSMHashBucket *bucket)
|
||||
{
|
||||
if (bucket)
|
||||
{
|
||||
if (bucket->m_keys)
|
||||
{
|
||||
PR_Free(bucket->m_keys);
|
||||
bucket->m_keys = NULL;
|
||||
}
|
||||
|
||||
if (bucket->m_values)
|
||||
{
|
||||
PR_Free(bucket->m_values);
|
||||
bucket->m_values = NULL;
|
||||
}
|
||||
|
||||
bucket->m_size = bucket->m_allocSize = 0;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus ssmbucket_init(SSMHashBucket *bucket)
|
||||
{
|
||||
bucket->m_keys = NULL;
|
||||
bucket->m_values = NULL;
|
||||
|
||||
bucket->m_keys = (SSMHashKey *) PR_CALLOC(2 * sizeof(SSMHashKey));
|
||||
if (!bucket->m_keys) goto loser;
|
||||
|
||||
bucket->m_values = (void **) PR_CALLOC(2 * sizeof(void *));
|
||||
if (!bucket->m_values) goto loser;
|
||||
|
||||
bucket->m_size = 0;
|
||||
bucket->m_allocSize = 2;
|
||||
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
ssmbucket_free(bucket);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashInsert
|
||||
** DESCRIPTION: Insert a new data item keyed by (key) into (hash).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash into which the item is to be inserted.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The item to be inserted.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashInsert(SSMHashTable *hash, SSMHashKey key, void *value)
|
||||
{
|
||||
PRIntn whichElem;
|
||||
if ((hash == NULL) || (value == NULL))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
PR_EnterMonitor(hash->m_hashLock);
|
||||
|
||||
/* If the key already exists, replace the value.
|
||||
Otherwise, add the new key/value. */
|
||||
whichElem = ssmbucket_find(&(hash->m_buckets[BUCKETNUM(key)]), key);
|
||||
if (whichElem >= 0)
|
||||
hash->m_buckets[BUCKETNUM(key)].m_values[whichElem] = value;
|
||||
else
|
||||
ssmbucket_add(&(hash->m_buckets[BUCKETNUM(key)]), key, value);
|
||||
PR_ExitMonitor(hash->m_hashLock);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus ssm_HashFindValue(SSMHashTable *hash, SSMHashKey key, void **value,
|
||||
PRBool removeElem)
|
||||
{
|
||||
PRIntn whichElem;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
|
||||
if ((hash == NULL) || (value == NULL))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
PR_EnterMonitor(hash->m_hashLock);
|
||||
|
||||
*value = NULL; /* in case we fail */
|
||||
|
||||
whichElem = ssmbucket_find(&(hash->m_buckets[BUCKETNUM(key)]), key);
|
||||
if (whichElem >= 0)
|
||||
{
|
||||
*value = hash->m_buckets[BUCKETNUM(key)].m_values[whichElem];
|
||||
if (removeElem)
|
||||
rv = ssmbucket_remove(&(hash->m_buckets[BUCKETNUM(key)]),
|
||||
whichElem);
|
||||
}
|
||||
else
|
||||
rv = PR_FAILURE;
|
||||
PR_ExitMonitor(hash->m_hashLock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashFind
|
||||
** DESCRIPTION: Get the item whose key is (key).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the item is to be retrieved.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The item to be returned. Set to NULL if no suitable
|
||||
** item is found.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashFind(SSMHashTable *hash, SSMHashKey key, void **value)
|
||||
{
|
||||
return ssm_HashFindValue(hash, key, value, PR_FALSE);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashRemove
|
||||
** DESCRIPTION: Remove from a hash the item whose key is (key).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the item is to be removed.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The value removed from the hash.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashRemove(SSMHashTable *hash, SSMHashKey key, void **value)
|
||||
{
|
||||
return ssm_HashFindValue(hash, key, value, PR_TRUE);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashKeys
|
||||
** DESCRIPTION: Get keys for all items stored in the hash.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the keys are to be returned.
|
||||
** keys
|
||||
** Returns an array of keys. The array is allocated using PR_Malloc.
|
||||
** numKeys
|
||||
** Returns the number of keys in the array.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashKeys(SSMHashTable *hash, SSMHashKey **keys, PRIntn *numKeys)
|
||||
{
|
||||
SSMHashKey *rkeys = NULL, *walk;
|
||||
PRIntn i, howMany;
|
||||
|
||||
/* in case we fail */
|
||||
*keys = NULL;
|
||||
*numKeys = 0;
|
||||
|
||||
if (hash == NULL)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EnterMonitor(hash->m_hashLock);
|
||||
rkeys = (SSMHashKey *) PR_CALLOC(hash->m_size * sizeof(SSMHashKey));
|
||||
if (!rkeys)
|
||||
return PR_FAILURE;
|
||||
|
||||
/* Walk through all the buckets, grabbing their keys. */
|
||||
walk = rkeys;
|
||||
for(i=0;i<HASH_NUM_BUCKETS;i++)
|
||||
{
|
||||
howMany = hash->m_buckets[i].m_size;
|
||||
(void) memcpy(walk, hash->m_buckets[i].m_keys,
|
||||
hash->m_buckets[i].m_size * sizeof(SSMHashKey));
|
||||
walk += howMany;
|
||||
}
|
||||
PR_ExitMonitor(hash->m_hashLock);
|
||||
|
||||
*keys = rkeys;
|
||||
*numKeys = hash->m_size;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashDestroy
|
||||
** DESCRIPTION: Destroy a hash. Items in the hash are not freed.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash to be destroyed.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashDestroy(SSMHashTable *hash)
|
||||
{
|
||||
if (hash)
|
||||
{
|
||||
PRIntn i;
|
||||
for (i=0;i<HASH_NUM_BUCKETS;i++)
|
||||
ssmbucket_free(&(hash->m_buckets[i]));
|
||||
PR_DestroyMonitor(hash->m_hashLock);
|
||||
|
||||
PR_Free(hash);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashCreate
|
||||
** DESCRIPTION: Create and initialize a hash.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** Returns the newly created hash.
|
||||
** RETURNS:
|
||||
** PR_SUCCESS on success.
|
||||
** PR_FAILURE on failure.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashCreate(SSMHashTable **hash)
|
||||
{
|
||||
PRIntn i;
|
||||
SSMHashTable *rhash;
|
||||
|
||||
*hash = NULL; /* in case we fail */
|
||||
|
||||
rhash = (SSMHashTable *) PR_CALLOC(sizeof(SSMHashTable));
|
||||
if (!rhash) goto loser;
|
||||
for(i=0;i<HASH_NUM_BUCKETS;i++)
|
||||
{
|
||||
if (ssmbucket_init(&(rhash->m_buckets[i])))
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rhash->m_hashLock = PR_NewMonitor();
|
||||
if (!rhash->m_hashLock)
|
||||
goto loser;
|
||||
*hash = rhash;
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rhash)
|
||||
SSM_HashDestroy(rhash);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus SSM_HashCount(SSMHashTable *hash, PRIntn *numItems)
|
||||
{
|
||||
*numItems = 0; /* in case we fail */
|
||||
|
||||
if (hash == NULL)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
*numItems = hash->m_size;
|
||||
return PR_SUCCESS;
|
||||
}
|
192
security/psm/server/hashtbl.h
Normal file
192
security/psm/server/hashtbl.h
Normal file
@ -0,0 +1,192 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __SSM_HASHTBL_H__
|
||||
#define __SSM_HASHTBL_H__
|
||||
|
||||
#include "nspr.h"
|
||||
#include "prtypes.h"
|
||||
#include "prmem.h"
|
||||
#include "seccomon.h"
|
||||
#include "secitem.h"
|
||||
#include "ssmdefs.h"
|
||||
|
||||
/* It's a cheap method of hashing; we use the lower HASH_USE_LOW_BITS
|
||||
bits of the key to determine what bucket it fits in.
|
||||
Oh, what a hack. */
|
||||
#define HASH_USE_LOW_BITS 4
|
||||
#define HASH_NUM_BUCKETS (1 << HASH_USE_LOW_BITS)
|
||||
|
||||
typedef PRInt32 SSMHashKey;
|
||||
|
||||
struct _ssm_hashbucket
|
||||
{
|
||||
SSMHashKey *m_keys;
|
||||
void **m_values;
|
||||
PRIntn m_size;
|
||||
PRIntn m_allocSize;
|
||||
};
|
||||
|
||||
typedef struct _ssm_hashbucket SSMHashBucket;
|
||||
|
||||
struct _ssm_hashtbl
|
||||
{
|
||||
SSMHashBucket m_buckets[HASH_NUM_BUCKETS];
|
||||
PRIntn m_size;
|
||||
PRMonitor * m_hashLock;
|
||||
};
|
||||
|
||||
typedef struct _ssm_hashtbl SSMHashTable;
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashInsert
|
||||
** DESCRIPTION: Insert a new data item keyed by (key) into (hash).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash into which the item is to be inserted.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The item to be inserted.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashInsert(SSMHashTable *hash, SSMHashKey key, void *value);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashFind
|
||||
** DESCRIPTION: Get the item whose key is (key).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the item is to be retrieved.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The item to be returned. Set to NULL if no suitable
|
||||
** item is found.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashFind(SSMHashTable *hash, SSMHashKey key, void **value);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashRemove
|
||||
** DESCRIPTION: Remove from a hash the item whose key is (key).
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the item is to be removed.
|
||||
** key
|
||||
** The key used to store the item.
|
||||
** value
|
||||
** The value removed from the hash.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashRemove(SSMHashTable *hash, SSMHashKey key, void **value);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashKeys
|
||||
** DESCRIPTION: Get keys for all items stored in the hash.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash from which the keys are to be returned.
|
||||
** keys
|
||||
** Returns an array of keys. The array is allocated using PR_Malloc.
|
||||
** numKeys
|
||||
** Returns the number of keys in the array.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashKeys(SSMHashTable *hash, SSMHashKey **keys, PRIntn *numKeys);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashCount
|
||||
** DESCRIPTION: Returns a count of the number of items in the hash.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash to be counted.
|
||||
** numItems
|
||||
** Returns the number of items in the hash.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashCount(SSMHashTable *hash, PRIntn *numItems);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashDestroy
|
||||
** DESCRIPTION: Destroy a hash. Items in the hash are not freed.
|
||||
** INPUTS:
|
||||
** hash
|
||||
** The hash to be destroyed.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashDestroy(SSMHashTable *hash);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_HashCreate
|
||||
** DESCRIPTION: Create and initialize a hash.
|
||||
p** INPUTS:
|
||||
** hash
|
||||
** Returns the newly created hash.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_HashCreate(SSMHashTable **hash);
|
||||
|
||||
|
||||
#endif /* __SSM_HASHTBL_H__ */
|
138
security/psm/server/keyres.c
Normal file
138
security/psm/server/keyres.c
Normal file
@ -0,0 +1,138 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "serv.h"
|
||||
#include "kgenctxt.h"
|
||||
#include "pk11func.h"
|
||||
|
||||
#define SSMRESOURCE(object) (&(object)->super)
|
||||
|
||||
SSMStatus
|
||||
SSMKeyPair_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMKeyPair *keyPair = NULL;
|
||||
SSMKeyPairArg *keyPairArg = (SSMKeyPairArg*)arg;
|
||||
SSMStatus rv;
|
||||
|
||||
keyPair = SSM_ZNEW(SSMKeyPair);
|
||||
if (keyPair == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSMKeyPair_Init(keyPair, connection, SSM_RESTYPE_KEY_PAIR,
|
||||
keyPairArg->keyGenContext);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
*res = SSMRESOURCE(keyPair);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (keyPair != NULL) {
|
||||
SSM_FreeResource (SSMRESOURCE(keyPair));
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMKeyPair_Init(SSMKeyPair *inKeyPair, SSMControlConnection *connection,
|
||||
SSMResourceType type, SSMKeyGenContext *keyGenContext)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
rv = SSMResource_Init(connection, &inKeyPair->super, type);
|
||||
inKeyPair->m_KeyGenContext = keyGenContext;
|
||||
inKeyPair->m_KeyGenType = invalidKeyGen;
|
||||
SSM_ClientGetResourceReference(SSMRESOURCE(inKeyPair), NULL);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSMKeyPair_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMKeyPair *keyPair = (SSMKeyPair*)res;
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(keyPair));
|
||||
if (keyPair->m_PubKey) {
|
||||
SECKEY_DestroyPublicKey(keyPair->m_PubKey);
|
||||
}
|
||||
if (keyPair->m_PrivKey) {
|
||||
SECKEY_DestroyPrivateKey(keyPair->m_PrivKey);
|
||||
}
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(keyPair));
|
||||
SSMResource_Destroy(SSMRESOURCE(keyPair), PR_FALSE);
|
||||
if (doFree) {
|
||||
PORT_Free(keyPair);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMKeyPair_SetKeyGenType(SSMKeyPair *inKeyPair,
|
||||
SSMKeyGenType inKeyGenType)
|
||||
{
|
||||
if (inKeyPair->m_KeyGenType != invalidKeyGen) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
inKeyPair->m_KeyGenType = inKeyGenType;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMKeyPair_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMKeyPair *keyPair = (SSMKeyPair*)res;
|
||||
SSMStatus rv;
|
||||
|
||||
PR_ASSERT(SSM_IsAKindOf(res, SSM_RESTYPE_KEY_PAIR));
|
||||
switch(attrID) {
|
||||
case SSM_FID_KEYPAIR_KEY_GEN_TYPE:
|
||||
SSM_DEBUG("Setting the key gen type to %d.\n", value->u.numeric);
|
||||
if (value->type != SSM_NUMERIC_ATTRIBUTE) {
|
||||
rv = PR_FAILURE;
|
||||
break;
|
||||
}
|
||||
rv = SSMKeyPair_SetKeyGenType(keyPair, (SSMKeyGenType)value->u.numeric);
|
||||
break;
|
||||
default:
|
||||
SSM_DEBUG("Got unknown KeyPair Set Attr request %d.\n", attrID);
|
||||
rv = PR_FAILURE;
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
117
security/psm/server/keyres.h
Normal file
117
security/psm/server/keyres.h
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _KEYRES_H_
|
||||
#define _KEYRES_H_
|
||||
#include "resource.h"
|
||||
#include "key.h"
|
||||
#include "ctrlconn.h"
|
||||
|
||||
/*
|
||||
* FUNCTION: SSM_GenerateKeyPairs
|
||||
* INPUTS:
|
||||
* msg
|
||||
* The message sent by the client requesting the key generation.
|
||||
* destID
|
||||
* A pointer to pre-allocated memory where the funciton can place
|
||||
* a copy of the resource id to associate with the newly generated
|
||||
* key pair.
|
||||
* NOTES:
|
||||
* This function takes a key pair generation method message and performs the
|
||||
* actual key generation.
|
||||
*
|
||||
* RETURN:
|
||||
* PRSuccess if the key generation is successfull. Any other return value
|
||||
* indicates an error while trying to generate the key pair.
|
||||
*/
|
||||
extern SSMStatus SSM_GenerateKeyPair(SECItem *msg, SSMResourceID *destID);
|
||||
|
||||
/* Forward declare this structure so that builds will work.
|
||||
* Unfortunately, there is a circular dependency here.
|
||||
*/
|
||||
typedef struct SSMKeyGenContext SSMKeyGenContext;
|
||||
|
||||
/* Now we begin to define the KeyPair class */
|
||||
typedef struct SSMKeyPair {
|
||||
SSMResource super;
|
||||
|
||||
SECKEYPublicKey *m_PubKey;
|
||||
SECKEYPrivateKey *m_PrivKey;
|
||||
SSMKeyGenContext *m_KeyGenContext;
|
||||
SSMKeyGenType m_KeyGenType;
|
||||
} SSMKeyPair;
|
||||
|
||||
/*
|
||||
* This structure should be passed as the argument when creating
|
||||
* a key pair.
|
||||
*/
|
||||
|
||||
typedef struct SSMKeyPairArgStr {
|
||||
SSMKeyGenContext *keyGenContext;
|
||||
} SSMKeyPairArg;
|
||||
|
||||
/*
|
||||
* FUNCTION: SSMKeyPair_Create
|
||||
* INPUTS:
|
||||
* arg
|
||||
* An opaque pointer that gets passed while creation is taking place
|
||||
* within the resource code.
|
||||
* res
|
||||
* A pointer to a pointer where a copy of the pointer to the instatiated
|
||||
* class can be placed.
|
||||
* NOTES:
|
||||
* This is the constructor "method" the resource builder will call when
|
||||
* instatiating a key pair class.
|
||||
*
|
||||
* RETURN:
|
||||
* PRSuccess if creation was successful. In this case, a valid pointer
|
||||
* to an SSMResource will be placed at *res.
|
||||
* Any other return value indicates failure and the value at *res should
|
||||
* be ignored.
|
||||
*/
|
||||
extern SSMStatus SSMKeyPair_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
|
||||
extern SSMStatus SSMKeyPair_Init(SSMKeyPair *inKeyPair,
|
||||
SSMControlConnection *conn,
|
||||
SSMResourceType type,
|
||||
SSMKeyGenContext *keyGenContext);
|
||||
|
||||
extern SSMStatus
|
||||
SSMKeyPair_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
extern SSMStatus SSMKeyPair_Destroy(SSMResource *res, PRBool doFree);
|
||||
|
||||
#endif /* _KEYRES_H_ */
|
1214
security/psm/server/kgenctxt.c
Normal file
1214
security/psm/server/kgenctxt.c
Normal file
File diff suppressed because it is too large
Load Diff
189
security/psm/server/kgenctxt.h
Normal file
189
security/psm/server/kgenctxt.h
Normal file
@ -0,0 +1,189 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _KGENCTXT_H_
|
||||
#define _KGENCTXT_H_
|
||||
#include "resource.h"
|
||||
#include "keyres.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "secmodti.h"
|
||||
#include "minihttp.h"
|
||||
|
||||
typedef enum {
|
||||
SSM_CRMF_KEYGEN = (PRInt32) 1,
|
||||
SSM_OLD_STYLE_KEYGEN
|
||||
} SSMKeyGenContextType;
|
||||
|
||||
/* Parameters used to create a key gen context */
|
||||
typedef struct SSMKeyGenContextCreateArg
|
||||
{
|
||||
SSMControlConnection *parent;
|
||||
SSMKeyGenContextType type;
|
||||
CMTItem *param;
|
||||
} SSMKeyGenContextCreateArg;
|
||||
|
||||
typedef struct SSMKeyGenParams
|
||||
{
|
||||
PRUint32 slotID;
|
||||
PRUint32 keyGenMechanism;
|
||||
SSMKeyPair *kp;
|
||||
void *actualParams;
|
||||
} SSMKeyGenParams;
|
||||
|
||||
/*
|
||||
Key generation context. This object helps transactionalize
|
||||
the generation of one or more key pairs for new certificates.
|
||||
|
||||
This object has associated with it an incoming queue for key generation
|
||||
and flush requests, and a worker thread to do the key generation.
|
||||
*/
|
||||
struct SSMKeyGenContext
|
||||
{
|
||||
SSMResource super;
|
||||
|
||||
/* Control connection which created us (and to whom we send
|
||||
completion responses */
|
||||
SSMControlConnection *m_parent;
|
||||
|
||||
/* Context is used for CRMF or old-style keygen */
|
||||
SSMKeyGenContextType m_ctxtype;
|
||||
|
||||
/* Queue for messages from control connection dispatcher */
|
||||
SSMCollection *m_incomingQ;
|
||||
|
||||
/* Thread which processes keygen requests. */
|
||||
PRThread *m_serviceThread;
|
||||
|
||||
/* Slot for a token used to generate keys. */
|
||||
PK11SlotInfo * slot;
|
||||
char *m_slotName;
|
||||
PRBool m_disableEscrowWarning;
|
||||
|
||||
/* UI information for slot selection. */
|
||||
PRMonitor *slotSelectLock;
|
||||
PRBool slotUIWaiting;
|
||||
PRBool slotUIComplete;
|
||||
|
||||
/* key exchange mechanism */
|
||||
PRUint32 mech;
|
||||
|
||||
/* public key string, for use with KEYGEN tag */
|
||||
char * keystring;
|
||||
|
||||
/* The number of requests we've completed. */
|
||||
PRUint32 m_count;
|
||||
SSMKeyGenParams **m_keyGens; /* We will finish these up
|
||||
* once we get the Finish Key Gen message
|
||||
*/
|
||||
CERTCertificate *m_eaCert;
|
||||
PRInt32 m_numKeyGens;
|
||||
PRInt32 m_allocKeyGens;
|
||||
PRBool m_userCancel;
|
||||
CMTItem m_context;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SSM_KEYGEN_CXT_MESSAGE_NONE = (PRIntn) 0,
|
||||
SSM_KEYGEN_CXT_MESSAGE_DATA_PROVIDER_OPEN = SSM_DATA_PROVIDER_OPEN,
|
||||
SSM_KEYGEN_CXT_MESSAGE_DATA_PROVIDER_SHUTDOWN = SSM_DATA_PROVIDER_SHUTDOWN,
|
||||
SSM_KEYGEN_CXT_MESSAGE_GEN_KEY = SSM_REQUEST_MESSAGE |
|
||||
SSM_PKCS11_ACTION | SSM_CREATE_KEY_PAIR,
|
||||
SSM_KEYGEN_CXT_MESSAGE_ESCROW_WARNING
|
||||
} SSMKeyGenContextQMessages;
|
||||
|
||||
/* The parameter passed as data when sending a message
|
||||
* for ESCROW_WARNING
|
||||
*/
|
||||
typedef struct SSMEscrowWarnParam
|
||||
{
|
||||
CERTCertificate *escrowCA;
|
||||
} SSMEscrowWarnParam;
|
||||
|
||||
SSMStatus SSMKeyGenContext_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMKeyGenContext_Init(SSMKeyGenContext *ct,
|
||||
SSMKeyGenContextCreateArg *arg,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMKeyGenContext_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMKeyGenContext_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMKeyGenContext_Destroy(SSMResource *res, PRBool doFree);
|
||||
SSMStatus SSMKeyGenContext_Shutdown(SSMResource *res, SSMStatus status);
|
||||
SSMStatus SSMKeyGenContext_SetStatus(SSMKeyGenContext *ct, SSMStatus s);
|
||||
SSMStatus SSMKeyGenContext_NewKeyPair(SSMKeyGenContext *ct,
|
||||
SSMKeyPair **kp,
|
||||
SECItem *msg);
|
||||
SSMStatus SSMKeyGenContext_Print(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParams,
|
||||
char ** value,
|
||||
char **resultStr);
|
||||
SSMStatus SSMKeyGenContext_FormSubmitHandler(SSMResource * res,
|
||||
HTTPRequest * req);
|
||||
|
||||
|
||||
void SSMKeyGenContext_Invariant(SSMKeyGenContext *ct);
|
||||
|
||||
SSMStatus SSMKeyGenContext_FinishGeneratingAllKeyPairs(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
|
||||
SSMStatus SSMKeyGenContext_BeginGeneratingKeyPair(SSMControlConnection * ctrl,
|
||||
SECItem *msg,
|
||||
SSMResourceID *destID);
|
||||
|
||||
void SSMKeyGenContext_CancelKeyGen(SSMKeyGenContext *ct);
|
||||
|
||||
|
||||
/* Get a slot to perform keygen :
|
||||
* returns SSM_SUCCESS if the slot is available, stored in keyctxt,
|
||||
* or SSM_ERR_DEFER_RESPONSE if need to wait for user response,
|
||||
* SSM_FAILURE on failure.
|
||||
*/
|
||||
struct SSMTextGenContext;
|
||||
struct HTTPRequest;
|
||||
SSMStatus SSMKeyGenContext_GetSlot(SSMKeyGenContext * keyctxt,
|
||||
CK_MECHANISM_TYPE mechanism);
|
||||
SSMStatus SSMTokenUI_KeywordHandler(struct SSMTextGenContext * cx);
|
||||
SSMStatus SSMTokenUI_CommandHandler(struct HTTPRequest * req);
|
||||
SSMStatus SSMTokenUI_GetNames(SSMResource * res, PRBool start, char ** name);
|
||||
|
||||
CK_MECHANISM_TYPE
|
||||
SSMKeyGenContext_GenMechToAlgMech(CK_MECHANISM_TYPE mechanism);
|
||||
|
||||
#endif /* _KGENCTXT_H_ */
|
65
security/psm/server/macshell.h
Normal file
65
security/psm/server/macshell.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
// ===========================================================================
|
||||
// CCompleteApp.h ©1994-1998 Metrowerks Inc. All rights reserved.
|
||||
// ===========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PP_Prefix.h>
|
||||
#include <LApplication.h>
|
||||
|
||||
|
||||
class CBasicApp : public PP_PowerPlant::LApplication {
|
||||
|
||||
public:
|
||||
CBasicApp(); // constructor registers PPobs
|
||||
virtual ~CBasicApp(); // stub destructor
|
||||
|
||||
|
||||
// this overriding method handles application commands
|
||||
virtual Boolean ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam);
|
||||
|
||||
|
||||
// this overriding method returns the status of menu items
|
||||
virtual void FindCommandStatus(PP_PowerPlant::CommandT inCommand,
|
||||
Boolean &outEnabled, Boolean &outUsesMark,
|
||||
PP_PowerPlant::Char16 &outMark, Str255 outName);
|
||||
protected:
|
||||
|
||||
virtual void StartUp(); // override startup functions
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern CBasicApp *gTheApp;
|
611
security/psm/server/main.c
Normal file
611
security/psm/server/main.c
Normal file
@ -0,0 +1,611 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "serv.h"
|
||||
#include "secport.h"
|
||||
#include "dataconn.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "minihttp.h"
|
||||
#include "ciferfam.h"
|
||||
#include "secmime.h"
|
||||
#include "messages.h"
|
||||
#include "textgen.h"
|
||||
#include "oldfunc.h"
|
||||
#include "nss.h"
|
||||
#include "p12plcy.h"
|
||||
#include "nlslayer.h"
|
||||
|
||||
void SSM_InitLogging(void);
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
#include "timebomb.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <wtypes.h>
|
||||
#include <winreg.h>
|
||||
#include <winerror.h>
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef SIG_ERR
|
||||
#define SIG_ERR -1
|
||||
#endif /*SIG_ERR*/
|
||||
|
||||
#endif /*XP_UNIX*/
|
||||
|
||||
#define POLICY_TYPE_INDEX 0
|
||||
|
||||
SSMCollection * connections = NULL;
|
||||
SSMHashTable * tokenList = NULL;
|
||||
PRMonitor * tokenLock = NULL;
|
||||
SSMHashTable * ctrlConnections = NULL;
|
||||
|
||||
SSMPolicyType policyType = ssmDomestic;
|
||||
|
||||
/*
|
||||
* The following is a quick write of enabling various ciphers. This code is
|
||||
* essentially moved from the server core code. Eventually we will need to
|
||||
* place this data and functionality in a more modular way.
|
||||
*/
|
||||
#define SSM_POLICY_END 0 /* end of table */
|
||||
#define SSM_POLICY_SSL 1 /* SSL ciphersuites: not really used */
|
||||
#define SSM_POLICY_PK12 2 /* PKCS #12 ciphersuites */
|
||||
#define SSM_POLICY_SMIME 3 /* S/MIME ciphersuites */
|
||||
|
||||
typedef struct {
|
||||
PRInt32 policy;
|
||||
PRInt32 key;
|
||||
PRInt32 value;
|
||||
} SSMPolicyEntry;
|
||||
|
||||
static SSMPolicyEntry ssmPK12PolicyTable[] =
|
||||
{
|
||||
{SSM_POLICY_PK12, PKCS12_RC4_40, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_PK12, PKCS12_RC4_128, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_PK12, PKCS12_RC2_CBC_40, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_PK12, PKCS12_RC2_CBC_128, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_PK12, PKCS12_DES_56, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_PK12, PKCS12_DES_EDE3_168, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_END, 0, 0}
|
||||
};
|
||||
|
||||
static SSMPolicyEntry ssmSMIMEPolicyTable[] =
|
||||
{
|
||||
{SSM_POLICY_SMIME, SMIME_RC2_CBC_40, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_RC2_CBC_64, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_RC2_CBC_128, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_DES_CBC_56, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_DES_EDE3_168, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_40, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_64, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_SMIME, SMIME_RC5PAD_64_16_128, (PRInt32)PR_TRUE},
|
||||
{SSM_POLICY_END, 0, 0}
|
||||
};
|
||||
|
||||
static SSMStatus SSM_InstallPK12Policy(void)
|
||||
{
|
||||
const SSMPolicyEntry* entry = ssmPK12PolicyTable;
|
||||
int i;
|
||||
|
||||
for (i = 0; entry[i].policy != SSM_POLICY_END; i++) {
|
||||
if (SEC_PKCS12EnableCipher(entry[i].key, entry[i].value) !=
|
||||
SECSuccess) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
}
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
||||
static SSMStatus SSM_InstallSMIMEPolicy(void)
|
||||
{
|
||||
const SSMPolicyEntry* entry = ssmSMIMEPolicyTable;
|
||||
int i;
|
||||
|
||||
for (i = 0; entry[i].policy != SSM_POLICY_END; i++) {
|
||||
if (SECMIME_SetPolicy(entry[i].key, entry[i].value) != SECSuccess) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
}
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX sjlee: we don't need to do a similar thing for SSL as we can call an
|
||||
* NSS function to do it
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This function is required by svrplcy to set the
|
||||
* utility policy. This will tell us what kind of
|
||||
* policy we are running.
|
||||
*/
|
||||
SECStatus Utility_SetPolicy(long which, int policy)
|
||||
{
|
||||
if (which == POLICY_TYPE_INDEX) {
|
||||
switch (policy) {
|
||||
case SVRPLCYDomestic:
|
||||
policyType = ssmDomestic;
|
||||
break;
|
||||
case SVRPLCYExport:
|
||||
policyType = ssmExport;
|
||||
break;
|
||||
case SVRPLCYFrance:
|
||||
policyType = ssmFrance;
|
||||
break;
|
||||
default:
|
||||
/* This is an unknown policy type. */
|
||||
PR_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SSM_SetPolicy(void)
|
||||
{
|
||||
#if 0
|
||||
SVRPLCY_InstallSSLPolicy();
|
||||
SVRPLCY_InstallPK12Policy();
|
||||
SVRPLCY_InstallSMIMEPolicy();
|
||||
SVRPLCY_InstallUtilityPolicy();
|
||||
#else
|
||||
/* Always domestic policy now */
|
||||
NSS_SetDomesticPolicy();
|
||||
SSM_InstallPK12Policy();
|
||||
SSM_InstallSMIMEPolicy();
|
||||
#endif
|
||||
}
|
||||
|
||||
SSMPolicyType
|
||||
SSM_GetPolicy(void)
|
||||
{
|
||||
return policyType;
|
||||
}
|
||||
|
||||
static void
|
||||
enable_SMIME_cipher_prefs(void)
|
||||
{
|
||||
SSMPolicyType policy;
|
||||
|
||||
policy = SSM_GetPolicy();
|
||||
|
||||
switch (policy)
|
||||
{
|
||||
case ssmDomestic:
|
||||
SECMIME_EnableCipher(SMIME_DES_EDE3_168, 1);
|
||||
SECMIME_EnableCipher(SMIME_RC2_CBC_128, 1);
|
||||
SECMIME_EnableCipher(SMIME_RC2_CBC_64, 1);
|
||||
SECMIME_EnableCipher(SMIME_DES_CBC_56, 1);
|
||||
#if 0
|
||||
SECMIME_EnableCipher(SMIME_RC5PAD_64_16_128, 1);
|
||||
SECMIME_EnableCipher(SMIME_RC5PAD_64_16_64, 1);
|
||||
SECMIME_EnableCipher(SMIME_FORTEZZA, 1);
|
||||
#endif
|
||||
case ssmExport:
|
||||
SECMIME_EnableCipher(SMIME_RC2_CBC_40, 1);
|
||||
#if 0
|
||||
SECMIME_EnableCipher(SMIME_RC5PAD_64_16_40, 1);
|
||||
#endif
|
||||
case ssmFrance:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* now tell secmime that we've sent it the last preference */
|
||||
SECMIME_EnableCipher(CIPHER_FAMILYID_MASK, 0);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ssm_InitializePKCS11Strings(void)
|
||||
{
|
||||
char *manufacturerID = NULL;
|
||||
char *libraryDescription = NULL;
|
||||
char *tokenDescription = NULL;
|
||||
char *privateTokenDescription = NULL;
|
||||
char *slotDescription = NULL;
|
||||
char *privateSlotDescription = NULL;
|
||||
char *fipsSlotDescription = NULL;
|
||||
char *fipsPrivateSlotDescription = NULL;
|
||||
|
||||
SSMTextGenContext *cx;
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMTextGen_NewTopLevelContext(NULL, &cx);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "manufacturerID", &manufacturerID);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "libraryDescription",
|
||||
&libraryDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "tokenDescription",
|
||||
&tokenDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "privateTokenDescription",
|
||||
&privateTokenDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "slotDescription", &slotDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "privateSlotDescription",
|
||||
&privateSlotDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "fipsSlotDescription",
|
||||
&fipsSlotDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "fipsPrivateSlotDescription",
|
||||
&fipsPrivateSlotDescription);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
if (cx != NULL) {
|
||||
SSMTextGen_DestroyContext(cx);
|
||||
}
|
||||
PK11_ConfigurePKCS11(manufacturerID, libraryDescription, tokenDescription,
|
||||
privateTokenDescription, slotDescription,
|
||||
privateSlotDescription, fipsSlotDescription,
|
||||
fipsPrivateSlotDescription, 0, 0);
|
||||
return SECSuccess;
|
||||
loser:
|
||||
PR_FREEIF(manufacturerID);
|
||||
PR_FREEIF(libraryDescription);
|
||||
PR_FREEIF(tokenDescription);
|
||||
PR_FREEIF(privateTokenDescription);
|
||||
PR_FREEIF(slotDescription);
|
||||
PR_FREEIF(privateSlotDescription);
|
||||
if (cx != NULL) {
|
||||
SSMTextGen_DestroyContext(cx);
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#define CATCH_SIGNAL_DEFAULT(SIGNAL) \
|
||||
if (((int)signal(SIGNAL, psm_signal_handler_default)) == ((int)SIG_ERR)) \
|
||||
goto loser;
|
||||
|
||||
#define CATCH_SIGNAL_IGNORE(SIGNAL) \
|
||||
if (((int)signal(SIGNAL, psm_signal_handler_ignore)) == ((int)SIG_ERR)) \
|
||||
goto loser;
|
||||
|
||||
static void
|
||||
psm_signal_handler_default(int sig)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf ("Trapping the signal %d\n", sig);
|
||||
#endif
|
||||
SSM_ReleaseLockFile();
|
||||
kill(getpid(),SIGKILL);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_signal_handler_ignore(int sig)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf ("Ignoring the signal %d\n", sig);
|
||||
#endif
|
||||
signal(sig,psm_signal_handler_ignore);
|
||||
}
|
||||
|
||||
static SSMStatus
|
||||
psm_catch_signals(void)
|
||||
{
|
||||
CATCH_SIGNAL_IGNORE(SIGHUP);
|
||||
CATCH_SIGNAL_DEFAULT(SIGINT);
|
||||
CATCH_SIGNAL_DEFAULT(SIGQUIT);
|
||||
CATCH_SIGNAL_DEFAULT(SIGILL);
|
||||
CATCH_SIGNAL_DEFAULT(SIGTRAP);
|
||||
CATCH_SIGNAL_DEFAULT(SIGABRT);
|
||||
CATCH_SIGNAL_DEFAULT(SIGIOT);
|
||||
#ifdef SIGEMT
|
||||
CATCH_SIGNAL_DEFAULT(SIGEMT);
|
||||
#endif
|
||||
CATCH_SIGNAL_DEFAULT(SIGFPE);
|
||||
CATCH_SIGNAL_DEFAULT(SIGBUS);
|
||||
CATCH_SIGNAL_DEFAULT(SIGSEGV);
|
||||
#ifdef SIGSYS
|
||||
CATCH_SIGNAL_DEFAULT(SIGSYS);
|
||||
#endif
|
||||
CATCH_SIGNAL_IGNORE(SIGPIPE);
|
||||
CATCH_SIGNAL_DEFAULT(SIGTERM);
|
||||
#ifndef LINUX
|
||||
CATCH_SIGNAL_DEFAULT(SIGUSR1);
|
||||
#endif
|
||||
CATCH_SIGNAL_DEFAULT(SIGUSR2);
|
||||
#ifdef SIGXCPU
|
||||
CATCH_SIGNAL_DEFAULT(SIGXCPU);
|
||||
#endif
|
||||
#ifdef SIGDANGER
|
||||
CATCH_SIGNAL_DEFAULT(SIGDANGER);
|
||||
#endif
|
||||
return SSM_SUCCESS;
|
||||
loser:
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(XP_PC) && !defined(DEBUG)
|
||||
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
|
||||
LPSTR lpszLine, int nShow)
|
||||
#else
|
||||
#ifdef macintosh
|
||||
/*
|
||||
We run RunMacPSM in a separate thread off the main thread.
|
||||
This is because we can't do any blocking I/O routines on the main
|
||||
thread, because Mac NSPR doesn't own the original thread used to
|
||||
run the app.
|
||||
*/
|
||||
void RunMacPSM(void *arg)
|
||||
#else
|
||||
int main(int argc, char ** argv)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
#ifdef macintosh
|
||||
#pragma unused(arg)
|
||||
#endif
|
||||
#if (defined(XP_PC) && !defined(DEBUG)) || (defined(macintosh))
|
||||
/* substitute argc and argv for NSPR */
|
||||
int argc = 0;
|
||||
char *argv[] = {"", NULL};
|
||||
#endif
|
||||
PRIntn result = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
PR_STDIO_INIT();
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Initialize logging. */
|
||||
SSM_InitLogging();
|
||||
#endif
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
SSM_CheckTimebomb();
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
if (psm_catch_signals() != SSM_SUCCESS) {
|
||||
SSM_DEBUG("Couldn't set signal handlers. Quitting\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
SSM_SetPolicy();
|
||||
enable_SMIME_cipher_prefs();
|
||||
if (SSM_GetPolicy() == ssmDomestic) {
|
||||
SSM_EnableHighGradeKeyGen();
|
||||
}
|
||||
|
||||
/* Initialize NLS layer */
|
||||
if (nlsInit() != PR_TRUE) {
|
||||
SSM_DEBUG("Failed to initialize the NLS layer\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Initialize global list of control connections. */
|
||||
connections = SSM_NewCollection();
|
||||
if (connections == NULL)
|
||||
{
|
||||
SSM_DEBUG("Can't initialize! (%ld)\n", (long) result);
|
||||
exit(1);
|
||||
}
|
||||
/* Initialize global list of tokens */
|
||||
result = SSM_HashCreate(&tokenList);
|
||||
if (result != PR_SUCCESS || !tokenList) {
|
||||
SSM_DEBUG("Can't initialize - tokenList \n");
|
||||
exit(result);
|
||||
}
|
||||
tokenLock = PR_NewMonitor();
|
||||
if (!tokenLock) {
|
||||
SSM_DEBUG("Can't initialize - tokenLock\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Initialize hash table of control connections */
|
||||
result = SSM_HashCreate(&ctrlConnections);
|
||||
if (result != PR_SUCCESS || !ctrlConnections) {
|
||||
SSM_DEBUG("Can't initialize global table for control connections \n");
|
||||
exit(result);
|
||||
}
|
||||
|
||||
/* Initialize resource table */
|
||||
SSM_ResourceInit();
|
||||
|
||||
if (SSM_InitPolicyHandler() != PR_SUCCESS) {
|
||||
SSM_DEBUG("Couldn't initialize the Policy Handler.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* initialize random number generator */
|
||||
SSM_DEBUG("Initializing random number generator.\n");
|
||||
RNG_RNGInit();
|
||||
RNG_SystemInfoForRNG();
|
||||
|
||||
/*
|
||||
* All the ciphers except SSL_RSA_WITH_NULL_MD5 are on by default.
|
||||
* Enable encryption, enable NULL cipher.
|
||||
*/
|
||||
#ifdef XP_MAC
|
||||
result = mainLoop(argc, argv);
|
||||
#else
|
||||
result = PR_Initialize(mainLoop, argc, argv, 0);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("main: Finishing (%ld)\n", (long) result);
|
||||
#endif
|
||||
#ifdef XP_UNIX
|
||||
SSM_ReleaseLockFile();
|
||||
#endif
|
||||
#ifndef XP_MAC
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
void *
|
||||
psm_malloc(unsigned long numbytes)
|
||||
{
|
||||
return NewPtrClear(numbytes);
|
||||
}
|
||||
|
||||
void
|
||||
psm_free(void *ptr)
|
||||
{
|
||||
DisposePtr((char *) ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
PRIntn mainLoop(PRIntn argc, char ** argv)
|
||||
{
|
||||
PRFileDesc *socket, *respsocket;
|
||||
PRNetAddr clientaddr;
|
||||
SSMControlConnection *curconnect;
|
||||
SSMResourceID ctrlID;
|
||||
SSMStatus status = PR_FAILURE;
|
||||
PRBool alive = PR_TRUE;
|
||||
|
||||
/* Register ourselves so that logs, etc can identify us */
|
||||
SSM_RegisterThread("main", NULL);
|
||||
|
||||
/* Open NLS stuff */
|
||||
SSM_DEBUG("Initializing NLS.\n");
|
||||
#ifdef XP_MAC
|
||||
SSM_InitNLS(":ui:");
|
||||
#else
|
||||
SSM_InitNLS("ui");
|
||||
#endif
|
||||
ssm_InitializePKCS11Strings();
|
||||
|
||||
/* Initialize the protocol */
|
||||
#ifdef XP_MAC
|
||||
CMT_Init(malloc, free);
|
||||
#else
|
||||
CMT_Init(PR_Malloc, PR_Free);
|
||||
#endif
|
||||
|
||||
/* Open the HTTP listener */
|
||||
SSM_DEBUG("Opening HTTP thread.\n");
|
||||
status = SSM_InitHTTP();
|
||||
if (status != SSM_SUCCESS)
|
||||
{
|
||||
SSM_DEBUG("Couldn't open web port. Exiting.\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* open a port for control connections, with well-known port# */
|
||||
socket = SSM_OpenControlPort();
|
||||
if (!socket)
|
||||
{
|
||||
SSM_DEBUG("Couldn't open control port. Exiting.\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
while (alive)
|
||||
{
|
||||
/* wait until there is incoming request */
|
||||
|
||||
respsocket = PR_Accept(socket, &clientaddr, PR_INTERVAL_NO_TIMEOUT);
|
||||
/* while (respsocket == NULL)
|
||||
{
|
||||
if (PR_GetError() != PR_WOULD_BLOCK_ERROR)
|
||||
goto loser;
|
||||
PR_Sleep(CARTMAN_SPINTIME);
|
||||
#ifdef DEBUG
|
||||
printf("master: Still ready for client connection on port %d\n", CARTMAN_PORT); fflush(stdout);
|
||||
#endif
|
||||
respsocket = PR_Accept(socket, &clientaddr,
|
||||
PR_SecondsToInterval(2));
|
||||
} */
|
||||
if (!respsocket) {
|
||||
/* accept failed: abort */
|
||||
status = PR_GetError();
|
||||
SSM_DEBUG("Error %d accepting control connection. Exiting.\n",
|
||||
status);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (SSM_SocketPeerCheck(respsocket, PR_TRUE)) {
|
||||
SSM_DEBUG("creating control connection.\n");
|
||||
status = SSM_CreateResource(SSM_RESTYPE_CONTROL_CONNECTION,
|
||||
respsocket,
|
||||
NULL,
|
||||
&ctrlID,
|
||||
(SSMResource **) &curconnect);
|
||||
if (status != PR_SUCCESS)
|
||||
break;
|
||||
|
||||
PR_ASSERT(RESOURCE_CLASS(curconnect) == SSM_RESTYPE_CONTROL_CONNECTION);
|
||||
}
|
||||
else {
|
||||
/* connection did not come from localhost: shut down the
|
||||
* connection and continue to loop
|
||||
*/
|
||||
SSM_DEBUG("Connection attempt from a non-local host!\n");
|
||||
status = PR_Shutdown(respsocket, PR_SHUTDOWN_BOTH);
|
||||
respsocket = NULL;
|
||||
}
|
||||
} /* end while(true) */
|
||||
loser:
|
||||
/* Shut down the HTTP thread. */
|
||||
if (httpListenThread != NULL){
|
||||
PR_Interrupt(httpListenThread);
|
||||
}
|
||||
exit(1);
|
||||
/* ### mwelch - should we return meaningful error code? */
|
||||
|
||||
return 0;
|
||||
}
|
2131
security/psm/server/minihttp.c
Normal file
2131
security/psm/server/minihttp.c
Normal file
File diff suppressed because it is too large
Load Diff
219
security/psm/server/minihttp.h
Normal file
219
security/psm/server/minihttp.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __SSM_MINIHTTP_H__
|
||||
#define __SSM_MINIHTTP_H__
|
||||
|
||||
#include "ssmerrs.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "serv.h"
|
||||
#include "prthread.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "nlsutil.h"
|
||||
|
||||
/* Result codes; see
|
||||
http://info.internet.isi.edu:80/in-notes/rfc/files/rfc2068.txt
|
||||
for more information */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HTTP_OK = (PRInt32) 200,
|
||||
HTTP_NO_CONTENT = 204,
|
||||
HTTP_BAD_REQUEST = 400,
|
||||
HTTP_UNAUTHORIZED = 401,
|
||||
HTTP_FORBIDDEN = 403,
|
||||
HTTP_NOT_FOUND = 404,
|
||||
HTTP_METHOD_NOT_ALLOWED = 405,
|
||||
HTTP_INTERNAL_ERROR = 500,
|
||||
HTTP_NOT_IMPLEMENTED = 501,
|
||||
HTTP_SERVICE_UNAVAILABLE = 503,
|
||||
HTTP_GATEWAY_TIMEOUT = 504,
|
||||
HTTP_VERSION_UNSUPPORTED = 505
|
||||
} HTTPErrorCode;
|
||||
|
||||
/* ### mwelch - This has to be done better after the 11/1998 demo. */
|
||||
typedef enum
|
||||
{
|
||||
SSM_UI_NULL = (PRUint32) 0,
|
||||
|
||||
SSM_UI_KEYGEN_PROGRESS, /* Frameset containing keygen components */
|
||||
|
||||
SSM_UI_DIALOG_FRAMESET, /* Generic frameset for dialogs */
|
||||
SSM_UI_DIALOG_FB, /* Dialogs: NSM -> client feedback, kept open */
|
||||
SSM_UI_DIALOG_CANCEL /* A "cancel" command invokable by the client */
|
||||
} SSMDialogSelector;
|
||||
|
||||
struct HTTPRequest
|
||||
{
|
||||
PRFileDesc *sock; /* Socket with which we talk to client */
|
||||
|
||||
char *rawreqbuf; /* Copy of the raw request we got */
|
||||
char *reqbuf; /* The HTTP request we got,
|
||||
which is later parsed */
|
||||
char **paramNames; /* Names of parameters passed to the URL */
|
||||
char **paramValues; /* Values of parameters passed to the URL */
|
||||
PRUint32 numParams; /* How many parameters were passed */
|
||||
|
||||
PRUint32 slen; /* The amount of actual text in the buffer(s) */
|
||||
PRUint32 len; /* The allocated length of the buffer(s) */
|
||||
|
||||
char *hdrbuf; /* Response header */
|
||||
SSMStatus rv; /* Internal result code (used if an
|
||||
internal error occurred) */
|
||||
HTTPErrorCode httprv; /* HTTP result code (200, 401, 404, etc) */
|
||||
char *errormsg; /* if a problem occurs, send this string back
|
||||
to the client. */
|
||||
|
||||
char *filename; /* Canned file to fetch from data, if any */
|
||||
|
||||
/* These point to chars within (reqbuf). */
|
||||
char *handlerName; /* Command requested by client */
|
||||
char *params; /* Parameters passed to GET */
|
||||
char *agent; /* User-Agent value */
|
||||
|
||||
char *ctrlrid; /* Authorization: RID of control connection */
|
||||
char *password; /* Authorization: RID of nonce */
|
||||
char *referer; /* The URL for the referer */
|
||||
SSMControlConnection *ctrlconn;
|
||||
/* Control connection owning this connection */
|
||||
SSMResource *target; /* Target resource, if any */
|
||||
|
||||
char *language; /* Accept-Language value */
|
||||
char *charset; /* Accept-Charset value */
|
||||
|
||||
PRBool sentResponse; /* Have we already sent a response to the user? */
|
||||
|
||||
PRBool keepSock; /* Are we keeping this socket (eg for logging)? */
|
||||
PRBool processText; /* Should we interpret files we send out as text? */
|
||||
SSMResourceID rid; /* ID of requested resource */
|
||||
};
|
||||
|
||||
/* Typedef for a command handler. */
|
||||
typedef SSMStatus (*SSMCommandHandlerFunc)(HTTPRequest *req);
|
||||
|
||||
/* Register a command handler. */
|
||||
SSMStatus SSM_HTTPRegisterCommandHandler(const char *name,
|
||||
SSMCommandHandlerFunc func);
|
||||
|
||||
/* function to parse the request and submit html */
|
||||
SSMStatus SSM_HTTPGetGenericLump(HTTPRequest *req, PRBool binary);
|
||||
|
||||
/* The default handler, which uses baseRef as a prefix for two strings
|
||||
to use in processing and returning HTTP headers and content. Can be
|
||||
called by other handlers if no special header/content processing
|
||||
for the user is necessary. */
|
||||
SSMStatus SSM_HTTPDefaultCommandHandler(HTTPRequest *req);
|
||||
|
||||
/* ### sjlee: This function is called when you need to sleep one second
|
||||
* before closing the window due to collision of dialog windows
|
||||
* this is really the default command handler with a sleep
|
||||
*/
|
||||
SSMStatus SSM_HTTPCloseAndSleep(HTTPRequest* req);
|
||||
|
||||
|
||||
/* Handler for getting binary data. This should be consolidated with
|
||||
the default handler. */
|
||||
SSMStatus SSM_HTTPGetBinaryHandler(HTTPRequest *req);
|
||||
|
||||
/* Handler for monitoring resources. */
|
||||
SSMStatus SSM_HTTPMonitorResourceHandler(HTTPRequest *req);
|
||||
|
||||
/* Handler which shuts down a resource. */
|
||||
SSMStatus SSM_HTTPShutdownResourceHandler(HTTPRequest *req);
|
||||
|
||||
/* Hello World example */
|
||||
SSMStatus SSM_HTTPHelloWorld(HTTPRequest *req);
|
||||
|
||||
/* NLS Hello World example */
|
||||
SSMStatus SSM_HTTPHelloWorldWithNLS(HTTPRequest *req);
|
||||
|
||||
/* SSM_HTTPThread listens to the HTTP socket for connections from
|
||||
one or more clients. (arg) should be an open socket (PRFileDesc*),
|
||||
therefore the port needs to have been created before being passed
|
||||
to this thread. */
|
||||
void SSM_HTTPThread(void *arg);
|
||||
|
||||
/* Open the HTTP listener. */
|
||||
SSMStatus SSM_InitHTTP(void);
|
||||
|
||||
/* Get the port on which we're listening for HTTP connections. */
|
||||
PRUint32 SSM_GetHTTPPort(void);
|
||||
|
||||
/* Construct a URL and size info based on a known page/access point
|
||||
and control connection. */
|
||||
SSMStatus SSM_GenerateURL(SSMControlConnection *conn,
|
||||
char *command,
|
||||
char *baseRef,
|
||||
SSMResource *targetRes, /* can pass NULL for this */
|
||||
char *otherParams,
|
||||
PRUint32 *width, PRUint32 *height,
|
||||
char **url);
|
||||
|
||||
/* Main listening thread for HTTP requests */
|
||||
extern PRThread *httpListenThread;
|
||||
|
||||
extern PRUint32 httpListenPort;
|
||||
|
||||
/* Command handler utilities */
|
||||
SSMStatus SSM_HTTPParamByName(HTTPRequest *req,
|
||||
const char *key, const char **value);
|
||||
|
||||
SSMStatus SSM_RIDTextToResource(HTTPRequest *req, const char *ridText,
|
||||
SSMResource **res);
|
||||
|
||||
SSMStatus SSM_HTTPReportError(HTTPRequest *req, HTTPErrorCode statusCode);
|
||||
|
||||
void SSM_HTTPReportSpecificError(HTTPRequest *req, char *fmt, ...);
|
||||
|
||||
SSMStatus SSM_HTTPParamValue(HTTPRequest *req, const char *key, char **value);
|
||||
SSMStatus SSM_HTTPAddParamValue(HTTPRequest *req, const char * key,
|
||||
const char * value);
|
||||
|
||||
SSMStatus
|
||||
SSM_HTTPSendOKHeader(HTTPRequest *req,
|
||||
char * addtlHeaders,
|
||||
char * contentType);
|
||||
|
||||
SSMStatus
|
||||
SSM_HTTPSendUTF8String(HTTPRequest *req, char * str);
|
||||
|
||||
SSMStatus
|
||||
SSM_HTTPCloseWindow(HTTPRequest *req);
|
||||
|
||||
char * SSM_ConvertStringToHTMLString(char * string);
|
||||
|
||||
SSMStatus SSM_ProcessPasswordWindow(HTTPRequest * req);
|
||||
|
||||
#endif
|
||||
|
406
security/psm/server/multitoken.c
Normal file
406
security/psm/server/multitoken.c
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "resource.h"
|
||||
#include "kgenctxt.h"
|
||||
#include "nlsutil.h"
|
||||
#include "base64.h"
|
||||
#include "pk11func.h"
|
||||
#include "textgen.h"
|
||||
#include "minihttp.h"
|
||||
#include "connect.h"
|
||||
#include "messages.h"
|
||||
|
||||
/* lock to wait for UI */
|
||||
typedef struct {
|
||||
PRMonitor * lock;
|
||||
PRBool UIComplete;
|
||||
} SSMTokenUI_Monitor;
|
||||
|
||||
#define SSM_PARENT_CONN(x) &((x)->m_parent->super)
|
||||
|
||||
#if 0 /* XXX not used? */
|
||||
static SSMTokenUI_Monitor UIlock;
|
||||
#endif
|
||||
|
||||
PK11SlotListElement * PK11_GetNextSafe(PK11SlotList *list,
|
||||
PK11SlotListElement *le,
|
||||
PRBool restart);
|
||||
SSMStatus SSMTokenUI_GetNames(SSMResource * res, PRBool start, char ** name);
|
||||
|
||||
SSMStatus SSM_SetUserPasswordCommunicator(PK11SlotInfo * slot,
|
||||
SSMKeyGenContext *ct);
|
||||
|
||||
CK_MECHANISM_TYPE
|
||||
SSMKeyGenContext_GenMechToAlgMech(CK_MECHANISM_TYPE mechanism)
|
||||
{
|
||||
CK_MECHANISM_TYPE searchMech;
|
||||
|
||||
/* We are interested in slots based on the ability to perform
|
||||
a given algorithm, not on their ability to generate keys usable
|
||||
by that algorithm. Therefore, map keygen-specific mechanism tags
|
||||
to tags for the corresponding crypto algorthm. */
|
||||
switch(mechanism)
|
||||
{
|
||||
case CKM_RSA_PKCS_KEY_PAIR_GEN:
|
||||
searchMech = CKM_RSA_PKCS;
|
||||
break;
|
||||
case CKM_DSA_KEY_PAIR_GEN:
|
||||
searchMech = CKM_DSA;
|
||||
break;
|
||||
case CKM_RC4_KEY_GEN:
|
||||
searchMech = CKM_RC4;
|
||||
break;
|
||||
case CKM_DH_PKCS_KEY_PAIR_GEN:
|
||||
searchMech = CKM_DH_PKCS_DERIVE; /* ### mwelch is this right? */
|
||||
break;
|
||||
case CKM_DES_KEY_GEN:
|
||||
/* What do we do about DES keygen? Right now, we're just using
|
||||
DES_KEY_GEN to look for tokens, because otherwise we'll have
|
||||
to search the token list three times. */
|
||||
default:
|
||||
searchMech = mechanism;
|
||||
break;
|
||||
}
|
||||
return searchMech;
|
||||
}
|
||||
|
||||
SSMStatus SSMKeyGenContext_GetSlot(SSMKeyGenContext * keyctxt,
|
||||
CK_MECHANISM_TYPE mechanism)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
PK11SlotList * slotList = NULL;
|
||||
CK_MECHANISM_TYPE searchMech;
|
||||
PRBool reLock;
|
||||
|
||||
searchMech = SSMKeyGenContext_GenMechToAlgMech(mechanism);
|
||||
|
||||
if (!keyctxt->slot ||
|
||||
!PK11_DoesMechanism(keyctxt->slot, searchMech)) {
|
||||
slotList = PK11_GetAllTokens(searchMech, PR_TRUE, PR_TRUE,
|
||||
keyctxt->super.m_connection);
|
||||
|
||||
if (!keyctxt)
|
||||
goto loser;
|
||||
if (!slotList || !slotList->head)
|
||||
goto loser;
|
||||
|
||||
if (!slotList->head->next) {
|
||||
/* only one slot available, just return it */
|
||||
keyctxt->slot = slotList->head->slot;
|
||||
keyctxt->m_slotName = strdup(PK11_GetSlotName(keyctxt->slot));
|
||||
} else {
|
||||
char * mech = PR_smprintf("mech=%d&task=keygen&unused=unused", searchMech);
|
||||
if (keyctxt->m_ctxtype == SSM_OLD_STYLE_KEYGEN) {
|
||||
CMTItem msg;
|
||||
GenKeyOldStyleTokenRequest request;
|
||||
char ** tokenNames = NULL;
|
||||
int numtokens = 0;
|
||||
PK11SlotListElement * slotElement;
|
||||
|
||||
slotElement = PK11_GetFirstSafe(slotList);
|
||||
while(slotElement) {
|
||||
numtokens++;
|
||||
tokenNames = (char **) PR_REALLOC(tokenNames, numtokens*sizeof(*tokenNames));
|
||||
tokenNames[numtokens - 1] = strdup(PK11_GetTokenName(slotElement->slot));
|
||||
|
||||
slotElement = PK11_GetNextSafe(slotList, slotElement, PR_FALSE);
|
||||
}
|
||||
|
||||
/* send message to plugin: use native UI for select token dialog */
|
||||
SSM_LockUIEvent(&keyctxt->super);
|
||||
request.rid = keyctxt->super.m_id;
|
||||
request.numtokens = numtokens;
|
||||
request.tokenNames = tokenNames;
|
||||
|
||||
msg.type = SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_TOKEN;
|
||||
if (CMT_EncodeMessage(GenKeyOldStyleTokenRequestTemplate, &msg,
|
||||
&request) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
SSM_SendQMessage(keyctxt->super.m_connection->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
msg.type, msg.len, (char *)msg.data, PR_TRUE);
|
||||
|
||||
SSM_WaitUIEvent(&keyctxt->super, PR_INTERVAL_NO_TIMEOUT);
|
||||
SSM_UnlockUIEvent(&keyctxt->super);
|
||||
keyctxt->slot = (PK11SlotInfo*)keyctxt->super.m_uiData;
|
||||
} else /* post UI event */ {
|
||||
/* post a UI event to ask user for the slot */
|
||||
SSM_LockUIEvent(&keyctxt->super);
|
||||
|
||||
/* Release the lock on the resource temporarily while
|
||||
* the UI happens.
|
||||
*/
|
||||
rv = SSM_UnlockResource(&keyctxt->super);
|
||||
reLock = (rv == PR_SUCCESS) ? PR_TRUE : PR_FALSE;
|
||||
rv = SSMControlConnection_SendUIEvent(keyctxt->super.m_connection,
|
||||
"get",
|
||||
"select_token",
|
||||
(SSMResource *)keyctxt,
|
||||
mech,
|
||||
&((SSMResource*)keyctxt)->m_clientContext);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
if (keyctxt->super.m_UILock != NULL) {
|
||||
PR_ExitMonitor(keyctxt->super.m_UILock);
|
||||
}
|
||||
goto loser;
|
||||
}
|
||||
/* wait until the UI dialog box is done */
|
||||
SSM_WaitUIEvent(&keyctxt->super, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (reLock) {
|
||||
/* Get the lock back. */
|
||||
SSM_LockResource(&keyctxt->super);
|
||||
}
|
||||
SSM_UnlockUIEvent(&keyctxt->super);
|
||||
PR_Free(mech);
|
||||
/* ok, the return from UI is processed in command handler */
|
||||
/* Make sure password prompt doesn't get sucked away by
|
||||
* the disappearing dialog
|
||||
*/
|
||||
PR_Sleep(PR_TicksPerSecond());
|
||||
keyctxt->slot = (PK11SlotInfo*)keyctxt->super.m_uiData;
|
||||
if (keyctxt->slot != NULL) {
|
||||
keyctxt->m_slotName = strdup(PK11_GetSlotName(keyctxt->slot));
|
||||
}
|
||||
} /* end of post UI event */
|
||||
} /* end of multiple tokens available */
|
||||
/* Get a slot reference so it doesn't disappear */
|
||||
if (keyctxt->slot) {
|
||||
PK11_ReferenceSlot(keyctxt->slot);
|
||||
}
|
||||
}
|
||||
/* we should have a slot now */
|
||||
if (keyctxt->slot == NULL)
|
||||
goto loser;
|
||||
|
||||
/* Before we authenticate, make sure the user initialized the DB. */
|
||||
if (PK11_NeedUserInit(keyctxt->slot))
|
||||
rv = SSM_SetUserPasswordCommunicator(keyctxt->slot, keyctxt);
|
||||
|
||||
rv = PK11_Authenticate(keyctxt->slot, PR_FALSE, keyctxt);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
goto done;
|
||||
loser:
|
||||
|
||||
if (rv == SSM_SUCCESS)
|
||||
rv = SSM_FAILURE;
|
||||
keyctxt->slot = NULL;
|
||||
done:
|
||||
if (slotList)
|
||||
PK11_FreeSlotList(slotList);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* send a message to communicator to display UI for setting slot password */
|
||||
SSMStatus
|
||||
SSM_SetUserPasswordCommunicator(PK11SlotInfo * slot,
|
||||
SSMKeyGenContext *ct)
|
||||
{
|
||||
CMTItem msg;
|
||||
GenKeyOldStylePasswordRequest passwdmsg;
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
PRBool reLock = PR_FALSE;
|
||||
|
||||
PR_ASSERT(SSM_IsAKindOf(&ct->super, SSM_RESTYPE_KEYGEN_CONTEXT));
|
||||
|
||||
|
||||
switch (ct->m_ctxtype) {
|
||||
case (SSM_CRMF_KEYGEN):
|
||||
rv = SSM_SetUserPassword(slot, &ct->super);
|
||||
break;
|
||||
case (SSM_OLD_STYLE_KEYGEN):
|
||||
SSM_LockUIEvent(&ct->super);
|
||||
passwdmsg.rid = ct->super.m_id;
|
||||
passwdmsg.tokenName = PK11_GetTokenName(slot);
|
||||
passwdmsg.internal = (CMBool) PK11_IsInternal(slot);
|
||||
passwdmsg.minpwdlen = PR_MAX(SSM_MIN_PWD_LEN,PK11_GetMinimumPwdLength(slot));
|
||||
passwdmsg.maxpwdlen = slot->maxPassword;
|
||||
msg.type = SSM_REPLY_OK_MESSAGE | SSM_KEYGEN_TAG | SSM_KEYGEN_PASSWORD;
|
||||
if (CMT_EncodeMessage(GenKeyOldStylePasswordRequestTemplate, &msg,
|
||||
&passwdmsg) != CMTSuccess)
|
||||
goto loser;
|
||||
rv = SSM_SendQMessage(ct->super.m_connection->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
msg.type, msg.len, (char *)msg.data, PR_TRUE);
|
||||
if (rv != SSM_SUCCESS)
|
||||
SSM_UnlockUIEvent(&ct->super);
|
||||
else
|
||||
SSM_WaitUIEvent(&ct->super, PR_INTERVAL_NO_TIMEOUT);
|
||||
break;
|
||||
default:
|
||||
SSM_DEBUG("Unknown keygen type!\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (rv != SSM_SUCCESS)
|
||||
SSM_DEBUG("SetUserPasswordComm: can't send password request msg!\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
ssmpkcs11_convert_slot(SSMTextGenContext *cx,
|
||||
PRInt32 slotIndex,
|
||||
PK11SlotInfo *slot,
|
||||
char *fmt,
|
||||
PRBool accumulate);
|
||||
|
||||
SSMStatus SSMTokenUI_KeywordHandler(SSMTextGenContext * cx)
|
||||
{
|
||||
SSMResource *ctxt = NULL;
|
||||
SSMStatus rv;
|
||||
char * tempUStr = NULL;
|
||||
char * wrapper = NULL;
|
||||
CK_MECHANISM_TYPE searchMech;
|
||||
char *searchMechStr;
|
||||
static PK11SlotList * slotList;
|
||||
static PK11SlotListElement * slotElement;
|
||||
PRIntn i = 0;
|
||||
|
||||
if (!cx || !cx->m_request || !cx->m_params || !cx->m_result)
|
||||
goto loser;
|
||||
|
||||
ctxt = SSMTextGen_GetTargetObject(cx);
|
||||
|
||||
/* Get the wrapper string from the properties file. */
|
||||
wrapper = (char *) SSM_At(cx->m_params, 0);
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, wrapper, &tempUStr);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_HTTPParamValue(cx->m_request, "action", &searchMechStr);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
searchMech = atoi(searchMechStr);
|
||||
slotList = PK11_GetAllTokens(searchMech, PR_TRUE, PR_TRUE,
|
||||
ctxt->m_connection);
|
||||
if (!slotList)
|
||||
goto loser;
|
||||
|
||||
slotElement = PK11_GetFirstSafe(slotList);
|
||||
while(slotElement)
|
||||
{
|
||||
rv = ssmpkcs11_convert_slot(cx, i++, slotElement->slot, tempUStr,
|
||||
PR_TRUE);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
slotElement = PK11_GetNextSafe(slotList, slotElement, PR_FALSE);
|
||||
}
|
||||
|
||||
rv = SSM_SUCCESS;
|
||||
goto done;
|
||||
loser:
|
||||
SSM_DEBUG("Errors creating token list!\n");
|
||||
SSMTextGen_UTF8StringClear(&cx->m_result);
|
||||
if (rv==SSM_SUCCESS)
|
||||
rv = SSM_FAILURE;
|
||||
done:
|
||||
PR_FREEIF(tempUStr);
|
||||
return rv;
|
||||
}
|
||||
PK11SlotInfo *
|
||||
SSMPKCS11_FindSlotByID(SECMODModuleID modID,
|
||||
CK_SLOT_ID slotID);
|
||||
|
||||
SSMStatus
|
||||
figure_out_token_selection(char *str,
|
||||
SECMODModuleID *modID,
|
||||
CK_SLOT_ID *slotID)
|
||||
{
|
||||
char *walk;
|
||||
|
||||
walk = PL_strchr(str, '+');
|
||||
if (!walk)
|
||||
return SSM_FAILURE;
|
||||
*walk++ = '\0';
|
||||
*modID = atoi(str);
|
||||
*slotID = atoi(walk);
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMTokenUI_CommandHandler(HTTPRequest * req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
char * tokenName = NULL;
|
||||
SSMResource *res;
|
||||
SECMODModuleID modID;
|
||||
CK_SLOT_ID slotID;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
if (!req->target)
|
||||
goto loser;
|
||||
res = req->target;
|
||||
|
||||
res->m_uiData = NULL;
|
||||
/* check the parameter values */
|
||||
if (res->m_buttonType == SSM_BUTTON_CANCEL)
|
||||
{
|
||||
slot = NULL;
|
||||
goto done; /* return the closing javascript */
|
||||
}
|
||||
|
||||
/* Determine what token the user selected. */
|
||||
rv = SSM_HTTPParamValue(req, "token", &tokenName);
|
||||
if (rv != SSM_SUCCESS)
|
||||
{
|
||||
req->httprv = HTTP_BAD_REQUEST;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = figure_out_token_selection(tokenName, &modID, &slotID);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
slot = SSMPKCS11_FindSlotByID(modID, slotID);
|
||||
if (!slot)
|
||||
goto loser;
|
||||
|
||||
done:
|
||||
/* Tell the keygen context what token was selected. */
|
||||
res->m_uiData = slot;
|
||||
SSM_NotifyUIEvent(res);
|
||||
/* Done with our part, so pass back whatever the dialog wants in
|
||||
order to close the window. */
|
||||
return SSM_HTTPCloseAndSleep(req);
|
||||
|
||||
loser:
|
||||
res->m_uiData = NULL;
|
||||
SSM_NotifyUIEvent(res);
|
||||
SSM_DEBUG("Can't get input from token_select dialog!\n");
|
||||
return SSM_FAILURE;
|
||||
}
|
55
security/psm/server/nlslayer.h
Normal file
55
security/psm/server/nlslayer.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef _NLSLAYER_H_
|
||||
#define _NLSLAYER_H_
|
||||
|
||||
PRBool nlsInit();
|
||||
char* nlsGetUTF8String(const char *name);
|
||||
void * nlsNewDateFormat();
|
||||
void nlsFreeDateFormat(void * p);
|
||||
char * nslPRTimeToUTF8String(void* p, PRInt64 t);
|
||||
PRBool nlsUnicodeToUTF8(unsigned char * inBuf, unsigned int inBufBytes,
|
||||
unsigned char * outBuf, unsigned int maxOutBufLen,
|
||||
unsigned int * outBufLen);
|
||||
PRBool nlsUTF8ToUnicode(unsigned char * inBuf, unsigned int inBufBytes,
|
||||
unsigned char * outBuf, unsigned int maxOutBufLen,
|
||||
unsigned int * outBufLen);
|
||||
PRBool nlsUnicodeToASCII(unsigned char * inBuf, unsigned int inBufBytes,
|
||||
unsigned char * outBuf, unsigned int maxOutBufLen,
|
||||
unsigned int * outBufLen);
|
||||
PRBool nlsASCIIToUnicode(unsigned char * inBuf, unsigned int inBufBytes,
|
||||
unsigned char * outBuf, unsigned int maxOutBufLen,
|
||||
unsigned int * outBufLen);
|
||||
|
||||
#endif /* _NLSLAYER_H_ */
|
101
security/psm/server/nlsutil.c
Normal file
101
security/psm/server/nlsutil.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "nlsutil.h"
|
||||
#include "serv.h" /* for SSM_DEBUG */
|
||||
#include "ssmerrs.h"
|
||||
#include "resource.h"
|
||||
|
||||
/* atoi() for a UnicodeString. (sigh) */
|
||||
PRInt32
|
||||
SSMTextGen_atoi(char *str)
|
||||
{
|
||||
PRInt32 result = -1;
|
||||
|
||||
/* Extract the text by converting to ASCII. */
|
||||
if (str)
|
||||
{
|
||||
/* Convert the text into a number, if possible. */
|
||||
PR_sscanf(str, "%ld", &result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Debug a UnicodeString. */
|
||||
#ifdef DEBUG
|
||||
void
|
||||
SSM_DebugUTF8String(char *prefix, char *ustr)
|
||||
{
|
||||
char *ch;
|
||||
|
||||
if (ustr)
|
||||
{
|
||||
ch = ustr;
|
||||
if (ch)
|
||||
SSM_DEBUG("%s:\n%s\n"
|
||||
"End of text\n", (prefix ? prefix : ""), ch);
|
||||
}
|
||||
else
|
||||
SSM_DEBUG("%s: (null string)\n", (prefix ? prefix : ""));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear a UnicodeString. */
|
||||
void
|
||||
SSMTextGen_UTF8StringClear(char **str)
|
||||
{
|
||||
if (str && *str)
|
||||
{
|
||||
PR_Free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSM_ConcatenateUTF8String(char **prefix, char *suffix)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (prefix == NULL || suffix == NULL) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
tmp = PR_smprintf("%s%s", (*prefix) ? *prefix : "", suffix);
|
||||
if (tmp == NULL) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
PR_Free(*prefix);
|
||||
*prefix = tmp;
|
||||
return SSM_SUCCESS;
|
||||
}
|
54
security/psm/server/nlsutil.h
Normal file
54
security/psm/server/nlsutil.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __nlsutil_h__
|
||||
#define __nlsutil_h__
|
||||
|
||||
#include "resource.h"
|
||||
#include "minihttp.h"
|
||||
|
||||
|
||||
/* Clear a UnicodeString. */
|
||||
void SSMTextGen_UTF8StringClear(char **str);
|
||||
|
||||
PRInt32 SSMTextGen_atoi(char *str);
|
||||
|
||||
#ifdef DEBUG
|
||||
void SSM_DebugUTF8String(char *prefix, char *ustr);
|
||||
#else
|
||||
#define SSM_DebugUTF8String(p,u)
|
||||
#endif
|
||||
|
||||
SSMStatus SSM_ConcatenateUTF8String(char **prefix, char *suffix);
|
||||
#endif
|
1315
security/psm/server/oldfunc.c
Normal file
1315
security/psm/server/oldfunc.c
Normal file
File diff suppressed because it is too large
Load Diff
78
security/psm/server/oldfunc.h
Normal file
78
security/psm/server/oldfunc.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _OLDFUNC_H_
|
||||
#define _OLDFUNC_H_
|
||||
|
||||
#include "keyres.h"
|
||||
#include "base64.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include "certt.h"
|
||||
#include "certdb.h"
|
||||
#include "cryptohi.h"
|
||||
#include "kgenctxt.h"
|
||||
#include "textgen.h"
|
||||
#include "secdert.h"
|
||||
#include "minihttp.h"
|
||||
#include "ssldlgs.h"
|
||||
|
||||
#define SSM_MAX_KEY_BITS 2048L
|
||||
|
||||
/* this needs to be localized */
|
||||
#define XP_HIGH_GRADE "1024 (High Grade)"
|
||||
#define XP_MEDIUM_GRADE " 768 (Medium Grade)"
|
||||
#define XP_LOW_GRADE " 512 (Low Grade)"
|
||||
|
||||
typedef struct SECKeySizeChoiceInfoStr {
|
||||
char *name;
|
||||
int size;
|
||||
unsigned int enabled;
|
||||
} SECKeySizeChoiceInfo;
|
||||
|
||||
|
||||
extern void _ssm_compress_spaces(char *psrc);
|
||||
SSMStatus SSM_OKButtonCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_CertCAImportCommandHandler1(HTTPRequest * req);
|
||||
SSMStatus SSM_CertCAImportCommandHandler2(HTTPRequest * req);
|
||||
SSMStatus SSM_FinishImportCACertHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_SubmitFormFromButtonHandler(HTTPRequest * req);
|
||||
SSMStatus SSM_SubmitFormFromButtonAndFreeTarget(HTTPRequest * req);
|
||||
SSMStatus SSM_CACertKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_CAPolicyKeywordHandler(SSMTextGenContext * cx);
|
||||
SSMStatus SSM_EnableHighGradeKeyGen(void);
|
||||
PRBool SSM_KeyGenAllowedForSize(int size);
|
||||
|
||||
char * default_nickname(CERTCertificate *cert, SSMControlConnection *conn);
|
||||
PRBool certificate_conflict(SSMControlConnection * cx, SECItem * derCert,
|
||||
CERTCertDBHandle * handle, PRBool sendUIEvent);
|
||||
#endif
|
954
security/psm/server/p12res.c
Normal file
954
security/psm/server/p12res.c
Normal file
@ -0,0 +1,954 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "p12res.h"
|
||||
#include "minihttp.h"
|
||||
#include "pk11func.h"
|
||||
#include "secmod.h"
|
||||
#include "p12.h"
|
||||
#include "p12plcy.h"
|
||||
#include "secerr.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "advisor.h"
|
||||
#include "nlslayer.h"
|
||||
|
||||
#define SSMRESOURCE(object) (&object->super)
|
||||
|
||||
#define PKCS12_IN_BUFFER_SIZE 2048
|
||||
|
||||
static SSMStatus
|
||||
ssmpkcs12context_createpkcs12file(SSMPKCS12Context *cx,
|
||||
PRBool forceAuthenticate,
|
||||
CERTCertificate **certArr,
|
||||
PRIntn numCerts);
|
||||
|
||||
|
||||
SECStatus
|
||||
SSM_UnicodeConversion(SECItem *dest, SECItem *src,
|
||||
PRBool toUnicode, PRBool swapBytes)
|
||||
{
|
||||
unsigned int allocLen;
|
||||
|
||||
if(!dest || !src) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
allocLen = ((toUnicode) ? (src->len << 2) : src->len);
|
||||
if (allocLen == 0) {
|
||||
/* empty string: we need to pad it by 2 bytes */
|
||||
allocLen = 2;
|
||||
}
|
||||
|
||||
dest->data = SSM_ZNEW_ARRAY(unsigned char, allocLen);
|
||||
|
||||
if(!SSM_UCS2_ASCIIConversion(toUnicode, src->data, src->len,
|
||||
dest->data, allocLen, &dest->len,
|
||||
swapBytes)) {
|
||||
PR_Free(dest->data);
|
||||
dest->data = NULL;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Create(void *arg, SSMControlConnection *ctrl,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMPKCS12Context *cxt = NULL;
|
||||
SSMPKCS12CreateArg *createArg = (SSMPKCS12CreateArg*)arg;
|
||||
SSMStatus rv;
|
||||
|
||||
cxt = SSM_ZNEW(SSMPKCS12Context);
|
||||
if (cxt == NULL) {
|
||||
return SSM_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = SSMPKCS12Context_Init(ctrl,cxt,SSM_RESTYPE_PKCS12_CONTEXT ,
|
||||
createArg->isExportContext);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
*res = SSMRESOURCE(cxt);
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
if (cxt != NULL) {
|
||||
SSM_FreeResource(SSMRESOURCE(cxt));
|
||||
}
|
||||
*res = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Init(SSMControlConnection *ctrl, SSMPKCS12Context *res,
|
||||
SSMResourceType type, PRBool isExportContext)
|
||||
{
|
||||
res->m_isExportContext = isExportContext;
|
||||
res->m_password = NULL;
|
||||
res->m_inputProcessed = PR_FALSE;
|
||||
res->m_file = NULL;
|
||||
res->m_digestFile = NULL;
|
||||
res->m_error = PR_FALSE;
|
||||
return SSMResource_Init(ctrl, SSMRESOURCE(res), type);
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context*)res;
|
||||
|
||||
SSMResource_Destroy(res, PR_FALSE);
|
||||
if (cxt->m_password != NULL) {
|
||||
PR_Free(cxt->m_password);
|
||||
cxt->m_password = NULL;
|
||||
}
|
||||
if (cxt->m_cert != NULL) {
|
||||
CERT_DestroyCertificate(cxt->m_cert);
|
||||
cxt->m_cert = NULL;
|
||||
}
|
||||
if (doFree) {
|
||||
PR_Free(res);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static SSMStatus
|
||||
SSMPKCS12Context_HandlePasswordRequest(SSMResource *res,
|
||||
HTTPRequest *req)
|
||||
{
|
||||
char *password, *confirmPassword;
|
||||
SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)res;
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
|
||||
/* Let's get the password out of the dialog. */
|
||||
if (res->m_buttonType != SSM_BUTTON_OK) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_HTTPParamValue(req, "passwd", &password);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_HTTPParamValue(req, "confirmPasswd", &confirmPassword);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
if (strcmp(password, confirmPassword) != 0) {
|
||||
/* Should re-prompt, but for now we fail. */
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
p12Cxt->m_password = PL_strdup(password);
|
||||
goto done;
|
||||
loser:
|
||||
p12Cxt->m_password = NULL;
|
||||
done:
|
||||
SSM_LockResource(res);
|
||||
SSM_NotifyResource(res);
|
||||
SSM_UnlockResource(res);
|
||||
SSM_HTTPDefaultCommandHandler(req);
|
||||
p12Cxt->m_inputProcessed = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_FormSubmitHandler(SSMResource *res, HTTPRequest *req)
|
||||
{
|
||||
char *formName;
|
||||
SSMStatus rv=SSM_FAILURE;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "formName", &formName);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
if (!strcmp(formName, "cert_backup_form")) {
|
||||
rv = SSMPKCS12Context_HandlePasswordRequest(res, req);
|
||||
} else if (!strcmp(formName, "set_db_password")) {
|
||||
rv = SSM_SetDBPasswordHandler(req);
|
||||
} else {
|
||||
goto loser;
|
||||
}
|
||||
return rv;
|
||||
loser:
|
||||
SSM_HTTPDefaultCommandHandler(req);
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
ssmpkcs12context_writetoexportfile(void *arg, const char *buf,
|
||||
unsigned long len)
|
||||
{
|
||||
SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)arg;
|
||||
PRInt32 bytesWritten;
|
||||
|
||||
if (p12Cxt == NULL) {
|
||||
return;
|
||||
}
|
||||
if (p12Cxt->m_file == NULL) {
|
||||
p12Cxt->m_error = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
bytesWritten = PR_Write(p12Cxt->m_file, buf, len);
|
||||
if (bytesWritten != len) {
|
||||
p12Cxt->m_error = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_CreatePKCS12FileForMultipleCerts(SSMPKCS12Context *p12Cxt,
|
||||
PRBool forceAuthenticate,
|
||||
CERTCertificate **certArr,
|
||||
PRIntn numCerts)
|
||||
{
|
||||
return ssmpkcs12context_createpkcs12file(p12Cxt, forceAuthenticate,
|
||||
certArr, numCerts);
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_CreatePKCS12File(SSMPKCS12Context *cxt,
|
||||
PRBool forceAuthenticate)
|
||||
{
|
||||
return ssmpkcs12context_createpkcs12file(cxt, forceAuthenticate,
|
||||
&cxt->m_cert, 1);
|
||||
}
|
||||
|
||||
static SSMStatus
|
||||
ssmpkcs12context_createpkcs12file(SSMPKCS12Context *cxt,
|
||||
PRBool forceAuthenticate,
|
||||
CERTCertificate **certArr,
|
||||
PRIntn numCerts)
|
||||
{
|
||||
SEC_PKCS12ExportContext *p12ecx = NULL;
|
||||
SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
|
||||
SECItem pwitem = { siBuffer, NULL, 0 };
|
||||
PK11SlotInfo *slot = NULL;
|
||||
PK11SlotInfo *slotToUse = NULL;
|
||||
SSMControlConnection *ctrl;
|
||||
SSMStatus rv=SSM_FAILURE;
|
||||
int i;
|
||||
|
||||
if (cxt == NULL || certArr == NULL || numCerts == 0) {
|
||||
return SSM_ERR_BAD_REQUEST;
|
||||
}
|
||||
/*
|
||||
* We're about to send the UI event requesting the password to use
|
||||
* when encrypting
|
||||
*/
|
||||
SSM_LockResource(&cxt->super);
|
||||
cxt->m_inputProcessed = PR_FALSE;
|
||||
rv = SSMControlConnection_SendUIEvent(SSMRESOURCE(cxt)->m_connection,
|
||||
"get", "cert_backup",
|
||||
SSMRESOURCE(cxt),
|
||||
(numCerts > 1) ? "multipleCerts=1" :
|
||||
NULL,
|
||||
&SSMRESOURCE(cxt)->m_clientContext);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
SSM_UnlockResource(SSMRESOURCE(cxt));
|
||||
goto loser;
|
||||
}
|
||||
/*
|
||||
* Wait until the form is submitted to proceed. We'll get notified.
|
||||
*/
|
||||
SSM_WaitResource(SSMRESOURCE(cxt), PR_INTERVAL_NO_TIMEOUT);
|
||||
SSM_UnlockResource(SSMRESOURCE(cxt));
|
||||
if (cxt->m_password == NULL ||
|
||||
cxt->super.m_buttonType == SSM_BUTTON_CANCEL) {
|
||||
rv = SSM_ERR_NO_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
/* Wait for the dialog box to go down so that when it disappears,
|
||||
* the window doesn't take away the password prompt.
|
||||
*/
|
||||
PR_Sleep(PR_TicksPerSecond());
|
||||
|
||||
ctrl = SSMRESOURCE(cxt)->m_connection;
|
||||
pwitem.data = (unsigned char *) cxt->m_password;
|
||||
pwitem.len = strlen(cxt->m_password);
|
||||
PK11_FindObjectForCert(certArr[0], ctrl, &slot);
|
||||
if (slot == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
slotToUse = slot;
|
||||
if (forceAuthenticate && PK11_NeedLogin(slot)) {
|
||||
PK11_Logout(slot);
|
||||
}
|
||||
if (PK11_Authenticate(slot, PR_TRUE, ctrl) != SECSuccess) {
|
||||
rv = SSM_ERR_BAD_DB_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, ctrl);
|
||||
|
||||
if (p12ecx == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1)
|
||||
!= SECSuccess) {
|
||||
rv = SSM_ERR_BAD_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
for (i=0; i <numCerts; i++) {
|
||||
PK11_FindObjectForCert(certArr[i], ctrl, &slot);
|
||||
if (slot != slotToUse) {
|
||||
continue;
|
||||
}
|
||||
keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
|
||||
if (!SEC_PKCS12IsEncryptionAllowed() || PK11_IsFIPS()) {
|
||||
certSafe = keySafe;
|
||||
} else {
|
||||
certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, &pwitem,
|
||||
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
|
||||
}
|
||||
if (certSafe == NULL || keySafe == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, certArr[i],
|
||||
SSMRESOURCE(cxt)->m_connection->m_certdb,
|
||||
keySafe, NULL, PR_TRUE, &pwitem,
|
||||
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
|
||||
!= SECSuccess) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Done with the password, free it */
|
||||
PR_Free(cxt->m_password);
|
||||
cxt->m_password = NULL;
|
||||
rv = SSM_RequestFilePathFromUser(SSMRESOURCE(cxt),
|
||||
"pkcs12_export_file_prompt",
|
||||
"*.p12",
|
||||
PR_FALSE);
|
||||
if (rv != SSM_SUCCESS || cxt->super.m_fileName == NULL) {
|
||||
rv = SSM_ERR_BAD_FILENAME;
|
||||
goto loser;
|
||||
}
|
||||
cxt->m_file = PR_Open (cxt->super.m_fileName,
|
||||
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
0600);
|
||||
if (cxt->m_file == NULL) {
|
||||
rv = SSM_ERR_BAD_FILENAME;
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12Encode(p12ecx, ssmpkcs12context_writetoexportfile, cxt)
|
||||
!= SECSuccess) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
PR_Close(cxt->m_file);
|
||||
if (slotToUse) {
|
||||
PK11_FreeSlot(slotToUse);
|
||||
}
|
||||
SEC_PKCS12DestroyExportContext(p12ecx);
|
||||
return SSM_SUCCESS;
|
||||
loser:
|
||||
if (p12ecx != NULL) {
|
||||
SEC_PKCS12DestroyExportContext(p12ecx);
|
||||
}
|
||||
if (slot && cxt->m_cert && (slot != cxt->m_cert->slot)) {
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
PR_FREEIF(cxt->m_password);
|
||||
cxt->m_password = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* This function converts ASCII strings to UCS2 strings in Network Byte Order.
|
||||
** The "swapBytes" argument is ignored.
|
||||
** The PKCS#12 code only makes it true on Little Endian systems,
|
||||
** where it was intended to force the output into NBO.
|
||||
*/
|
||||
PRBool
|
||||
SSM_UCS2_ASCIIConversion(PRBool toUnicode,
|
||||
unsigned char *inBuf,
|
||||
unsigned int inBufLen,
|
||||
unsigned char *outBuf,
|
||||
unsigned int maxOutBufLen,
|
||||
unsigned int *outBufLen,
|
||||
PRBool swapBytes)
|
||||
{
|
||||
if (!inBuf || !outBuf || !outBufLen) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (toUnicode) {
|
||||
PRBool rv;
|
||||
#ifdef DEBUG
|
||||
unsigned int outLen;
|
||||
int i;
|
||||
fprintf(stderr,"\n---ssm_ConvertAsciiToUCS2---\nInput: inBuf= ");
|
||||
for (i = 0; i < inBufLen; i++) {
|
||||
fprintf(stderr, "%c", inBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\ninBufLen=%d\n", inBufLen);
|
||||
#endif
|
||||
rv = nlsASCIIToUnicode(inBuf, inBufLen,
|
||||
outBuf, maxOutBufLen, outBufLen);
|
||||
|
||||
#ifdef DEBUG
|
||||
outLen = *outBufLen;
|
||||
fprintf(stderr,"output: outBuf= ");
|
||||
for(i = 0; i < outLen; i++) {
|
||||
fprintf(stderr, "%c ", outBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\noutBuf= ");
|
||||
for(i = 0; i < outLen; i++) {
|
||||
fprintf(stderr,"%2x ", outBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\noutLen = %d\n", outLen);
|
||||
#endif /* DEBUG */
|
||||
|
||||
return rv;
|
||||
}
|
||||
PR_ASSERT(PR_FALSE); /* not supported yet */
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SSM_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
|
||||
unsigned int inBufLen,unsigned char *outBuf,
|
||||
unsigned int maxOutBufLen, unsigned int *outBufLen)
|
||||
{
|
||||
PRBool retval;
|
||||
#ifdef DEBUG
|
||||
unsigned int i;
|
||||
#endif
|
||||
|
||||
if(!inBuf || !outBuf || !outBufLen) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
*outBufLen = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"---UCS2_UTF8Conversion (%s) ---\nInput: \n",
|
||||
(toUnicode?"to UCS2":"to UTF8"));
|
||||
for(i=0; i< inBufLen; i++) {
|
||||
fprintf(stderr,"%c", (char) inBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
for(i=0; i< inBufLen; i++) {
|
||||
fprintf(stderr,"%2x ", (char) inBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
#endif
|
||||
|
||||
if(toUnicode) {
|
||||
retval = nlsUTF8ToUnicode(inBuf, inBufLen, outBuf, maxOutBufLen,
|
||||
outBufLen);
|
||||
} else {
|
||||
retval = nlsUnicodeToUTF8(inBuf, inBufLen, outBuf, maxOutBufLen,
|
||||
outBufLen);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"Output: \n");
|
||||
for(i=0; i< *outBufLen; i++) {
|
||||
fprintf(stderr,"%c", (char) outBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
for(i=0; i< *outBufLen; i++) {
|
||||
fprintf(stderr,"%2x ", (char) outBuf[i]);
|
||||
}
|
||||
fprintf(stderr,"\n\n");
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssmpkcs12context_digestopen(void *arg, PRBool readData)
|
||||
{
|
||||
char *tmpFileName=NULL;
|
||||
char filePathSep;
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg;
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
filePathSep = '/';
|
||||
#elif defined(WIN32)
|
||||
filePathSep = '\\';
|
||||
#elif defined(XP_MAC)
|
||||
filePathSep = ':';
|
||||
#else
|
||||
#error Tell me what the file path separator is of this platform.
|
||||
#endif
|
||||
|
||||
tmpFileName = PR_smprintf("%s%c%s",
|
||||
SSMRESOURCE(cxt)->m_connection->m_dirRoot,
|
||||
filePathSep,
|
||||
".nsm_p12_tmp");
|
||||
if (tmpFileName == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (readData) {
|
||||
cxt->m_digestFile = PR_Open(tmpFileName,
|
||||
PR_RDONLY, 0400);
|
||||
} else {
|
||||
cxt->m_digestFile = PR_Open(tmpFileName,
|
||||
PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE,
|
||||
0600);
|
||||
}
|
||||
cxt->m_tempFilePath = tmpFileName;
|
||||
if (cxt->m_digestFile == NULL) {
|
||||
cxt->m_error = PR_TRUE;
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssmpkcs12context_digestclose(void *arg, PRBool removeFile)
|
||||
{
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg;
|
||||
|
||||
if (cxt == NULL || cxt->m_digestFile == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
PR_Close(cxt->m_digestFile);
|
||||
cxt->m_digestFile = NULL;
|
||||
if (removeFile) {
|
||||
PR_Delete(cxt->m_tempFilePath);
|
||||
PR_Free(cxt->m_tempFilePath);
|
||||
cxt->m_tempFilePath = NULL;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
ssmpkcs12context_digestread(void *arg, unsigned char *buf, unsigned long len)
|
||||
{
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg;
|
||||
|
||||
if (cxt == NULL || cxt->m_digestFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (buf == NULL || len == 0) {
|
||||
return -1;
|
||||
}
|
||||
return PR_Read(cxt->m_digestFile, buf, len);
|
||||
}
|
||||
|
||||
static int
|
||||
ssmpkcs12context_digestwrite(void *arg, unsigned char *buf, unsigned long len)
|
||||
{
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg;
|
||||
|
||||
if (cxt == NULL || cxt->m_digestFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (buf == NULL || len == 0) {
|
||||
return -1;
|
||||
}
|
||||
return PR_Write(cxt->m_digestFile, buf, len);
|
||||
}
|
||||
|
||||
SECItem*
|
||||
SSM_NicknameCollisionCallback(SECItem *old_nick, PRBool *cancel,
|
||||
void *wincx)
|
||||
{
|
||||
/* We don't handle this yet */
|
||||
*cancel = PR_TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PK11SlotInfo*
|
||||
SSMPKCS12Context_ChooseSlotForImport(SSMPKCS12Context *cxt,
|
||||
PK11SlotList *slotList)
|
||||
{
|
||||
char mech[20];
|
||||
SSMStatus rv;
|
||||
|
||||
PR_snprintf(mech, 20, "mech=%d&task=import&unused=unused", CKM_RSA_PKCS);
|
||||
SSM_LockUIEvent(&cxt->super);
|
||||
rv = SSMControlConnection_SendUIEvent(cxt->super.m_connection,
|
||||
"get",
|
||||
"select_token",
|
||||
&cxt->super,
|
||||
mech, &SSMRESOURCE(cxt)->m_clientContext);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
SSM_UnlockResource(&cxt->super);
|
||||
return NULL;
|
||||
}
|
||||
SSM_WaitUIEvent(&cxt->super, PR_INTERVAL_NO_TIMEOUT);
|
||||
/* Wait so damn window goes away without swallowing up
|
||||
* the password prompt that will come up next.
|
||||
*/
|
||||
PR_Sleep(PR_TicksPerSecond());
|
||||
return (PK11SlotInfo*)cxt->super.m_uiData;
|
||||
}
|
||||
|
||||
static PK11SlotInfo*
|
||||
SSMPKCS12Context_GetSlotForImport(SSMPKCS12Context *cxt)
|
||||
{
|
||||
PK11SlotList *slotList;
|
||||
PK11SlotInfo *slot = NULL;
|
||||
|
||||
slotList = PK11_GetAllTokens(CKM_RSA_PKCS, PR_TRUE, PR_TRUE,
|
||||
cxt->super.m_connection);
|
||||
if (slotList == NULL || slotList->head == NULL) {
|
||||
/* Couldn't find a slot, let's try the internal slot
|
||||
* and see what happens
|
||||
*/
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
} else if (slotList->head->next == NULL) {
|
||||
/*
|
||||
* Only one slot, return it.
|
||||
*/
|
||||
slot = PK11_ReferenceSlot(slotList->head->slot);
|
||||
} else {
|
||||
slot = SSMPKCS12Context_ChooseSlotForImport(cxt, slotList);
|
||||
}
|
||||
if (slotList)
|
||||
PK11_FreeSlotList(slotList);
|
||||
return slot;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_RestoreCertFromPKCS12File(SSMPKCS12Context *cxt)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SECItem passwdReq;
|
||||
char *prompt=NULL;
|
||||
PK11SlotInfo *slot=NULL;
|
||||
SEC_PKCS12DecoderContext *p12dcx=NULL;
|
||||
PRBool swapUnicode = PR_FALSE;
|
||||
unsigned char *buf=NULL;
|
||||
SECItem pwItem = { siBuffer, NULL, 0 }, uniPwItem = { siBuffer, NULL, 0 };
|
||||
SECStatus srv;
|
||||
CERTCertList *certList=NULL;
|
||||
CERTCertListNode *node=NULL;
|
||||
PromptRequest request;
|
||||
|
||||
if (cxt == NULL || cxt->m_isExportContext) {
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
swapUnicode = PR_TRUE;
|
||||
#endif
|
||||
|
||||
rv = SSM_RequestFilePathFromUser(SSMRESOURCE(cxt),
|
||||
"pkcs12_import_file_prompt",
|
||||
"*.p12",
|
||||
PR_TRUE);
|
||||
if (rv != SSM_SUCCESS || cxt->super.m_fileName == NULL) {
|
||||
rv = SSM_ERR_BAD_FILENAME;
|
||||
goto loser;
|
||||
}
|
||||
prompt = SSM_GetCharFromKey("pkcs12_request_password_prompt",
|
||||
"ISO-8859-1");
|
||||
if (prompt == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
request.resID = SSMRESOURCE(cxt)->m_id;
|
||||
request.prompt = prompt;
|
||||
request.clientContext = SSMRESOURCE(cxt)->m_clientContext;
|
||||
if (CMT_EncodeMessage(PromptRequestTemplate, (CMTItem*)&passwdReq, &request) != CMTSuccess) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
passwdReq.type = (SECItemType) (SSM_EVENT_MESSAGE | SSM_PROMPT_EVENT);
|
||||
SSM_LockResource(SSMRESOURCE(cxt));
|
||||
cxt->m_password = NULL;
|
||||
rv = SSM_SendQMessage(SSMRESOURCE(cxt)->m_connection->m_controlOutQ,
|
||||
20,
|
||||
passwdReq.type,
|
||||
passwdReq.len,
|
||||
(char*)passwdReq.data,
|
||||
PR_TRUE);
|
||||
SSM_WaitResource(SSMRESOURCE(cxt), SSM_PASSWORD_WAIT_TIME);
|
||||
SSM_UnlockResource(SSMRESOURCE(cxt));
|
||||
if (cxt->m_password == NULL) {
|
||||
rv = SSM_ERR_NO_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
cxt->m_file = PR_Open(SSMRESOURCE(cxt)->m_fileName,
|
||||
PR_RDONLY, 0400);
|
||||
if (cxt->m_file == NULL) {
|
||||
rv = SSM_ERR_BAD_FILENAME;
|
||||
goto loser;
|
||||
}
|
||||
slot = SSMPKCS12Context_GetSlotForImport(cxt);
|
||||
if (slot == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (PK11_NeedLogin(slot)) {
|
||||
/* we should log out only if the slot needs login */
|
||||
PK11_Logout(slot);
|
||||
}
|
||||
|
||||
/* User has not initialize DB, ask for a password. */
|
||||
if (PK11_NeedUserInit(slot)) {
|
||||
rv = SSM_SetUserPassword(slot, SSMRESOURCE(cxt));
|
||||
if (rv != SSM_SUCCESS) {
|
||||
rv = SSM_ERR_NEED_USER_INIT_DB;
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
if (PK11_Authenticate(slot, PR_FALSE, SSMRESOURCE(cxt)->m_connection)
|
||||
!= SECSuccess) {
|
||||
rv = SSM_ERR_BAD_DB_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
pwItem.data = (unsigned char *) cxt->m_password;
|
||||
pwItem.len = strlen(cxt->m_password);
|
||||
if (SSM_UnicodeConversion(&uniPwItem, &pwItem, PR_TRUE,
|
||||
swapUnicode) != SECSuccess) {
|
||||
rv = SSM_ERR_BAD_PASSWORD;
|
||||
goto loser;
|
||||
}
|
||||
p12dcx = SEC_PKCS12DecoderStart(&uniPwItem, slot,
|
||||
SSMRESOURCE(cxt)->m_connection,
|
||||
ssmpkcs12context_digestopen,
|
||||
ssmpkcs12context_digestclose,
|
||||
ssmpkcs12context_digestread,
|
||||
ssmpkcs12context_digestwrite,
|
||||
cxt);
|
||||
if (p12dcx == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
buf = SSM_NEW_ARRAY(unsigned char, PKCS12_IN_BUFFER_SIZE);
|
||||
if (buf == NULL) {
|
||||
rv = SSM_ERR_OUT_OF_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
cxt->m_file = PR_Open(SSMRESOURCE(cxt)->m_fileName, PR_RDONLY, 0400);
|
||||
if (cxt->m_file == NULL) {
|
||||
rv = SSM_ERR_BAD_FILENAME;
|
||||
goto loser;
|
||||
}
|
||||
while (PR_TRUE) {
|
||||
int readLen = PR_Read(cxt->m_file, buf, PKCS12_IN_BUFFER_SIZE);
|
||||
if (readLen < 0) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
srv = SEC_PKCS12DecoderUpdate(p12dcx, buf, readLen);
|
||||
if (srv != SECSuccess || readLen != PKCS12_IN_BUFFER_SIZE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (srv != SECSuccess) {
|
||||
rv = SSM_ERR_CANNOT_DECODE;
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12DecoderValidateBags(p12dcx, SSM_NicknameCollisionCallback)
|
||||
!= SECSuccess) {
|
||||
if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) {
|
||||
rv = SSM_PKCS12_CERT_ALREADY_EXISTS;
|
||||
} else {
|
||||
rv = SSM_FAILURE;
|
||||
}
|
||||
goto loser;
|
||||
}
|
||||
if (SEC_PKCS12DecoderImportBags(p12dcx) != SECSuccess) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
PR_Close(cxt->m_file);
|
||||
cxt->m_file = NULL;
|
||||
PR_Free(prompt);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
certList = SEC_PKCS12DecoderGetCerts(p12dcx);
|
||||
if (certList != NULL) {
|
||||
for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
if ((node->cert->trust) &&
|
||||
(node->cert->trust->emailFlags & CERTDB_USER) &&
|
||||
CERT_VerifyCertNow(cxt->super.m_connection->m_certdb,
|
||||
node->cert, PR_TRUE, certUsageEmailSigner,
|
||||
cxt) == SSM_SUCCESS) {
|
||||
rv = SSM_UseAsDefaultEmailIfNoneSet(cxt->super.m_connection,
|
||||
node->cert, PR_FALSE);
|
||||
if (rv == SSM_SUCCESS) {
|
||||
/* We just made this cert the default new cert */
|
||||
rv = SSM_ERR_NEW_DEF_MAIL_CERT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CERT_DestroyCertList(certList);
|
||||
certList = NULL;
|
||||
}
|
||||
|
||||
SEC_PKCS12DecoderFinish(p12dcx);
|
||||
return (rv == SSM_ERR_NEW_DEF_MAIL_CERT) ? rv : SSM_SUCCESS;
|
||||
loser:
|
||||
if (cxt->m_file != NULL) {
|
||||
PR_Close(cxt->m_file);
|
||||
cxt->m_file = NULL;
|
||||
}
|
||||
if (prompt != NULL) {
|
||||
PR_Free(prompt);
|
||||
}
|
||||
if (slot != NULL) {
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
if (p12dcx != NULL) {
|
||||
SEC_PKCS12DecoderFinish(p12dcx);
|
||||
}
|
||||
if (buf != NULL) {
|
||||
PR_Free(buf);
|
||||
}
|
||||
cxt->m_error = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_ProcessPromptReply(SSMResource *res,
|
||||
char *reply)
|
||||
{
|
||||
SSMPKCS12Context *cxt = (SSMPKCS12Context*)res;
|
||||
|
||||
if (!SSM_IsAKindOf(res, SSM_RESTYPE_PKCS12_CONTEXT)) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
cxt->m_password = reply?PL_strdup(reply):NULL;
|
||||
SSM_LockResource(res);
|
||||
SSM_NotifyResource(res);
|
||||
SSM_UnlockResource(res);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Print(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParams,
|
||||
char **value,
|
||||
char **resultStr)
|
||||
{
|
||||
char mechStr[48];
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
|
||||
PR_ASSERT(resultStr != NULL);
|
||||
if (resultStr == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto done;
|
||||
}
|
||||
if (numParams) {
|
||||
rv = SSMResource_Print(res, fmt, numParams, value, resultStr);
|
||||
goto done;
|
||||
}
|
||||
PR_snprintf(mechStr, 48, "%d", CKM_RSA_PKCS);
|
||||
*resultStr = PR_smprintf(fmt, res->m_id, mechStr, "");
|
||||
|
||||
rv = (*resultStr == NULL) ? SSM_FAILURE : SSM_SUCCESS;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
void SSMPKCS12Context_BackupMultipleCertsThread(void *arg)
|
||||
{
|
||||
SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)arg;
|
||||
SSMStatus rv;
|
||||
SSMControlConnection *connection = p12Cxt->super.m_connection;
|
||||
PRIntn i;
|
||||
|
||||
SSM_RegisterThread("PKCS12", NULL);
|
||||
SSM_DEBUG("About to backup some certs.\n");
|
||||
|
||||
rv = SSMControlConnection_SendUIEvent(connection,
|
||||
"get", "backup_new_cert",
|
||||
&p12Cxt->super, NULL,
|
||||
&p12Cxt->super.m_clientContext);
|
||||
PR_ASSERT(SSMRESOURCE(p12Cxt)->m_buttonType == SSM_BUTTON_NONE);
|
||||
if (rv == SSM_SUCCESS) {
|
||||
while (SSMRESOURCE(p12Cxt)->m_buttonType == SSM_BUTTON_NONE) {
|
||||
SSM_WaitForOKCancelEvent(SSMRESOURCE(p12Cxt),
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Eventhough we tell Nova to use a context it provided to us,
|
||||
* it still tries to use the top-most window to bring up the
|
||||
* next dialog. Meaning I still have to insert this freakin'
|
||||
* sleep.
|
||||
*
|
||||
* XXX -javi
|
||||
*/
|
||||
PR_Sleep(PR_TicksPerSecond());
|
||||
#if 0
|
||||
/*
|
||||
* Disable this for now, until we figure out how we're really gonna
|
||||
* support putting multiple cert/key pairs in one P12 file.
|
||||
*/
|
||||
SSMPKCS12Context_CreatePKCS12FileForMultipleCerts(p12Cxt, PR_FALSE,
|
||||
p12Cxt->arg->certs,
|
||||
p12Cxt->arg->numCerts);
|
||||
#endif
|
||||
for (i=0; i<p12Cxt->arg->numCerts;i++) {
|
||||
p12Cxt->m_cert = p12Cxt->arg->certs[i];
|
||||
SSMPKCS12Context_CreatePKCS12File(p12Cxt, PR_FALSE);
|
||||
/*
|
||||
* ARGH!! If we do more than one, then Communicator crashes
|
||||
* because it tries to use a window that no longer exists as
|
||||
* the base for the next window.
|
||||
*/
|
||||
PR_Sleep(PR_TicksPerSecond());
|
||||
}
|
||||
PR_Free(p12Cxt->arg->certs);
|
||||
PR_Free(p12Cxt->arg);
|
||||
p12Cxt->arg = NULL;
|
||||
p12Cxt->m_thread = NULL;
|
||||
SSM_FreeResource(&p12Cxt->super);
|
||||
SSM_DEBUG("Done backing up certs.\n");
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_WarnPKCS12Incompatibility(SSMTextGenContext *cx)
|
||||
{
|
||||
SSMStatus rv;
|
||||
char *value;
|
||||
|
||||
rv = SSM_HTTPParamValue(cx->m_request, "multipleCerts", &value);
|
||||
PR_FREEIF(cx->m_result);
|
||||
cx->m_result = NULL;
|
||||
if (rv == SSM_SUCCESS) {
|
||||
rv = SSM_FindUTF8StringInBundles(cx, "pkcs12_incompatible_warn",
|
||||
&cx->m_result);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
cx->m_result = PL_strdup("");
|
||||
}
|
||||
} else {
|
||||
cx->m_result = PL_strdup("");
|
||||
}
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
121
security/psm/server/p12res.h
Normal file
121
security/psm/server/p12res.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef P12RES_H_
|
||||
#define P12RES_H_
|
||||
#include "resource.h"
|
||||
#include "ctrlconn.h"
|
||||
/*
|
||||
* Initially, this will only be used as a resource to use in doing UI
|
||||
* events necessary for PKCS12 operations.
|
||||
*/
|
||||
|
||||
typedef struct SSMPKCS12ContextStr SSMPKCS12Context;
|
||||
|
||||
typedef struct SSMPKCS12BackupThreadArgStr {
|
||||
CERTCertificate **certs;
|
||||
PRIntn numCerts;
|
||||
} SSMPKCS12BackupThreadArg;
|
||||
|
||||
struct SSMPKCS12ContextStr {
|
||||
SSMResource super;
|
||||
char *m_password;
|
||||
PRFileDesc *m_file;
|
||||
PRFileDesc *m_digestFile;
|
||||
char *m_tempFilePath;
|
||||
PRBool m_error;
|
||||
PRBool m_inputProcessed;
|
||||
PRBool m_isExportContext; /* We're either importing or exporting. */
|
||||
CERTCertificate *m_cert;
|
||||
PRThread *m_thread; /* A thread for doing backup when doing
|
||||
* CMMF.
|
||||
*/
|
||||
SSMPKCS12BackupThreadArg *arg;
|
||||
};
|
||||
|
||||
typedef struct SSMPKCS12CreateArgStr {
|
||||
PRBool isExportContext;
|
||||
} SSMPKCS12CreateArg;
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Create(void *arg, SSMControlConnection *ctrl,
|
||||
SSMResource **res);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Init(SSMControlConnection *ctrl, SSMPKCS12Context *res,
|
||||
SSMResourceType type, PRBool isExportContext);
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Destroy(SSMResource *res, PRBool doFree);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_FormSubmitHandler(SSMResource *res, HTTPRequest *req);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_Print(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParams,
|
||||
char **value,
|
||||
char **resultStr);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_CreatePKCS12File(SSMPKCS12Context *cxt,
|
||||
PRBool forceAuthenticate);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_RestoreCertFromPKCS12File(SSMPKCS12Context *cxt);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_ProcessPromptReply(SSMResource *res,
|
||||
char *reply);
|
||||
|
||||
PRBool
|
||||
SSM_UCS2_ASCIIConversion(PRBool toUnicode,
|
||||
unsigned char *inBuf, unsigned int inBufLen,
|
||||
unsigned char *outBuf, unsigned int maxOutBufLen,
|
||||
unsigned int *outBufLen, PRBool swapBytes);
|
||||
|
||||
PRBool
|
||||
SSM_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
|
||||
unsigned int inBufLen,unsigned char *outBuf,
|
||||
unsigned int maxOutBufLen, unsigned int *outBufLen);
|
||||
|
||||
SSMStatus
|
||||
SSMPKCS12Context_CreatePKCS12FileForMultipleCerts(SSMPKCS12Context *p12Cxt,
|
||||
PRBool forceAuthenticate,
|
||||
CERTCertificate **certArr,
|
||||
PRIntn numCerts);
|
||||
|
||||
void SSMPKCS12Context_BackupMultipleCertsThread(void *arg);
|
||||
#endif /*P12RES_H_*/
|
280
security/psm/server/p7cinfo.c
Normal file
280
security/psm/server/p7cinfo.c
Normal file
@ -0,0 +1,280 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "p7cinfo.h"
|
||||
#include "ssmerrs.h"
|
||||
|
||||
/* Shorthand macros for inherited classes */
|
||||
#define SSMRESOURCE(ci) (&(ci)->super)
|
||||
|
||||
SSMStatus
|
||||
SSMP7ContentInfo_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7ContentInfo *ci;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
ci = (SSMP7ContentInfo *) PR_CALLOC(sizeof(SSMP7ContentInfo));
|
||||
if (!ci) goto loser;
|
||||
|
||||
SSMRESOURCE(ci)->m_connection = connection;
|
||||
rv = SSMP7ContentInfo_Init(ci, connection, (SEC_PKCS7ContentInfo *) arg,
|
||||
SSM_RESTYPE_PKCS7_CONTENT_INFO);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMP7ContentInfo_Invariant(ci);
|
||||
|
||||
*res = SSMRESOURCE(ci);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (ci)
|
||||
{
|
||||
SSMRESOURCE(ci)->m_refCount = 1; /* force destroy */
|
||||
SSM_FreeResource(SSMRESOURCE(ci));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7ContentInfo_Init(SSMP7ContentInfo *ci, SSMControlConnection * conn,
|
||||
SEC_PKCS7ContentInfo *cinfo,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
/* Initialize superclass */
|
||||
rv = SSMResource_Init(conn, SSMRESOURCE(ci), type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Fill in the content info */
|
||||
PR_ASSERT(cinfo != NULL);
|
||||
ci->m_cinfo = cinfo;
|
||||
|
||||
/* Sanity check before returning */
|
||||
SSMP7ContentInfo_Invariant(ci);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
/* member destruct, if any are allocated, will happen in the
|
||||
_Destroy method */
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7ContentInfo_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMP7ContentInfo *ci = (SSMP7ContentInfo *) res;
|
||||
SSMP7ContentInfo_Invariant(ci);
|
||||
/* Destroy our members. */
|
||||
if (ci->m_cinfo)
|
||||
{
|
||||
SEC_PKCS7DestroyContentInfo(ci->m_cinfo);
|
||||
ci->m_cinfo = NULL;
|
||||
}
|
||||
|
||||
/* Destroy superclass. */
|
||||
SSMResource_Destroy(res, PR_FALSE);
|
||||
|
||||
/* Free if asked. */
|
||||
if (doFree)
|
||||
PR_Free(res);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMP7ContentInfo_Invariant(SSMP7ContentInfo *ci)
|
||||
{
|
||||
/* Superclass invariant */
|
||||
SSMResource_Invariant(SSMRESOURCE(ci));
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(ci));
|
||||
|
||||
/* Class check */
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(ci), SSM_RESTYPE_PKCS7_CONTENT_INFO));
|
||||
|
||||
/* Member check */
|
||||
PR_ASSERT(ci->m_cinfo != NULL);
|
||||
if (ci->m_signerCert)
|
||||
PR_ASSERT(SSM_IsAKindOf(&(ci->m_signerCert->super),SSM_RESTYPE_CERTIFICATE));
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(ci));
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7ContentInfo_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
rv = SSMResource_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 3) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_P7CINFO_IS_SIGNED;
|
||||
(*ids)[*count++] = SSM_FID_P7CINFO_IS_ENCRYPTED;
|
||||
(*ids)[*count++] = SSM_FID_P7CINFO_SIGNER_CERT;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7ContentInfo_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMP7ContentInfo *cinfo = (SSMP7ContentInfo *) res;
|
||||
SEC_PKCS7ContentInfo *info;
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
SSMP7ContentInfo_Invariant(cinfo);
|
||||
if (!cinfo)
|
||||
{
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(cinfo));
|
||||
info = cinfo->m_cinfo;
|
||||
if (!info)
|
||||
{
|
||||
rv = SSM_ERR_ATTRIBUTE_MISSING;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_P7CINFO_IS_SIGNED:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = SEC_PKCS7ContentIsSigned(cinfo->m_cinfo);
|
||||
rv = SSM_SUCCESS;
|
||||
break;
|
||||
case SSM_FID_P7CINFO_IS_ENCRYPTED:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = SEC_PKCS7ContentIsEncrypted(cinfo->m_cinfo);
|
||||
rv = SSM_SUCCESS;
|
||||
break;
|
||||
case SSM_FID_P7CINFO_SIGNER_CERT:
|
||||
/* Make sure we have a cert to return. */
|
||||
rv = SSM_ERR_ATTRIBUTE_MISSING; /* by default */
|
||||
|
||||
/* want signed data */
|
||||
if ((info->content.signedData) &&
|
||||
/* want signer info */
|
||||
(info->content.signedData->signerInfos) &&
|
||||
/* 1 and only 1 signer
|
||||
### mwelch what if we have more than one? */
|
||||
(info->content.signedData->signerInfos[0]) &&
|
||||
(info->content.signedData->signerInfos[1] == NULL))
|
||||
{
|
||||
/* Get the cert, wrap it in a resource, and return its ID. */
|
||||
CERTCertificate *cert =
|
||||
info->content.signedData->signerInfos[0]->cert;
|
||||
SSMResourceID certID;
|
||||
|
||||
if (!cert) goto loser; /* we could still have a null cert */
|
||||
|
||||
rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
|
||||
cert,
|
||||
SSMRESOURCE(cinfo)->m_connection,
|
||||
&certID,
|
||||
(SSMResource **) &cinfo->m_signerCert);
|
||||
SSMP7ContentInfo_Invariant(cinfo);
|
||||
|
||||
value->type = SSM_RID_ATTRIBUTE;
|
||||
rv = SSM_ClientGetResourceReference(&cinfo->m_signerCert->super,
|
||||
&certID);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
rv = SSM_SUCCESS;
|
||||
value->type = SSM_RID_ATTRIBUTE;
|
||||
value->u.numeric = certID;
|
||||
SSM_FreeResource(&cinfo->m_signerCert->super);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
rv = SSMResource_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
if (cinfo)
|
||||
SSM_UnlockResource(SSMRESOURCE(cinfo));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7ContentInfo_VerifyDetachedSignature(SSMP7ContentInfo *ci,
|
||||
SECCertUsage usage,
|
||||
HASH_HashType hash,
|
||||
PRBool keepCerts,
|
||||
PRIntn digestLen,
|
||||
char *detachedDigest)
|
||||
{
|
||||
SSMStatus rv = PR_FAILURE;
|
||||
SECItem digest;
|
||||
|
||||
SSMP7ContentInfo_Invariant(ci);
|
||||
|
||||
digest.len = digestLen;
|
||||
digest.data = (unsigned char*) detachedDigest;
|
||||
|
||||
if (ci->m_cinfo)
|
||||
{
|
||||
if (SEC_PKCS7VerifyDetachedSignature(ci->m_cinfo, usage,
|
||||
&digest, hash, keepCerts))
|
||||
rv = SSM_SUCCESS;
|
||||
}
|
||||
return rv;
|
||||
}
|
86
security/psm/server/p7cinfo.h
Normal file
86
security/psm/server/p7cinfo.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_P7CINFO_H__
|
||||
#define __SSM_P7CINFO_H__
|
||||
|
||||
#include "secpkcs7.h"
|
||||
#include "resource.h"
|
||||
#include "certres.h"
|
||||
|
||||
/* Initialization parameters for an SSMSSLSocketStatus. */
|
||||
|
||||
/*
|
||||
Wrapper for the SEC_PKCS7ContentInfo structure. This is generated by
|
||||
several calls within the PKCS7 library, including PKCS7 decoder streams.
|
||||
*/
|
||||
typedef struct SSMP7ContentInfo
|
||||
{
|
||||
SSMResource super;
|
||||
|
||||
SEC_PKCS7ContentInfo *m_cinfo;
|
||||
SSMResourceCert *m_signerCert;
|
||||
} SSMP7ContentInfo;
|
||||
|
||||
SSMStatus SSMP7ContentInfo_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMP7ContentInfo_Init(SSMP7ContentInfo *ss,
|
||||
SSMControlConnection * conn,
|
||||
SEC_PKCS7ContentInfo *cinfo,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMP7ContentInfo_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMP7ContentInfo_Invariant(SSMP7ContentInfo *ss);
|
||||
|
||||
SSMStatus SSMP7ContentInfo_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMP7ContentInfo_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
/*
|
||||
Functions which involve a PKCS7ContentInfo resource, but which
|
||||
aren't immediately germane to the object itself (if that makes
|
||||
sense)
|
||||
*/
|
||||
SSMStatus SSMP7ContentInfo_VerifyDetachedSignature(SSMP7ContentInfo *ci,
|
||||
SECCertUsage usage,
|
||||
HASH_HashType hash,
|
||||
PRBool keepCerts,
|
||||
PRIntn digestLen,
|
||||
char *detachedDigest);
|
||||
|
||||
|
||||
#endif
|
513
security/psm/server/p7dconn.c
Normal file
513
security/psm/server/p7dconn.c
Normal file
@ -0,0 +1,513 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "p7dconn.h"
|
||||
#include "serv.h"
|
||||
#include "servimpl.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "collectn.h"
|
||||
#include "secmime.h"
|
||||
|
||||
/* Shorthand macros for inherited classes */
|
||||
#define SSMRESOURCE(conn) (&(conn)->super.super.super)
|
||||
#define SSMCONNECTION(conn) (&(conn)->super.super)
|
||||
#define SSMDATACONNECTION(conn) (&(conn)->super)
|
||||
#define SSM_PARENT_CONN(conn) ((SSMControlConnection*)((conn)->super.super.m_parent))
|
||||
|
||||
void SSMP7DecodeConnection_ServiceThread(void * arg);
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_StartDecoding(SSMP7DecodeConnection *conn);
|
||||
|
||||
/* callbacks for PKCS7 decoder */
|
||||
void SSMP7DecodeConnection_ContentCallback(void *arg,
|
||||
const char *buf,
|
||||
unsigned long len);
|
||||
PK11SymKey * SSMP7DecodeConnection_GetDecryptKey(void *arg,
|
||||
SECAlgorithmID *algid);
|
||||
PRBool SSMP7DecodeConnection_DecryptionAllowed(SECAlgorithmID *algid,
|
||||
PK11SymKey *bulkkey);
|
||||
SECItem * SSMP7DecodeConnection_GetPasswordKey(void *arg,
|
||||
SECKEYKeyDBHandle *handle);
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_Create(void *arg,
|
||||
SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7DecodeConnection *conn;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMP7DecodeConnection *) PR_CALLOC(sizeof(SSMP7DecodeConnection));
|
||||
if (!conn) goto loser;
|
||||
|
||||
SSMRESOURCE(conn)->m_connection = connection;
|
||||
rv = SSMP7DecodeConnection_Init(conn, (SSMInfoP7Decode*) arg,
|
||||
SSM_RESTYPE_PKCS7_DECODE_CONNECTION);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMP7DecodeConnection_Invariant(conn);
|
||||
|
||||
*res = SSMRESOURCE(conn);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv); /* force destroy */
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_Init(SSMP7DecodeConnection *conn,
|
||||
SSMInfoP7Decode *info,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
rv = SSMDataConnection_Init(SSMDATACONNECTION(conn), info->ctrl, type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Start the decoder */
|
||||
if (SSMP7DecodeConnection_StartDecoding(conn) != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Save the client UI context */
|
||||
SSMRESOURCE(conn)->m_clientContext = info->clientContext;
|
||||
|
||||
/* Spin the service thread. */
|
||||
SSM_DEBUG("Creating decoder service thread.\n");
|
||||
|
||||
SSM_GetResourceReference(SSMRESOURCE(conn));
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread =
|
||||
SSM_CreateThread(SSMRESOURCE(conn),
|
||||
SSMP7DecodeConnection_ServiceThread);
|
||||
if (SSMDATACONNECTION(conn)->m_dataServiceThread == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7DecodeConnection_FinishDecoding(SSMP7DecodeConnection *conn)
|
||||
{
|
||||
SEC_PKCS7ContentInfo *p7info = NULL;
|
||||
SSMResourceID resID;
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
if (conn->m_cinfo)
|
||||
{
|
||||
SSM_FreeResource(&conn->m_cinfo->super);
|
||||
conn->m_cinfo = NULL;
|
||||
}
|
||||
|
||||
if (conn->m_context)
|
||||
{
|
||||
p7info = SEC_PKCS7DecoderFinish(conn->m_context);
|
||||
if (!p7info) {
|
||||
conn->m_error = PR_GetError();
|
||||
}
|
||||
conn->m_context = NULL;
|
||||
if (p7info)
|
||||
{
|
||||
rv = SSM_CreateResource(SSM_RESTYPE_PKCS7_CONTENT_INFO,
|
||||
p7info,
|
||||
SSM_PARENT_CONN(conn),
|
||||
&resID,
|
||||
(SSMResource **) &conn->m_cinfo);
|
||||
}
|
||||
else
|
||||
rv = PR_FAILURE;
|
||||
|
||||
SSM_LockResource(&conn->super.super.super);
|
||||
SSM_NotifyResource(&conn->super.super.super);
|
||||
SSM_UnlockResource(&conn->super.super.super);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7DecodeConnection_StartDecoding(SSMP7DecodeConnection *conn)
|
||||
{
|
||||
PR_ASSERT(conn->m_context == NULL);
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context)
|
||||
SSMP7DecodeConnection_FinishDecoding(conn);
|
||||
|
||||
conn->m_context =
|
||||
SEC_PKCS7DecoderStart(SSMP7DecodeConnection_ContentCallback,
|
||||
conn,
|
||||
SSMP7DecodeConnection_GetPasswordKey,
|
||||
conn,
|
||||
SSMP7DecodeConnection_GetDecryptKey,
|
||||
conn,
|
||||
SSMP7DecodeConnection_DecryptionAllowed);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
/* Did we get a context */
|
||||
if (!conn->m_context) {
|
||||
conn->m_error = PR_GetError();
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMP7DecodeConnection *conn = (SSMP7DecodeConnection *) res;
|
||||
|
||||
if (doFree)
|
||||
SSM_DEBUG("SSMP7DecodeConnection_Destroy called.\n");
|
||||
|
||||
/* We should be shut down. */
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Destroy our fields. */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context)
|
||||
SSMP7DecodeConnection_FinishDecoding(conn);
|
||||
|
||||
if (conn->m_cinfo)
|
||||
{
|
||||
SSM_FreeResource(&conn->m_cinfo->super);
|
||||
conn->m_cinfo = NULL;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
|
||||
/* Destroy superclass fields. */
|
||||
SSMDataConnection_Destroy(SSMRESOURCE(conn), PR_FALSE);
|
||||
|
||||
/* Free the connection object if asked. */
|
||||
if (doFree)
|
||||
PR_DELETE(conn);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMP7DecodeConnection_Invariant(SSMP7DecodeConnection *conn)
|
||||
{
|
||||
SSMDataConnection_Invariant(SSMDATACONNECTION(conn));
|
||||
/* our specific invariants */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
/* check class */
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn), SSM_RESTYPE_PKCS7_DECODE_CONNECTION));
|
||||
/* we should not be simultaneously decoded and decoding */
|
||||
if (conn->m_context)
|
||||
PR_ASSERT(conn->m_cinfo == NULL);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7DecodeConnection_Shutdown(SSMResource *arg, SSMStatus status)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
/* Call our superclass shutdown. */
|
||||
rv = SSMDataConnection_Shutdown(arg, status);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
PKCS7 decoding is performed by a single service thread. This thread
|
||||
feeds data from the outgoing queue into the PKCS7 decoder.
|
||||
*/
|
||||
void SSMP7DecodeConnection_ServiceThread(void * arg)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7DecodeConnection* conn;
|
||||
SSMControlConnection* ctrl;
|
||||
SECItem* msg;
|
||||
PRIntn read;
|
||||
char buffer[LINESIZE+1] = {0};
|
||||
|
||||
SSM_RegisterNewThread("p7decode", (SSMResource *) arg);
|
||||
conn = (SSMP7DecodeConnection *)arg;
|
||||
SSM_DEBUG("initializing.\n");
|
||||
if (!arg)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread = PR_GetCurrentThread();
|
||||
|
||||
/* set up the client data socket and authenticate it with nonce */
|
||||
rv = SSMDataConnection_SetupClientSocket(SSMDATACONNECTION(conn));
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Start decoding */
|
||||
SSM_DEBUG("Start updating decoder..\n");
|
||||
while ((SSMRESOURCE(conn)->m_status == PR_SUCCESS) &&
|
||||
(SSM_Count(SSMDATACONNECTION(conn)->m_shutdownQ) == 0) &&
|
||||
(rv == PR_SUCCESS)) {
|
||||
read = LINESIZE; /* set the read size to the default line size */
|
||||
rv = SSMDataConnection_ReadFromSocket(SSMDATACONNECTION(conn),
|
||||
(PRInt32*)&read, buffer);
|
||||
|
||||
if (read > 0) {
|
||||
/* there is data, pass it along to PKCS7 */
|
||||
SSM_DEBUG("Received %ld bytes of data for decoder.\n", read);
|
||||
PR_ASSERT(conn->m_context);
|
||||
if (SEC_PKCS7DecoderUpdate(conn->m_context, buffer, read) != SECSuccess) {
|
||||
conn->m_error = PR_GetError();
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
/* either EOF or an error condition */
|
||||
/* If we have a decoder in progress, stop it. */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context) {
|
||||
SSM_DEBUG("Stopping PKCS7 decoder, generating content info struct.\n");
|
||||
SSMP7DecodeConnection_FinishDecoding(conn);
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
/* we have an EOF, shut down the client socket */
|
||||
PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL);
|
||||
if (SSMDATACONNECTION(conn)->m_clientSocket != NULL) {
|
||||
SSM_DEBUG("shutting down client socket.\n");
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_Shutdown(SSMDATACONNECTION(conn)->m_clientSocket,
|
||||
PR_SHUTDOWN_SEND);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
/* If we've been asked to return the result, return it. */
|
||||
if (SSMDATACONNECTION(conn)->m_sendResult) {
|
||||
SSM_DEBUG("Responding to deferred content info request.\n");
|
||||
|
||||
msg = (SECItem*)PORT_ZAlloc(sizeof(SECItem));
|
||||
PR_ASSERT(msg != NULL); /* need to have some preallocated
|
||||
failure to send */
|
||||
if (conn->m_cinfo) {
|
||||
SSMAttributeValue value;
|
||||
GetAttribReply reply;
|
||||
|
||||
value.type = SSM_RID_ATTRIBUTE;
|
||||
rv = SSM_ClientGetResourceReference(&conn->m_cinfo->super,
|
||||
&value.u.rid);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE);
|
||||
reply.result = SSM_SUCCESS;
|
||||
reply.value = value;
|
||||
if (CMT_EncodeMessage(GetAttribReplyTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated a reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
/*
|
||||
* We don't need the content info anymore since we sent it back
|
||||
* Is it OK to release our reference?
|
||||
*/
|
||||
SSM_FreeResource(&conn->m_cinfo->super);
|
||||
conn->m_cinfo = NULL;
|
||||
}
|
||||
else {
|
||||
SingleNumMessage reply;
|
||||
|
||||
msg->type = (SECItemType) (SSM_REPLY_ERR_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE);
|
||||
reply.value = SSM_ERR_ATTRIBUTE_MISSING;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated error reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
}
|
||||
/* Post this message to the parent's control queue
|
||||
for delivery back to the client. */
|
||||
ctrl = (SSMControlConnection*)(SSMCONNECTION(conn)->m_parent);
|
||||
PR_ASSERT(SSM_IsAKindOf(&ctrl->super.super, SSM_RESTYPE_CONTROL_CONNECTION));
|
||||
rv = SSM_SendQMessage(ctrl->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
msg->type, msg->len,
|
||||
(char*)msg->data, PR_TRUE);
|
||||
SSM_FreeMessage(msg);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
SSM_DEBUG("** Thread shutting down ** (%ld)\n", rv);
|
||||
if (conn != NULL) {
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7DecodeConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMDataConnection_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 1) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_P7CONN_CONTENT_INFO;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7DecodeConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7DecodeConnection *dc = (SSMP7DecodeConnection *) res;
|
||||
|
||||
SSMP7DecodeConnection_Invariant(dc);
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_P7CONN_CONTENT_INFO:
|
||||
if (!dc->m_cinfo) {
|
||||
SSM_LockResource(res);
|
||||
SSM_WaitResource(res, PR_TicksPerSecond());
|
||||
SSM_UnlockResource(res);
|
||||
/*
|
||||
* If it's still NULL, then something really bad happened.
|
||||
*/
|
||||
if (!dc->m_cinfo)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Allocate a resource ID */
|
||||
value->type = SSM_RID_ATTRIBUTE;
|
||||
rv = SSM_ClientGetResourceReference(&dc->m_cinfo->super, &value->u.rid);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
/* Let's get rid of our reference to it and let the client inherit it.
|
||||
*/
|
||||
SSM_LockResource(res);
|
||||
SSM_FreeResource(&dc->m_cinfo->super);
|
||||
dc->m_cinfo = NULL;
|
||||
SSM_UnlockResource(res);
|
||||
break;
|
||||
|
||||
case SSM_FID_RESOURCE_ERROR:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = dc->m_error;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMDataConnection_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Callback functions for decoder. For now, use empty/default functions. */
|
||||
void SSMP7DecodeConnection_ContentCallback(void *arg,
|
||||
const char *buf,
|
||||
unsigned long len)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSMP7DecodeConnection *conn = (SSMP7DecodeConnection *)arg;
|
||||
PRIntn sent = 0;
|
||||
|
||||
SSM_DEBUG("writing data to socket.\n");
|
||||
PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL);
|
||||
sent = PR_Send(SSMDATACONNECTION(conn)->m_clientSocket, (void*)buf,
|
||||
(PRIntn)len, 0, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (sent != (PRIntn)len) {
|
||||
rv = PR_GetError();
|
||||
SSM_DEBUG("error writing data: %d \n", rv);
|
||||
}
|
||||
}
|
||||
|
||||
PK11SymKey * SSMP7DecodeConnection_GetDecryptKey(void *arg,
|
||||
SECAlgorithmID *algid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRBool SSMP7DecodeConnection_DecryptionAllowed(SECAlgorithmID *algid,
|
||||
PK11SymKey *bulkkey)
|
||||
{
|
||||
return SECMIME_DecryptionAllowed(algid, bulkkey);
|
||||
}
|
||||
|
||||
SECItem * SSMP7DecodeConnection_GetPasswordKey(void *arg,
|
||||
SECKEYKeyDBHandle *handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
81
security/psm/server/p7dconn.h
Normal file
81
security/psm/server/p7dconn.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_P7DCONN_H__
|
||||
#define __SSM_P7DCONN_H__
|
||||
|
||||
#include "prerror.h"
|
||||
#include "secpkcs7.h"
|
||||
|
||||
#include "dataconn.h"
|
||||
#include "p7cinfo.h"
|
||||
|
||||
/* Initialization parameters for an SSMP7DecodeConnection. */
|
||||
typedef struct SSMInfoP7Decode {
|
||||
SSMControlConnection *ctrl;
|
||||
CMTItem clientContext;
|
||||
} SSMInfoP7Decode;
|
||||
|
||||
/*
|
||||
PKCS7 decoder data connections.
|
||||
*/
|
||||
|
||||
typedef struct SSMP7DecodeConnection
|
||||
{
|
||||
SSMDataConnection super;
|
||||
|
||||
SEC_PKCS7DecoderContext *m_context;
|
||||
SSMP7ContentInfo *m_cinfo;
|
||||
PRInt32 m_error;
|
||||
} SSMP7DecodeConnection;
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMP7DecodeConnection_Init(SSMP7DecodeConnection *conn,
|
||||
SSMInfoP7Decode *info,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMP7DecodeConnection_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMP7DecodeConnection_Invariant(SSMP7DecodeConnection *conn);
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_Shutdown(SSMResource *arg, SSMStatus status);
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMP7DecodeConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
#endif
|
450
security/psm/server/p7econn.c
Normal file
450
security/psm/server/p7econn.c
Normal file
@ -0,0 +1,450 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "p7econn.h"
|
||||
#include "serv.h"
|
||||
#include "servimpl.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "collectn.h"
|
||||
|
||||
/* Shorthand macros for inherited classes */
|
||||
#define SSMRESOURCE(conn) (&(conn)->super.super.super)
|
||||
#define SSMCONNECTION(conn) (&(conn)->super.super)
|
||||
#define SSMDATACONNECTION(conn) (&(conn)->super)
|
||||
#define SSM_PARENT_CONN(conn) ((SSMControlConnection*)((conn)->super.super.m_parent))
|
||||
|
||||
void SSMP7EncodeConnection_ServiceThread(void * arg);
|
||||
|
||||
/* callbacks for PKCS7 encoder */
|
||||
void SSMP7EncodeConnection_ContentCallback(void *arg,
|
||||
const char *buf,
|
||||
unsigned long len);
|
||||
SECItem * SSMP7EncodeConnection_GetPasswordKey(void *arg,
|
||||
SECKEYKeyDBHandle *handle);
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_Create(void *arg,
|
||||
SSMControlConnection *connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7EncodeConnection *conn;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMP7EncodeConnection *) PR_CALLOC(sizeof(SSMP7EncodeConnection));
|
||||
if (!conn)
|
||||
goto loser;
|
||||
|
||||
SSMRESOURCE(conn)->m_connection = connection;
|
||||
rv = SSMP7EncodeConnection_Init(conn, (SSMInfoP7Encode *) arg,
|
||||
SSM_RESTYPE_PKCS7_ENCODE_CONNECTION);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
SSMP7EncodeConnection_Invariant(conn);
|
||||
|
||||
*res = SSMRESOURCE(conn);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
|
||||
if (conn) {
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv); /* force destroy */
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_Init(SSMP7EncodeConnection *conn,
|
||||
SSMInfoP7Encode *info,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7ContentInfo *cinfo;
|
||||
|
||||
rv = SSMDataConnection_Init(SSMDATACONNECTION(conn), info->ctrl, type);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Spin the service thread. */
|
||||
SSM_DEBUG("Creating encoder service thread.\n");
|
||||
|
||||
SSM_GetResourceReference(SSMRESOURCE(conn));
|
||||
|
||||
rv = SSMControlConnection_GetResource(SSM_PARENT_CONN(conn), info->ciRID,
|
||||
(SSMResource **)&cinfo);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
conn->m_cinfo = cinfo;
|
||||
|
||||
/* Save the client UI context */
|
||||
SSMRESOURCE(conn)->m_clientContext = info->clientContext;
|
||||
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread =
|
||||
SSM_CreateThread(SSMRESOURCE(conn),
|
||||
SSMP7EncodeConnection_ServiceThread);
|
||||
if (SSMDATACONNECTION(conn)->m_dataServiceThread == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7EncodeConnection_FinishEncoding(SSMP7EncodeConnection *conn)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_cinfo) {
|
||||
SSM_FreeResource(&conn->m_cinfo->super);
|
||||
conn->m_cinfo = NULL;
|
||||
}
|
||||
|
||||
if (conn->m_context) {
|
||||
conn->m_retValue = SEC_PKCS7EncoderFinish(conn->m_context,
|
||||
SSMP7EncodeConnection_GetPasswordKey,
|
||||
conn);
|
||||
conn->m_error = PR_GetError();
|
||||
conn->m_context = NULL;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7EncodeConnection_StartEncoding(SSMP7EncodeConnection *conn)
|
||||
{
|
||||
PR_ASSERT(conn->m_context == NULL);
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context)
|
||||
SSMP7EncodeConnection_FinishEncoding(conn);
|
||||
|
||||
conn->m_context =
|
||||
SEC_PKCS7EncoderStart(conn->m_cinfo->m_cinfo,
|
||||
SSMP7EncodeConnection_ContentCallback,
|
||||
conn, NULL);
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMP7EncodeConnection *conn = (SSMP7EncodeConnection *) res;
|
||||
|
||||
if (doFree)
|
||||
SSM_DEBUG("SSMHashConnection_Destroy called.\n");
|
||||
|
||||
/* We should be shut down. */
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Destroy our fields. */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context)
|
||||
SSMP7EncodeConnection_FinishEncoding(conn);
|
||||
|
||||
if (conn->m_cinfo) {
|
||||
SSM_FreeResource(&conn->m_cinfo->super);
|
||||
conn->m_cinfo = NULL;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
|
||||
/* Destroy superclass fields. */
|
||||
SSMDataConnection_Destroy(SSMRESOURCE(conn), PR_FALSE);
|
||||
|
||||
/* Free the connection object if asked. */
|
||||
if (doFree)
|
||||
PR_DELETE(conn);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMP7EncodeConnection_Invariant(SSMP7EncodeConnection *conn)
|
||||
{
|
||||
SSMDataConnection_Invariant(SSMDATACONNECTION(conn));
|
||||
/* our specific invariants */
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
/* check class */
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn),
|
||||
SSM_RESTYPE_PKCS7_ENCODE_CONNECTION));
|
||||
/* we should not be simultaneously encoded and encoding */
|
||||
if (conn->m_context)
|
||||
PR_ASSERT(conn->m_cinfo != NULL);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMP7EncodeConnection_Shutdown(SSMResource *arg, SSMStatus status)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
/* Call our superclass shutdown. */
|
||||
rv = SSMDataConnection_Shutdown(arg, status);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
PKCS7 decoding is performed by a single service thread. This thread
|
||||
feeds data from the outgoing queue into the PKCS7 encoder.
|
||||
*/
|
||||
void SSMP7EncodeConnection_ServiceThread(void * arg)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMP7EncodeConnection * conn;
|
||||
SSMControlConnection *ctrl;
|
||||
SECItem *msg;
|
||||
PRIntn read;
|
||||
char buffer[LINESIZE+1] = {0};
|
||||
|
||||
SSM_RegisterNewThread("p7encode", (SSMResource *) arg);
|
||||
conn = (SSMP7EncodeConnection *)arg;
|
||||
SSM_DEBUG("initializing.\n");
|
||||
if (!arg) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSMDATACONNECTION(conn)->m_dataServiceThread = PR_GetCurrentThread();
|
||||
|
||||
/* set up the client data socket and authenticate it with nonce */
|
||||
rv = SSMDataConnection_SetupClientSocket(SSMDATACONNECTION(conn));
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Start encoding */
|
||||
SSM_DEBUG("Creating encoder.\n");
|
||||
SSMP7EncodeConnection_StartEncoding(conn);
|
||||
|
||||
while ((SSMRESOURCE(conn)->m_status == PR_SUCCESS) &&
|
||||
(SSM_Count(SSMDATACONNECTION(conn)->m_shutdownQ) == 0) &&
|
||||
(rv == PR_SUCCESS)) {
|
||||
read = LINESIZE; /* set the read size to the default line size */
|
||||
rv = SSMDataConnection_ReadFromSocket(SSMDATACONNECTION(conn),
|
||||
(PRInt32*)&read, buffer);
|
||||
|
||||
if (read > 0) {
|
||||
/* there is data, pass it along to PKCS7 */
|
||||
SSM_DEBUG("Received %ld bytes of data for encoder.\n", read);
|
||||
PR_ASSERT(conn->m_context);
|
||||
SEC_PKCS7EncoderUpdate(conn->m_context, buffer, read);
|
||||
}
|
||||
else {
|
||||
/* either EOF or an error condition */
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
SSM_DEBUG("Stopping PKCS7 encoder.\n");
|
||||
|
||||
/* If we have a encoder in progress, stop it. */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
if (conn->m_context) {
|
||||
SSMP7EncodeConnection_FinishEncoding(conn);
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
if (rv == PR_SUCCESS) {
|
||||
/* we have an EOF, shut down the client socket. */
|
||||
PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL);
|
||||
if (SSMDATACONNECTION(conn)->m_clientSocket != NULL) {
|
||||
SSM_DEBUG("shutting down client socket.\n");
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_Shutdown(SSMDATACONNECTION(conn)->m_clientSocket,
|
||||
PR_SHUTDOWN_SEND);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we've been asked to return the result, return it. */
|
||||
if (SSMDATACONNECTION(conn)->m_sendResult) {
|
||||
SSM_DEBUG("Responding to deferred content info request.\n");
|
||||
|
||||
msg = (SECItem*)PORT_ZAlloc(sizeof(SECItem));
|
||||
PR_ASSERT(msg != NULL); /* need to have some preallocated
|
||||
failure to send */
|
||||
if (conn->m_cinfo) {
|
||||
SSMAttributeValue value;
|
||||
GetAttribReply reply;
|
||||
|
||||
value.type = SSM_RID_ATTRIBUTE;
|
||||
rv = SSM_ClientGetResourceReference(&conn->m_cinfo->super,
|
||||
&value.u.rid);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE);
|
||||
reply.value = value;
|
||||
reply.result = SSM_SUCCESS;
|
||||
if (CMT_EncodeMessage(GetAttribReplyTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated a reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
} else {
|
||||
SingleNumMessage reply;
|
||||
|
||||
msg->type = (SECItemType) (SSM_REPLY_ERR_MESSAGE | SSM_RESOURCE_ACTION
|
||||
| SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE);
|
||||
reply.value = SSM_ERR_ATTRIBUTE_MISSING;
|
||||
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DEBUG("Generated error reply (t %lx/l %ld/d %lx)\n",
|
||||
msg->type, msg->len, msg->data);
|
||||
}
|
||||
/* Post this message to the parent's control queue
|
||||
for delivery back to the client. */
|
||||
ctrl = (SSMControlConnection*)(SSMCONNECTION(conn)->m_parent);
|
||||
PR_ASSERT(SSM_IsAKindOf(&ctrl->super.super,
|
||||
SSM_RESTYPE_CONTROL_CONNECTION));
|
||||
rv = SSM_SendQMessage(ctrl->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
msg->type, msg->len,
|
||||
(char*)msg->data, PR_TRUE);
|
||||
SSM_FreeMessage(msg);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
SSM_DEBUG("** Thread shutting down ** (%ld)\n", rv);
|
||||
if (conn != NULL) {
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback functions for encoder. For now, use empty/default functions. */
|
||||
void SSMP7EncodeConnection_ContentCallback(void *arg,
|
||||
const char *buf,
|
||||
unsigned long len)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSMP7EncodeConnection *conn = (SSMP7EncodeConnection *)arg;
|
||||
PRIntn sent = 0;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
SSM_DEBUG("writing data to socket.\n");
|
||||
PR_ASSERT(SSMDATACONNECTION(conn)->m_clientSocket != NULL);
|
||||
sent = PR_Send(SSMDATACONNECTION(conn)->m_clientSocket, (void*)buf,
|
||||
(PRIntn)len, 0, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (sent != (PRIntn)len) {
|
||||
rv = PR_GetError();
|
||||
SSM_DEBUG("error writing data: %d \n", rv);
|
||||
}
|
||||
}
|
||||
|
||||
SECItem * SSMP7EncodeConnection_GetPasswordKey(void *arg,
|
||||
SECKEYKeyDBHandle *handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
switch(attrID) {
|
||||
case SSM_FID_CLIENT_CONTEXT:
|
||||
SSM_DEBUG("Setting PKCS7 Encode client context\n");
|
||||
if (value->type != SSM_STRING_ATTRIBUTE) {
|
||||
goto loser;
|
||||
}
|
||||
if (!(res->m_clientContext.data = (unsigned char *) PR_Malloc(value->u.string.len))) {
|
||||
goto loser;
|
||||
}
|
||||
memcpy(res->m_clientContext.data, value->u.string.data, value->u.string.len);
|
||||
res->m_clientContext.len = value->u.string.len;
|
||||
break;
|
||||
default:
|
||||
SSM_DEBUG("Got unknown P7 Encoder Set Attribute Request %d\n", attrID);
|
||||
goto loser;
|
||||
break;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMP7EncodeConnection *ec = (SSMP7EncodeConnection*)res;
|
||||
|
||||
SSMP7EncodeConnection_Invariant(ec);
|
||||
|
||||
switch (attrID) {
|
||||
case SSM_FID_P7CONN_RETURN_VALUE:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = ec->m_retValue;
|
||||
break;
|
||||
case SSM_FID_P7CONN_ERROR_VALUE:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = ec->m_error;
|
||||
break;
|
||||
default:
|
||||
SSM_DEBUG("Got unknown P7 Encoder Set Attribute Request %d\n", attrID);
|
||||
goto loser;
|
||||
break;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
87
security/psm/server/p7econn.h
Normal file
87
security/psm/server/p7econn.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_P7ECONN_H__
|
||||
#define __SSM_P7ECONN_H__
|
||||
|
||||
#include "prerror.h"
|
||||
#include "secpkcs7.h"
|
||||
|
||||
#include "dataconn.h"
|
||||
#include "p7cinfo.h"
|
||||
|
||||
/*
|
||||
PKCS7 encoder data connections.
|
||||
*/
|
||||
|
||||
/* Initialization parameters for an SSMP7EncodeConnection. */
|
||||
typedef struct SSMInfoP7Encode {
|
||||
SSMControlConnection *ctrl;
|
||||
SSMResourceID ciRID;
|
||||
CMTItem clientContext;
|
||||
} SSMInfoP7Encode;
|
||||
|
||||
typedef struct SSMP7EncodeConnection {
|
||||
SSMDataConnection super;
|
||||
|
||||
SEC_PKCS7EncoderContext *m_context;
|
||||
SSMP7ContentInfo *m_cinfo;
|
||||
PRInt32 m_retValue;
|
||||
PRInt32 m_error;
|
||||
} SSMP7EncodeConnection;
|
||||
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMP7EncodeConnection_Init(SSMP7EncodeConnection *conn,
|
||||
SSMInfoP7Encode *info,
|
||||
SSMResourceType type);
|
||||
SSMStatus SSMP7EncodeConnection_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMP7EncodeConnection_Invariant(SSMP7EncodeConnection *conn);
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_Shutdown(SSMResource *arg, SSMStatus status);
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMP7EncodeConnection_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
#endif /* __SSM_P7ECONN_H__ */
|
947
security/psm/server/password.c
Normal file
947
security/psm/server/password.c
Normal file
@ -0,0 +1,947 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "connect.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "prinrval.h"
|
||||
#include "crmf.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "minihttp.h"
|
||||
#include "textgen.h"
|
||||
#include "sechash.h"
|
||||
#include "pk11func.h"
|
||||
|
||||
extern SSMHashTable * tokenList;
|
||||
extern PRMonitor * tokenLock;
|
||||
|
||||
#define SSMRESOURCE(conn) (&(conn)->super)
|
||||
|
||||
/* Make these into functions? */
|
||||
#if 0
|
||||
#define SSM_PARENT_CONN(x) ((((SSMConnection *)(x))->m_parent) != NULL)? \
|
||||
(((SSMControlConnection *)(((SSMConnection *)(x))->m_parent))):\
|
||||
((SSMControlConnection *)x)
|
||||
#define SSM_PWD_TABLE(x) (SSM_PARENT_CONN(x))->m_passwdTable
|
||||
|
||||
#define SSM_OUT_QUEUE(x) (SSM_PARENT_CONN(x))->m_controlOutQ
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
SSMControlConnection * SSM_PARENT_CONN (SSMConnection * x)
|
||||
{
|
||||
return (((((SSMConnection *)(x))->m_parent) != NULL)?
|
||||
(((SSMControlConnection *)(((SSMConnection *)(x))->m_parent))):
|
||||
((SSMControlConnection *)x));
|
||||
}
|
||||
|
||||
SSMHashTable * SSM_PWD_TABLE(SSMConnection * x)
|
||||
{
|
||||
return (SSM_PARENT_CONN(x)->m_passwdTable);
|
||||
}
|
||||
|
||||
SSMCollection * SSM_OUT_QUEUE(SSMConnection * x)
|
||||
{
|
||||
return (SSM_PARENT_CONN(x)->m_controlOutQ);
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 SSM_GetTokenKey(PK11SlotInfo * slot)
|
||||
{
|
||||
return ((PK11_GetSlotID(slot)<<16) | PK11_GetModuleID(slot));
|
||||
}
|
||||
|
||||
char * SSM_GetPasswdCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
|
||||
{
|
||||
return SSM_GetAuthentication(slot, retry, PR_FALSE, (SSMResource*)arg);
|
||||
}
|
||||
|
||||
/* Do a couple of things in this functions:
|
||||
* 1) Get a password from user, and authenticate to token.
|
||||
* 2) Save this password encrypted in the global Cartman tokenList
|
||||
* for future reference.
|
||||
* Need to save password in case other users will need to authenticate
|
||||
* to the same tokens, so we make sure they're using the correct
|
||||
* passwords.
|
||||
* 3) Save this password encrypted in the control connection table in
|
||||
* case we will need to use it again.
|
||||
*/
|
||||
char * SSM_GetAuthentication(PK11SlotInfo * slot, PRBool retry, PRBool init,
|
||||
SSMResource * res)
|
||||
{
|
||||
PRInt32 tokenKey;
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
char * passwd = NULL, * tmp = NULL;
|
||||
PRBool first = PR_FALSE;
|
||||
SSM_TokenInfo * info = NULL, * infoLocal = NULL;
|
||||
SSMConnection *conn = &(res->m_connection->super);
|
||||
|
||||
tokenKey = SSM_GetTokenKey(slot);
|
||||
|
||||
/* register as interested in a password */
|
||||
SSM_PARENT_CONN(conn)->m_waiting++;
|
||||
|
||||
/* Get passwd table lock. */
|
||||
SSM_LockPasswdTable(conn);
|
||||
/* Look for entry for moduleID/slotID. */
|
||||
rv = SSM_HashFind(SSM_PWD_TABLE(conn), tokenKey, (void **)&passwd);
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
if (rv != PR_SUCCESS) {
|
||||
first = PR_TRUE;
|
||||
/* no entry found, we are the first to authenticate to this slot */
|
||||
SSM_DEBUG("%ld: creating passwd table entry for %s \n",
|
||||
conn, PK11_GetSlotName(slot));
|
||||
SSM_LockPasswdTable(conn);
|
||||
rv = SSM_HashInsert(SSM_PWD_TABLE(conn),tokenKey,(void *)SSM_NO_PASSWORD);
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: could not create entry in password table\n", conn);
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_AskUserPassword(res, slot, retry, init);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: error sending password request event\n", conn);
|
||||
goto loser;
|
||||
}
|
||||
} /* end of the we-are-first-to-request-this-passwd-clause */
|
||||
|
||||
/* If no password found, wait for it */
|
||||
if (!passwd || passwd == (char *)SSM_NO_PASSWORD) {
|
||||
rv = SSMControlConnection_WaitPassword(conn, tokenKey, &passwd);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (((int) passwd) == SSM_CANCEL_PASSWORD) {
|
||||
/* no password was provided or user hit "Cancel" */
|
||||
SSM_LockPasswdTable(conn);
|
||||
rv = SSM_HashRemove(SSM_PWD_TABLE(conn), tokenKey, (void **)&passwd);
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
if (rv != SSM_SUCCESS)
|
||||
SSM_DEBUG("SSM_GetAuthentication: user hit Cancel, can't remove password from connection table\n");
|
||||
passwd = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
/* We were the first to request the password,
|
||||
* so we need to enter it in to the token list.
|
||||
*/
|
||||
/* encrypt the password */
|
||||
if (SSM_EncryptPasswd(slot, passwd, &info) != SSM_SUCCESS) {
|
||||
SSM_DEBUG("%ld: could not encrypt password\n.", conn);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Place encrypted passwd in Cartman-wide tokenList */
|
||||
PR_EnterMonitor(tokenLock);
|
||||
/* Remove from tokenList if already on the list - must be stale */
|
||||
rv = SSM_HashRemove(tokenList, tokenKey, (void **)&tmp);
|
||||
if (rv == SSM_SUCCESS && tmp && tmp != (char *)SSM_NO_PASSWORD
|
||||
&& tmp != (char *)SSM_CANCEL_PASSWORD) { /* free stale data */
|
||||
PR_Free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
rv = SSM_HashInsert(tokenList, tokenKey, info);
|
||||
PR_ExitMonitor(tokenLock);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: can't create encr passwd entry\n", conn, tokenKey);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Store encrypted password in control connection table */
|
||||
infoLocal = (SSM_TokenInfo *) PORT_ZAlloc(sizeof(SSM_TokenInfo));
|
||||
if (!infoLocal)
|
||||
goto loser;
|
||||
infoLocal->slot = info->slot;
|
||||
infoLocal->tokenID = info->tokenID;
|
||||
infoLocal->encryptedLen = info->encryptedLen;
|
||||
infoLocal->symKey = info->symKey;
|
||||
infoLocal->encrypted = (char *) PORT_ZAlloc(info->encryptedLen);
|
||||
if (!infoLocal->encrypted)
|
||||
goto loser;
|
||||
memcpy(infoLocal->encrypted, info->encrypted, info->encryptedLen);
|
||||
PR_EnterMonitor(SSM_PARENT_CONN(conn)->m_encrPasswdLock);
|
||||
rv = SSM_HashRemove(SSM_PARENT_CONN(conn)->m_encrPasswdTable, tokenKey,
|
||||
(void **)&tmp);
|
||||
if (rv == SSM_SUCCESS && tmp && tmp != (char *)SSM_NO_PASSWORD &&
|
||||
tmp != (char *)SSM_CANCEL_PASSWORD ) {/* free stale data */
|
||||
PR_Free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
rv = SSM_HashInsert(SSM_PARENT_CONN(conn)->m_encrPasswdTable, tokenKey,
|
||||
infoLocal);
|
||||
PR_ExitMonitor(SSM_PARENT_CONN(conn)->m_encrPasswdLock);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: cannot insert token %d entry in encrPasswdTable\n",
|
||||
conn, tokenKey);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
SSM_DEBUG("%ld: wait untill others are done with passwd, remove it\n",
|
||||
conn);
|
||||
/* while ((SSM_PARENT_CONN(conn))->m_waiting > 1)
|
||||
* PR_Sleep(SSM_PASSWORD_WAIT_TIME);
|
||||
*/
|
||||
|
||||
SSM_LockPasswdTable(conn);
|
||||
rv = SSM_HashRemove(SSM_PWD_TABLE(conn), tokenKey, (void **)&passwd);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: could not remove passwd.\n", conn);
|
||||
goto loser;
|
||||
}
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
} /* end of if-first clause */
|
||||
|
||||
goto done;
|
||||
|
||||
loser:
|
||||
/* cleanup */
|
||||
PR_FREEIF(passwd);
|
||||
passwd = NULL;
|
||||
if (info) {
|
||||
PR_FREEIF(info->encrypted);
|
||||
PR_Free(info);
|
||||
}
|
||||
if (infoLocal) {
|
||||
PR_FREEIF(infoLocal->encrypted);
|
||||
PR_Free(infoLocal);
|
||||
}
|
||||
done:
|
||||
/* We are done receiving passwd */
|
||||
(SSM_PARENT_CONN(conn))->m_waiting--;
|
||||
return passwd ? strdup (passwd) : NULL;
|
||||
}
|
||||
/*
|
||||
* We get this callback if the slot is already logged-in.
|
||||
* Need to check client-supplied password against the password stored in
|
||||
* tokenList.
|
||||
*/
|
||||
PRBool SSM_VerifyPasswdCallback(PK11SlotInfo * slot, void * arg)
|
||||
{
|
||||
char * passwd = NULL;
|
||||
PRInt32 tokenKey;
|
||||
SSM_TokenInfo * info = NULL;
|
||||
SSM_TokenInfo * tokenInfo = NULL;
|
||||
SSMStatus rv;
|
||||
PRBool result = PR_FALSE;
|
||||
SSMResource * res = (SSMResource*)arg;
|
||||
SSMConnection * conn = &(res->m_connection->super);
|
||||
PRInt32 doTry = 0;
|
||||
void * tmp = NULL;
|
||||
|
||||
if (!slot || !arg)
|
||||
goto loser;
|
||||
|
||||
tokenKey = PK11_GetSlotID(slot) ^ PK11_GetModuleID(slot);
|
||||
info = (SSM_TokenInfo *) PORT_ZAlloc(sizeof(SSM_TokenInfo));
|
||||
if (!info) {
|
||||
SSM_DEBUG("Could not allocate memory in VerifyPasswdCallback.\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the password for this token.
|
||||
* We might have to find it in the local encrypted password table or
|
||||
* to request it from the client.
|
||||
*/
|
||||
rv = SSM_HashFind(SSM_PARENT_CONN(conn)->m_encrPasswdTable, tokenKey,
|
||||
(void **)&info);
|
||||
if (rv != PR_SUCCESS || info == (void *)SSM_NO_PASSWORD) {
|
||||
askpassword:
|
||||
/* ask user for a password and store it in local passwd table */
|
||||
rv = SSM_AskUserPassword(res, slot, doTry?PR_TRUE:PR_FALSE, PR_FALSE);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
doTry++;
|
||||
rv = SSMControlConnection_WaitPassword(conn, tokenKey, &passwd);
|
||||
if (rv != PR_SUCCESS || !passwd)
|
||||
goto loser;
|
||||
rv = SSM_EncryptPasswd(slot, passwd, &info);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
} /* end of no password, ask user */
|
||||
|
||||
/* Now get the stored password for this token */
|
||||
if (!tokenInfo) {
|
||||
PR_EnterMonitor(tokenLock);
|
||||
rv = SSM_HashFind(tokenList, tokenKey, (void **)&tokenInfo);
|
||||
PR_ExitMonitor(tokenLock);
|
||||
if (rv != PR_SUCCESS || !tokenInfo) {
|
||||
SSM_DEBUG("Can't find token info in VerifyPasswd.\n");
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Check password against tokenList entry */
|
||||
if (memcmp(tokenInfo->encrypted, info->encrypted, tokenInfo->encryptedLen)
|
||||
!= 0 || tokenInfo->encryptedLen != info->encryptedLen) {
|
||||
/* Failed compare, bad password */
|
||||
/* first clean up */
|
||||
if (info) PR_Free(info);
|
||||
info = NULL;
|
||||
/* If not retry, ask client for password. */
|
||||
if (doTry < 2 ) {
|
||||
/* ask user again */
|
||||
PR_Free(passwd);
|
||||
passwd = NULL;
|
||||
goto askpassword;
|
||||
}
|
||||
else
|
||||
goto loser;
|
||||
} /* end of password not verified */
|
||||
|
||||
SSM_DEBUG("Password verified OK.\n");
|
||||
|
||||
/* store password for local use */
|
||||
PR_EnterMonitor(SSM_PARENT_CONN(conn)->m_encrPasswdLock);
|
||||
SSM_HashRemove(SSM_PARENT_CONN(conn)->m_encrPasswdTable, tokenKey,
|
||||
(void **)&tmp);
|
||||
if (tmp && tmp != (char *)SSM_NO_PASSWORD ) {/* free stale data */
|
||||
PR_Free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
rv = SSM_HashInsert(SSM_PARENT_CONN(conn)->m_encrPasswdTable, tokenKey,
|
||||
info);
|
||||
PR_ExitMonitor(SSM_PARENT_CONN(conn)->m_encrPasswdLock);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: cannot insert token %d entry in encrPasswdTable\n",
|
||||
conn, tokenKey);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
loser:
|
||||
SSM_DEBUG("Password not verified. \n");
|
||||
/* log out this slot?? */
|
||||
if (info) {
|
||||
if (info->encrypted)
|
||||
PR_Free(info->encrypted);
|
||||
PR_Free(info);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
done:
|
||||
if (passwd)
|
||||
PR_Free(passwd);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Encrypt password for storage */
|
||||
#define SSM_PAD_BLOCK_SIZE(x, y) ((((x) + ((y)-1))/(y))*(y))
|
||||
|
||||
SSMStatus SSM_EncryptPasswd(PK11SlotInfo * slot, char * passwd,
|
||||
SSM_TokenInfo ** tokenInfo)
|
||||
{
|
||||
int resultLen;
|
||||
char *hashResult = NULL;
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
SECStatus srv;
|
||||
SSM_TokenInfo * info;
|
||||
|
||||
/* Hash the password. */
|
||||
resultLen = HASH_ResultLen(HASH_AlgSHA1);
|
||||
hashResult = (char *) PORT_ZAlloc(resultLen); /* because the original PORT_ZAlloc'd */
|
||||
if (!hashResult)
|
||||
goto loser;
|
||||
|
||||
srv = HASH_HashBuf(HASH_AlgSHA1, (unsigned char *) hashResult, (unsigned char *) passwd, strlen(passwd));
|
||||
if (srv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* fill in the tokenInfo structure */
|
||||
info = (SSM_TokenInfo *) PORT_ZAlloc(sizeof(SSM_TokenInfo));
|
||||
if (!info) {
|
||||
SSM_DEBUG("EncryptPwd: could not allocate memory to token list entry.\n");
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
info->encrypted = hashResult;
|
||||
info->encryptedLen = resultLen;
|
||||
info->slot = slot;
|
||||
info->tokenID = SSM_GetTokenKey(slot);
|
||||
*tokenInfo = info;
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
PR_FREEIF(hashResult);
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_NotEncryptPasswd(PK11SlotInfo * slot, char * passwd,
|
||||
SSM_TokenInfo * info)
|
||||
{
|
||||
CK_MECHANISM_TYPE mechanism;
|
||||
/* CK_SESSION_HANDLE session = CK_INVALID_SESSION; */
|
||||
PRInt32 keyLength, blockSize, outlen;
|
||||
PRUint32 encryptedLength;
|
||||
PK11SymKey * symKey;
|
||||
SECStatus rv;
|
||||
char * encrypted = NULL;
|
||||
PK11Context * context=NULL;
|
||||
SECItem *params;
|
||||
|
||||
|
||||
if (!slot || !passwd || !info) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
mechanism = CRMF_GetBestWrapPadMechanism(slot);
|
||||
keyLength = PK11_GetBestKeyLength(slot, mechanism);
|
||||
/* session = PK11_GetRWSession(slot);
|
||||
if (session == CK_INVALID_SESSION)
|
||||
goto loser;*/
|
||||
blockSize = PK11_GetBlockSize(mechanism, NULL);
|
||||
|
||||
/*
|
||||
* A password is encrypted when we first authenticate to token.
|
||||
* In this case, generate a symmetric Key on the slot.
|
||||
* If the key is already present, it means that the password for this
|
||||
* slot has already been encrypted and stored, need to encrypt
|
||||
* new password with the same key to compare against the stored
|
||||
* password.
|
||||
*/
|
||||
/* If no symKey found, generate one */
|
||||
if (!info->symKey) {
|
||||
symKey = PK11_KeyGen(slot, mechanism, NULL, keyLength, NULL);
|
||||
if (!symKey) {
|
||||
SSM_DEBUG("Failed to generate symKey to encrypt passwd.\n");
|
||||
goto loser;
|
||||
}
|
||||
} else
|
||||
symKey = info->symKey;
|
||||
|
||||
encryptedLength = SSM_PAD_BLOCK_SIZE(strlen(passwd)+1, blockSize);
|
||||
encrypted = (char *) PORT_ZAlloc(encryptedLength);
|
||||
if (!encrypted) {
|
||||
SSM_DEBUG("Could not allocate space for encrypted password. \n");
|
||||
goto loser;
|
||||
}
|
||||
params = CRMF_GetIVFromMechanism(mechanism);
|
||||
context=PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT,
|
||||
symKey, params);
|
||||
if (params != NULL) {
|
||||
SECITEM_FreeItem(params, PR_TRUE);
|
||||
}
|
||||
if (!context) {
|
||||
SSM_DEBUG("Can't create context to encrypt password: %d.\n",
|
||||
PR_GetError());
|
||||
goto loser;
|
||||
}
|
||||
rv = PK11_CipherOp(context, (unsigned char *) encrypted, &outlen,
|
||||
(int) encryptedLength,
|
||||
(unsigned char *) passwd, strlen(passwd));
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("Error encrypting password: %d\n", PR_GetError());
|
||||
goto loser;
|
||||
}
|
||||
rv = PK11_DigestFinal(context, (unsigned char *) &encrypted[outlen],
|
||||
(unsigned int *) &outlen, (unsigned int) blockSize);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("Error encrypting password: %d\n", PR_GetError());
|
||||
goto loser;
|
||||
}
|
||||
PK11_DestroyContext(context, PR_TRUE);
|
||||
/*if (session != CK_INVALID_SESSION)
|
||||
PK11_RestoreROSession(slot, session);*/
|
||||
|
||||
/* fill in the tokenInfo structure */
|
||||
info->encrypted = encrypted;
|
||||
info->encryptedLen = encryptedLength;
|
||||
info->slot = slot;
|
||||
return SSM_SUCCESS;
|
||||
loser:
|
||||
SSM_DEBUG("Failed to encrypt password.\n");
|
||||
if (context != NULL)
|
||||
PK11_DestroyContext(context, PR_TRUE);
|
||||
/*if (session != CK_INVALID_SESSION)
|
||||
PK11_RestoreROSession(slot, session);*/
|
||||
if (encrypted && *encrypted)
|
||||
PR_Free(encrypted);
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
||||
/* Needs to be fixed using NLS lib and proper string storage. -jane */
|
||||
char * SSM_GetPrompt(PK11SlotInfo *slot, PRBool retry, PRBool init)
|
||||
{
|
||||
char * prompt = NULL, * tmp = NULL, * key;
|
||||
SSMTextGenContext * cx;
|
||||
SSMStatus rv;
|
||||
|
||||
PR_ASSERT(init != PR_TRUE);
|
||||
|
||||
rv = SSMTextGen_NewTopLevelContext(NULL, &cx);
|
||||
if (rv != SSM_SUCCESS || !cx)
|
||||
goto loser;
|
||||
if (retry)
|
||||
key = "retry_token_password";
|
||||
else
|
||||
key = "ask_token_password";
|
||||
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, key, &tmp);
|
||||
if (rv != SSM_SUCCESS || !tmp)
|
||||
goto loser;
|
||||
prompt = PR_smprintf(tmp, PK11_GetTokenName(slot));
|
||||
|
||||
loser:
|
||||
PR_FREEIF(tmp);
|
||||
return prompt;
|
||||
}
|
||||
|
||||
|
||||
/* Send a password request for the client */
|
||||
SSMStatus SSM_AskUserPassword(SSMResource * res,
|
||||
PK11SlotInfo * slot, PRInt32 retry, PRBool init)
|
||||
{
|
||||
SECItem message;
|
||||
char * prompt = NULL;
|
||||
PRInt32 tokenKey = SSM_GetTokenKey(slot);
|
||||
SSMStatus rv = PR_FAILURE;
|
||||
SSMConnection *conn = (SSMConnection *)res->m_connection;
|
||||
PasswordRequest request;
|
||||
|
||||
prompt = SSM_GetPrompt(slot, retry, init);
|
||||
retry++;
|
||||
if (!prompt) {
|
||||
SSM_DEBUG("%ld: error getting prompt for password request.\n", conn);
|
||||
goto loser;
|
||||
}
|
||||
request.tokenKey = tokenKey;
|
||||
request.prompt = prompt;
|
||||
request.clientContext = res->m_clientContext;
|
||||
if (CMT_EncodeMessage(PasswordRequestTemplate, (CMTItem*)&message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (message.len == 0 || !message.data) {
|
||||
SSM_DEBUG("%ld: could not create password request message.\n", conn);
|
||||
goto loser;
|
||||
}
|
||||
message.type = (SECItemType) (SSM_EVENT_MESSAGE | SSM_AUTH_EVENT);
|
||||
rv = SSM_SendQMessage(SSM_OUT_QUEUE(conn), SSM_PRIORITY_UI, message.type,
|
||||
message.len, (char *)message.data, PR_TRUE);
|
||||
if (rv != PR_SUCCESS) {
|
||||
SSM_DEBUG("%ld: Can't enqueue password request. \n", conn);
|
||||
goto loser;
|
||||
}
|
||||
loser:
|
||||
if (prompt)
|
||||
PR_Free(prompt);
|
||||
if (message.data)
|
||||
PR_Free(message.data);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMControlConnection_WaitPassword(SSMConnection * conn,
|
||||
PRInt32 key, char ** str)
|
||||
{
|
||||
char * passwd;
|
||||
PRIntervalTime before;
|
||||
SSMStatus rv = PR_FAILURE;
|
||||
|
||||
*str = NULL;
|
||||
/* Wait no longer than our time-out period. */
|
||||
before = PR_IntervalNow();
|
||||
SSM_LockPasswdTable(conn);
|
||||
wait:
|
||||
SSM_DEBUG("%ld : waiting on password table for the password\n", conn);
|
||||
SSM_WaitPasswdTable(conn);
|
||||
/* Returned from wait.
|
||||
* Look for password.
|
||||
*/
|
||||
rv = SSM_HashFind(SSM_PWD_TABLE(conn), key, (void **)&passwd);
|
||||
if (rv!=PR_SUCCESS || !passwd || passwd ==(char *)SSM_NO_PASSWORD) {
|
||||
/* password not found, check for timeout */
|
||||
if (PR_IntervalNow() - before > SSM_PASSWORD_WAIT_TIME) {
|
||||
SSM_DEBUG("%ld:Timed out waiting for password.Bailing out.\n",
|
||||
conn);
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
else
|
||||
goto wait; /* continue waiting */
|
||||
} /* end of no password found */
|
||||
SSM_UnlockPasswdTable(conn);
|
||||
*str = passwd;
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern PK11SlotListElement *
|
||||
PK11_GetNextSafe(PK11SlotList * list, PK11SlotListElement * element,PRBool start);
|
||||
|
||||
PK11SlotListElement *
|
||||
ssm_GetSlotWithPwd(PK11SlotList * slotlist, PK11SlotListElement * current,
|
||||
PRBool start)
|
||||
{
|
||||
PK11SlotListElement * next = NULL;
|
||||
PR_ASSERT(slotlist);
|
||||
if (!current || start)
|
||||
next = PK11_GetFirstSafe(slotlist);
|
||||
else
|
||||
next = PK11_GetNextSafe(slotlist, current, PR_FALSE);
|
||||
while (next && PK11_NeedUserInit(next->slot) && !PK11_NeedLogin(next->slot))
|
||||
|
||||
next = PK11_GetNextSafe(slotlist, next, PR_FALSE);
|
||||
return next;
|
||||
}
|
||||
|
||||
PRIntn
|
||||
ssm_NumSlotsWithPassword(PK11SlotList * slotList)
|
||||
{
|
||||
PRIntn numslots = 0;
|
||||
PK11SlotListElement * element = PK11_GetFirstSafe(slotList);
|
||||
while (element) {
|
||||
if (PK11_NeedLogin(element->slot) || !PK11_NeedUserInit(element->slot))
|
||||
numslots++;
|
||||
element = PK11_GetNextSafe(slotList, element,PR_FALSE);
|
||||
}
|
||||
return numslots;
|
||||
}
|
||||
|
||||
SSMStatus SSM_ReSetPasswordKeywordHandler(SSMTextGenContext * cx)
|
||||
{
|
||||
char * slotname = NULL;
|
||||
PK11SlotInfo * slot;
|
||||
char * tmp = NULL;
|
||||
SSMStatus rv;
|
||||
SSMResource * target = cx->m_request->target;
|
||||
PK11SlotList * slotList = NULL;
|
||||
PK11SlotListElement * el = NULL;
|
||||
|
||||
PR_ASSERT(cx != NULL);
|
||||
PR_ASSERT(cx->m_request != NULL);
|
||||
PR_ASSERT(&cx->m_result != NULL);
|
||||
|
||||
rv = SSM_HTTPParamValue(cx->m_request, "action", &slotname);
|
||||
|
||||
if (!slotname || strcmp(slotname, "")== 0)
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
else if (strcmp(slotname, "all") == 0) {
|
||||
/* ask user */
|
||||
slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_TRUE, PR_TRUE, target);
|
||||
if (!slotList || !slotList->head)
|
||||
goto loser;
|
||||
if (ssm_NumSlotsWithPassword(slotList)>1) {
|
||||
char * mech = PR_smprintf("mech=%d&unused1=unused1&unused2=unused2",CKM_INVALID_MECHANISM);
|
||||
SSM_LockUIEvent(target);
|
||||
rv = SSMControlConnection_SendUIEvent(cx->m_request->ctrlconn,
|
||||
"get", "select_token",
|
||||
target,mech,&target->m_clientContext);
|
||||
SSM_WaitUIEvent(target, PR_INTERVAL_NO_TIMEOUT);
|
||||
slot = (PK11SlotInfo *) target->m_uiData;
|
||||
if (!slot)
|
||||
goto cancel;
|
||||
} else {
|
||||
/* only one interesting slot in the list */
|
||||
el = ssm_GetSlotWithPwd(slotList, NULL, PR_TRUE);
|
||||
slot = el->slot;
|
||||
}
|
||||
}
|
||||
else
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
if (!slot) {
|
||||
SSM_DEBUG("ReSetPasswordKeywordHandler: bad slotname %s\n", slotname);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
slotname = PK11_GetTokenName(slot);
|
||||
if (PK11_NeedPWInitForSlot(slot))
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "set_new_password", &tmp);
|
||||
else
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "reset_password", &tmp);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
PR_FREEIF(cx->m_result);
|
||||
cx->m_result = PR_smprintf(tmp, slotname);
|
||||
return rv;
|
||||
|
||||
loser:
|
||||
if (cx->m_result)
|
||||
PR_Free(cx->m_result);
|
||||
cx->m_result = NULL;
|
||||
return PR_FAILURE;
|
||||
cancel:
|
||||
SSM_HTTPCloseWindow(cx->m_request);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssm_VerifyPwdLength(char * password)
|
||||
{
|
||||
if (!password)
|
||||
return (!SSM_MIN_PWD_LEN);
|
||||
|
||||
if (strlen(password) < SSM_MIN_PWD_LEN)
|
||||
return PR_FALSE;
|
||||
if (strlen(password) > SSM_MAX_PWD_LEN)
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
SSMStatus SSM_PasswordPrefKeywordHandler(SSMTextGenContext * cx)
|
||||
{
|
||||
char * fmt = NULL, * checked = NULL;
|
||||
char * markchecked[] = { "", "", ""};
|
||||
SSMStatus rv;
|
||||
PRIntn askpw, timeout;
|
||||
|
||||
PR_ASSERT(cx != NULL);
|
||||
PR_ASSERT(cx->m_request != NULL);
|
||||
PR_ASSERT(cx->m_result != NULL);
|
||||
|
||||
/* need to get the table and fill it with current preferences */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "password_lifetime", &fmt);
|
||||
if (rv != SSM_SUCCESS || !fmt)
|
||||
goto done;
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "text_checked", &checked);
|
||||
if (rv != SSM_SUCCESS || !checked)
|
||||
goto done;
|
||||
rv = PREF_GetIntPref(cx->m_request->ctrlconn->m_prefs,
|
||||
"security.ask_for_password", &askpw);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto done;
|
||||
rv = PREF_GetIntPref(cx->m_request->ctrlconn->m_prefs,
|
||||
"security.password_lifetime", &timeout);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto done;
|
||||
|
||||
markchecked[askpw] = checked;
|
||||
PR_FREEIF(cx->m_result);
|
||||
cx->m_result = PR_smprintf(fmt, markchecked[0], markchecked[1],
|
||||
markchecked[2], timeout);
|
||||
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_SetDBPasswordHandler(HTTPRequest * req)
|
||||
{
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
char * oldpassword, * newpassword, *repeatpassword, * action;
|
||||
PK11SlotInfo * slot;
|
||||
char * responseKey = NULL;
|
||||
char * result = NULL;
|
||||
char * slotname = NULL, * askpwdoption, * pwdlifetime;
|
||||
PRIntn askpw, timeout;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "baseRef", &action);
|
||||
if (rv != SSM_SUCCESS || strcmp(action, "windowclose_doclose_js")!= 0)
|
||||
SSM_DEBUG("SetDBPasswordHandler: bad action %s\n", action);
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "slot", &slotname);
|
||||
if (rv != SSM_SUCCESS || !slotname ||
|
||||
!(slot = PK11_FindSlotByName(slotname)))
|
||||
goto loser;
|
||||
|
||||
/* process password preferences */
|
||||
rv = SSM_HTTPParamValue(req, "passwordlife", &askpwdoption);
|
||||
if (rv != SSM_SUCCESS || !askpwdoption)
|
||||
goto loser;
|
||||
rv = SSM_HTTPParamValue(req, "passwordwillexpire", &pwdlifetime);
|
||||
if (rv != SSM_SUCCESS || !pwdlifetime)
|
||||
goto loser;
|
||||
if (strcmp(askpwdoption, "firsttime") == 0)
|
||||
askpw = 0;
|
||||
else if (strcmp(askpwdoption, "everytime") == 0)
|
||||
askpw = 1;
|
||||
else if (strcmp(askpwdoption, "expiretime")==0) {
|
||||
askpw = 2;
|
||||
}
|
||||
else {
|
||||
SSM_DEBUG("SetDBPasswordHandler: bad password lifetime parameter %s\n",
|
||||
askpwdoption);
|
||||
goto loser;
|
||||
}
|
||||
timeout = atoi(pwdlifetime);
|
||||
if (askpw == 2 && !timeout)
|
||||
goto loser;
|
||||
|
||||
PK11_SetSlotPWValues(slot, askpw, timeout);
|
||||
rv = SSMControlConnection_SaveIntPref(req->ctrlconn,
|
||||
"security.ask_for_password", askpw);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
rv = SSMControlConnection_SaveIntPref(req->ctrlconn,
|
||||
"security.password_lifetime", timeout);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "newpassword", &newpassword);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
rv = SSM_HTTPParamValue(req, "repeatpassword", &repeatpassword);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
if (!PK11_NeedPWInitForSlot(slot)) {
|
||||
/* oldpassword doesn't make sense for password initialization dialog */
|
||||
rv = SSM_HTTPParamValue(req, "oldpassword", &oldpassword);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* we do this check to find the case where the user changed only password
|
||||
* settings, not the password itself
|
||||
*/
|
||||
if ((oldpassword[0] == '\0') && (newpassword[0] == '\0') &&
|
||||
(repeatpassword[0] == '\0')) {
|
||||
rv = SSM_HTTPDefaultCommandHandler(req);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssm_VerifyPwdLength(newpassword))
|
||||
goto loser;
|
||||
|
||||
if (strcmp(newpassword, repeatpassword) != 0)
|
||||
goto loser;
|
||||
|
||||
if (!PK11_NeedPWInitForSlot(slot)) { /* there is some password on the DB */
|
||||
if (!oldpassword)
|
||||
goto loser;
|
||||
if (PK11_CheckUserPassword(slot, oldpassword) !=
|
||||
SECSuccess)
|
||||
goto loser;
|
||||
if (PK11_ChangePW(slot, oldpassword, newpassword) !=
|
||||
SECSuccess)
|
||||
goto loser;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PK11_NeedUserInit(slot)) {
|
||||
if (PK11_InitPin(slot, NULL, newpassword) != SECSuccess)
|
||||
goto loser;
|
||||
}
|
||||
else {
|
||||
if (PK11_ChangePW(slot, NULL, newpassword) != SECSuccess)
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
result = PR_smprintf("result=password_success");
|
||||
loser:
|
||||
if (!result)
|
||||
result = PR_smprintf("result=password_failure");
|
||||
|
||||
rv = SSM_HTTPCloseAndSleep(req);
|
||||
if (rv != SSM_SUCCESS)
|
||||
SSM_DEBUG("SetDBPasswordHandler: failure in DefaultCommandHandler\n");
|
||||
|
||||
/* post status if password dialog was invoked from the SecurityAdvisor */
|
||||
if (SSM_IsA(req->target, SSM_RESTYPE_SECADVISOR_CONTEXT))
|
||||
SSMControlConnection_SendUIEvent(req->ctrlconn, "get",
|
||||
"show_followup", NULL,
|
||||
result,
|
||||
&((SSMResource *)req->ctrlconn)->m_clientContext);
|
||||
|
||||
PR_FREEIF(responseKey);
|
||||
done:
|
||||
if (req->target && req->target->m_UILock)
|
||||
SSM_NotifyUIEvent(req->target);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_ShowFollowupKeywordHandler(SSMTextGenContext * cx)
|
||||
{
|
||||
char * resultvalue;
|
||||
SSMStatus rv;
|
||||
|
||||
PR_ASSERT(cx != NULL);
|
||||
PR_ASSERT(cx->m_request != NULL);
|
||||
PR_ASSERT(cx->m_result != NULL);
|
||||
|
||||
rv = SSM_HTTPParamValue(cx->m_request, "result", &resultvalue);
|
||||
if (rv != SSM_SUCCESS || !resultvalue)
|
||||
goto loser;
|
||||
if (!strcmp(resultvalue, "password_success"))
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "set_password_success",
|
||||
&cx->m_result);
|
||||
else if (!strcmp(resultvalue,"password_failure"))
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "set_password_failure",
|
||||
&cx->m_result);
|
||||
else if (!strcmp(resultvalue, "no_ldap_setup"))
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, "no_ldap_server_set",
|
||||
&cx->m_result);
|
||||
loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_SetUserPassword(PK11SlotInfo * slot, SSMResource * ct)
|
||||
{
|
||||
SSMStatus rv;
|
||||
char * params = PR_smprintf("slot=%s&mechanism=%d",
|
||||
PK11_GetTokenName(slot),
|
||||
CKM_INVALID_MECHANISM);
|
||||
|
||||
SSM_LockUIEvent(ct);
|
||||
rv = SSMControlConnection_SendUIEvent(ct->m_connection,
|
||||
"get", "set_password",
|
||||
ct, params,
|
||||
&ct->m_clientContext);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
SSM_WaitUIEvent(ct, PR_INTERVAL_NO_TIMEOUT);
|
||||
return rv;
|
||||
loser:
|
||||
SSM_UnlockUIEvent(ct);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_ProcessPasswordWindow(HTTPRequest * req)
|
||||
{
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SSMResource * target = NULL;
|
||||
|
||||
if (!req || !req->ctrlconn)
|
||||
goto loser;
|
||||
/*
|
||||
* The window contents aren't going to change, so just send back
|
||||
* a NO_CONTENT error which causes leave its content as is.
|
||||
*/
|
||||
rv = SSM_HTTPReportError(req, HTTP_NO_CONTENT);
|
||||
target = (req->target ? req->target : (SSMResource *) req->ctrlconn);
|
||||
/* send UI event to bring up the dialog */
|
||||
SSM_LockUIEvent(&req->ctrlconn->super.super);
|
||||
rv = SSMControlConnection_SendUIEvent(req->ctrlconn, "get",
|
||||
"set_password", target,
|
||||
"slot=all&mech=1",
|
||||
&target->m_clientContext);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
SSM_UnlockUIEvent(&req->ctrlconn->super.super);
|
||||
goto loser;
|
||||
}
|
||||
SSM_WaitUIEvent(&req->ctrlconn->super.super, PR_INTERVAL_NO_TIMEOUT);
|
||||
loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
961
security/psm/server/pkcs11ui.c
Normal file
961
security/psm/server/pkcs11ui.c
Normal file
@ -0,0 +1,961 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "pkcs11ui.h"
|
||||
#include "pkcs11.h"
|
||||
#include "pk11func.h"
|
||||
#include "plstr.h"
|
||||
#include "secmod.h"
|
||||
#include "secmodti.h"
|
||||
#include "minihttp.h"
|
||||
#include "textgen.h"
|
||||
|
||||
/* Utility */
|
||||
PK11SlotInfo *
|
||||
SSMPKCS11_FindSlotByID(SECMODModuleID modID,
|
||||
CK_SLOT_ID slotID)
|
||||
{
|
||||
SECMODModule *mod = NULL;
|
||||
PRIntn i;
|
||||
|
||||
mod = SECMOD_FindModuleByID(modID);
|
||||
if (mod)
|
||||
{
|
||||
for(i=0;i<mod->slotCount;i++)
|
||||
{
|
||||
if (mod->slots[i]->slotID == slotID)
|
||||
return mod->slots[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
---------------------------------------------------------
|
||||
PKCS11 module processing (list, add, delete)
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
SSMStatus
|
||||
ssmpkcs11_convert_module(SSMTextGenContext *cx,
|
||||
PRInt32 modIndex,
|
||||
SECMODModule *mod,
|
||||
char *fmt)
|
||||
{
|
||||
char *dllName = NULL;
|
||||
char *tempStr = NULL;
|
||||
char *lib_ch = NULL;
|
||||
CK_INFO modInfo;
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SECStatus srv;
|
||||
/* 65? Why 65??? It's what's was used in the original UI. */
|
||||
char buf[65];
|
||||
char buf2[65];
|
||||
|
||||
srv = PK11_GetModInfo(mod, &modInfo);
|
||||
if (srv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* we provide the space in (buf), so we don't deallocate lib_ch */
|
||||
lib_ch = PK11_MakeString(NULL,buf2,(char *)modInfo.libraryDescription,
|
||||
sizeof(modInfo.libraryDescription));
|
||||
if (mod->dllName)
|
||||
{
|
||||
char *cursor, *newString;
|
||||
int numSlashes = 0, newLen, i, j, oldLen;
|
||||
|
||||
dllName = mod->dllName;
|
||||
/*
|
||||
* Now we need to escape the '\' characters so the string shows
|
||||
* up correctly in the UI.
|
||||
*/
|
||||
/* First count them to see if we even need to re-allocate*/
|
||||
cursor = dllName;
|
||||
while ((cursor = PL_strchr(cursor, '\\')) != NULL) {
|
||||
numSlashes++;
|
||||
cursor++;
|
||||
}
|
||||
if (numSlashes > 0) {
|
||||
oldLen = PL_strlen(dllName);
|
||||
newLen = oldLen + numSlashes + 1;
|
||||
newString = SSM_NEW_ARRAY(char, newLen);
|
||||
/*
|
||||
* If we can't allocate a new buffer, then let's just display
|
||||
* the original string. That's better than not displaying
|
||||
* anything.
|
||||
*/
|
||||
if (newString != NULL) {
|
||||
for (i=0, j=0; i<oldLen+1; i++,j++){
|
||||
newString[j] = dllName[i];
|
||||
if (newString[j] == '\\'){
|
||||
newString[j+1] = '\\';
|
||||
j++;
|
||||
}
|
||||
}
|
||||
dllName = newString;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = SSM_GetAndExpandText(cx, "text_pk11_no_dll", &dllName);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PR_snprintf(buf, sizeof(buf), "%d.%d",
|
||||
modInfo.libraryVersion.major, modInfo.libraryVersion.minor);
|
||||
|
||||
tempStr = PR_smprintf(fmt, modIndex, (long)mod->moduleID, lib_ch,
|
||||
mod->commonName, dllName, buf);
|
||||
if (tempStr == NULL) {
|
||||
rv = SSM_FAILURE;
|
||||
goto loser;
|
||||
}
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
|
||||
|
||||
loser:
|
||||
if (dllName && dllName != mod->dllName)
|
||||
PR_Free(dllName);
|
||||
PR_FREEIF (tempStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
PKCS11 module list keyword handler.
|
||||
Syntax: {_pk11modules <wrapper_key>}
|
||||
*/
|
||||
|
||||
SSMStatus
|
||||
SSM_PKCS11ModulesKeywordHandler(SSMTextGenContext *cx)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
char *wrapperKey = NULL;
|
||||
char *wrapperStr = NULL;
|
||||
SECMODModuleList *modList = SECMOD_GetDefaultModuleList();
|
||||
SECMODModuleList *modWalk = NULL;
|
||||
SECMODListLock *modLock = SECMOD_GetDefaultModuleListLock();
|
||||
PRBool gotLock = PR_FALSE; /* indicates whether we should release at end */
|
||||
PRInt32 i=0;
|
||||
|
||||
/* Check for parameter validity */
|
||||
PR_ASSERT(cx);
|
||||
PR_ASSERT(cx->m_request);
|
||||
PR_ASSERT(cx->m_params);
|
||||
PR_ASSERT(cx->m_result);
|
||||
if (!cx || !cx->m_request || !cx->m_params || !cx->m_result)
|
||||
{
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto real_loser; /* really bail here */
|
||||
}
|
||||
|
||||
if (SSM_Count(cx->m_params) != 1)
|
||||
{
|
||||
SSM_HTTPReportSpecificError(cx->m_request, "_certList: "
|
||||
"Incorrect number of parameters "
|
||||
"(%d supplied, 1 needed).\n",
|
||||
SSM_Count(cx->m_params));
|
||||
goto user_loser;
|
||||
}
|
||||
|
||||
/* Convert parameters to something we can use in finding certs. */
|
||||
wrapperKey = (char *) SSM_At(cx->m_params, 0);
|
||||
PR_ASSERT(wrapperKey);
|
||||
|
||||
/* Get the wrapper text. */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto real_loser; /* error string set by the called function */
|
||||
|
||||
/* Iterate over the PKCS11 modules. Put relevant info from each
|
||||
into its own copy of the wrapper text. */
|
||||
SECMOD_GetReadLock(modLock);
|
||||
gotLock = PR_TRUE;
|
||||
|
||||
modWalk = modList;
|
||||
while (modWalk)
|
||||
{
|
||||
rv = ssmpkcs11_convert_module(cx, i++, modWalk->module, wrapperStr);
|
||||
modWalk = modWalk->next;
|
||||
}
|
||||
|
||||
goto done;
|
||||
user_loser:
|
||||
/* If we reach this point, something in the input is wrong, but we
|
||||
can still send something back to the client to indicate that a
|
||||
problem has occurred. */
|
||||
|
||||
/* If we can't do what we're about to do, really bail. */
|
||||
if (!cx->m_request || !cx->m_request->errormsg)
|
||||
goto real_loser;
|
||||
|
||||
/* Clear the string we were accumulating. */
|
||||
SSMTextGen_UTF8StringClear(&cx->m_result);
|
||||
|
||||
/* Use the result string given to us to explain what happened. */
|
||||
SSM_ConcatenateUTF8String(&cx->m_result, cx->m_request->errormsg);
|
||||
/* Clear the result string, since we're sending this inline */
|
||||
SSMTextGen_UTF8StringClear(&cx->m_request->errormsg);
|
||||
|
||||
goto done;
|
||||
real_loser:
|
||||
/* If we reach this point, then we are so screwed that we cannot
|
||||
send anything vaguely normal back to the client. Bail. */
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
PR_FREEIF(wrapperStr);
|
||||
if (modLock && gotLock)
|
||||
SECMOD_ReleaseReadLock(modLock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
---------------------------------------------------------
|
||||
PKCS11 slot code
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SSM_PK11STR_SLOT_LOGGED_IN = (long) 0,
|
||||
SSM_PK11STR_SLOT_NOT_LOGGED_IN,
|
||||
SSM_PK11STR_SLOT_NO_LOGIN_REQUIRED,
|
||||
SSM_PK11STR_SLOT_NOT_PRESENT,
|
||||
SSM_PK11STR_SLOT_UNINITIALIZED,
|
||||
SSM_PK11STR_SLOT_DISABLED,
|
||||
SSM_PK11STR_SLOT_READY,
|
||||
SSM_PK11STR_SLOT_STRING_COUNT
|
||||
};
|
||||
|
||||
static char *slotStringKeys[] =
|
||||
{
|
||||
"text_pk11_slot_logged_in",
|
||||
"text_pk11_slot_not_logged_in",
|
||||
"text_pk11_slot_no_login_required",
|
||||
"text_pk11_slot_not_present",
|
||||
"text_pk11_slot_uninitialized",
|
||||
"text_pk11_slot_disabled",
|
||||
"text_pk11_slot_ready"
|
||||
};
|
||||
|
||||
static char **slotStrings = NULL;
|
||||
|
||||
void
|
||||
ssmpkcs11_initialize_slot_labels(SSMTextGenContext *cx)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
PRIntn i;
|
||||
|
||||
slotStrings = (char **) PR_Calloc(SSM_PK11STR_SLOT_STRING_COUNT + 1,
|
||||
sizeof(char**));
|
||||
PR_ASSERT(slotStrings);
|
||||
|
||||
for(i=0;i<SSM_PK11STR_SLOT_STRING_COUNT;i++)
|
||||
{
|
||||
rv = SSM_FindUTF8StringInBundles(cx, slotStringKeys[i],
|
||||
&slotStrings[i]);
|
||||
PR_ASSERT(rv == SSM_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
ssmpkcs11_convert_slot(SSMTextGenContext *cx,
|
||||
PRInt32 slotIndex,
|
||||
PK11SlotInfo *slot,
|
||||
char *fmt,
|
||||
PRBool accumulate) /* accumulate in cx->m_result? */
|
||||
{
|
||||
char *name = NULL;
|
||||
char *statusStr = NULL;
|
||||
char *serial = NULL;
|
||||
char *version = NULL;
|
||||
char *tempStr = NULL;
|
||||
long status, slotID = 0, moduleID = 0;
|
||||
CK_TOKEN_INFO tokenInfo;
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SECStatus srv = SECSuccess;
|
||||
/* 65? Why 65??? It's what's was used in the original UI. */
|
||||
char buf[65];
|
||||
char empty[1] = { '\0' } ;
|
||||
|
||||
if (!slotStrings)
|
||||
ssmpkcs11_initialize_slot_labels(cx);
|
||||
|
||||
/* If we have a NULL slot, return blank information. */
|
||||
if (!slot)
|
||||
{
|
||||
name = empty;
|
||||
statusStr = empty;
|
||||
serial = empty;
|
||||
version = empty;
|
||||
slotID = 0;
|
||||
|
||||
goto show_stuff;
|
||||
}
|
||||
|
||||
/* Get the slot name. Either the default name or the name of the token
|
||||
in the slot will be used. */
|
||||
if (PK11_IsPresent(slot))
|
||||
name = PK11_GetTokenName(slot);
|
||||
else
|
||||
name = PK11_GetSlotName(slot);
|
||||
|
||||
/* Report the status of the slot. */
|
||||
if (PK11_IsDisabled(slot))
|
||||
status = SSM_PK11STR_SLOT_DISABLED;
|
||||
else if (!PK11_IsPresent(slot))
|
||||
status = SSM_PK11STR_SLOT_NOT_PRESENT;
|
||||
else if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot))
|
||||
status = SSM_PK11STR_SLOT_UNINITIALIZED;
|
||||
else if (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))
|
||||
status = SSM_PK11STR_SLOT_NOT_LOGGED_IN;
|
||||
else if (PK11_NeedLogin(slot))
|
||||
status = SSM_PK11STR_SLOT_LOGGED_IN;
|
||||
else
|
||||
status = SSM_PK11STR_SLOT_READY;
|
||||
|
||||
statusStr = slotStrings[status];
|
||||
|
||||
/* Get the serial number and version. */
|
||||
|
||||
/* This is how the old UI determines if there's a token in, so... */
|
||||
if (PK11_IsPresent(slot))
|
||||
srv = PK11_GetTokenInfo(slot, &tokenInfo);
|
||||
|
||||
if (PK11_IsPresent(slot) && (srv == SECSuccess))
|
||||
{
|
||||
/* Get serial number and version from the token info. */
|
||||
serial = PK11_MakeString(NULL, NULL, (char*)tokenInfo.serialNumber,
|
||||
sizeof(tokenInfo.serialNumber));
|
||||
PR_snprintf(buf, sizeof(buf), "%d.%d",
|
||||
tokenInfo.firmwareVersion.major,
|
||||
tokenInfo.firmwareVersion.minor);
|
||||
version = buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get serial number and version from the slot info. */
|
||||
CK_SLOT_INFO slotInfo;
|
||||
srv = PK11_GetSlotInfo(slot, &slotInfo);
|
||||
if (srv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
serial = empty;
|
||||
PR_snprintf(buf, sizeof(buf), "%d.%d",
|
||||
slotInfo.firmwareVersion.major,
|
||||
slotInfo.firmwareVersion.minor);
|
||||
version = buf;
|
||||
}
|
||||
|
||||
slotID = (long) (slot->slotID);
|
||||
moduleID = (long) (slot->module->moduleID);
|
||||
|
||||
show_stuff:
|
||||
tempStr = PR_smprintf(fmt, slotIndex, slotID, moduleID, name,
|
||||
statusStr, serial, version);
|
||||
if (accumulate)
|
||||
{
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = SSM_HTTPSendUTF8String(cx->m_request, tempStr);
|
||||
|
||||
loser:
|
||||
/* The data that isn't freed is either because it's a member of the
|
||||
* data in a structure of the PK11 libraries or its a static local
|
||||
* variable.
|
||||
*/
|
||||
if (serial && serial != empty)
|
||||
PR_Free(serial);
|
||||
PR_FREEIF(tempStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
PKCS11 slot list keyword handler.
|
||||
Syntax: {_pk11slots <moduleID>,<wrapper_key>}
|
||||
*/
|
||||
|
||||
SSMStatus
|
||||
SSM_PKCS11SlotsKeywordHandler(SSMTextGenContext *cx)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
SECMODModule *module = NULL;
|
||||
char *wrapperKey = NULL;
|
||||
char *moduleIDStr = NULL;
|
||||
long moduleID;
|
||||
char *wrapperStr = NULL;
|
||||
PRInt32 i=0;
|
||||
|
||||
/* Check for parameter validity */
|
||||
PR_ASSERT(cx);
|
||||
PR_ASSERT(cx->m_request);
|
||||
PR_ASSERT(cx->m_params);
|
||||
PR_ASSERT(cx->m_result);
|
||||
if (!cx || !cx->m_request || !cx->m_params || !cx->m_result)
|
||||
{
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto real_loser; /* really bail here */
|
||||
}
|
||||
|
||||
if (SSM_Count(cx->m_params) != 2)
|
||||
{
|
||||
SSM_HTTPReportSpecificError(cx->m_request, "_certList: "
|
||||
"Incorrect number of parameters "
|
||||
"(%d supplied, 2 needed).\n",
|
||||
SSM_Count(cx->m_params));
|
||||
goto user_loser;
|
||||
}
|
||||
|
||||
/* Convert parameters to something we can use in finding certs. */
|
||||
moduleIDStr = (char *) SSM_At(cx->m_params, 0);
|
||||
PR_ASSERT(moduleIDStr);
|
||||
wrapperKey = (char *) SSM_At(cx->m_params, 1);
|
||||
PR_ASSERT(wrapperKey);
|
||||
|
||||
/* Find the module we're looking for based on the module ID. */
|
||||
module = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
|
||||
if (!module)
|
||||
goto user_loser;
|
||||
|
||||
/* Get the wrapper text. */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto real_loser; /* error string set by the called function */
|
||||
|
||||
/* Iterate over the slots from this module. Put relevant info from each
|
||||
into its own copy of the wrapper text. */
|
||||
for(i=0;i<module->slotCount;i++)
|
||||
{
|
||||
rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], wrapperStr,
|
||||
PR_TRUE);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto user_loser;
|
||||
}
|
||||
goto done;
|
||||
user_loser:
|
||||
/* If we reach this point, something in the input is wrong, but we
|
||||
can still send something back to the client to indicate that a
|
||||
problem has occurred. */
|
||||
|
||||
/* If we can't do what we're about to do, really bail. */
|
||||
if (!cx->m_request || !cx->m_request->errormsg)
|
||||
goto real_loser;
|
||||
|
||||
/* Clear the string we were accumulating. */
|
||||
SSMTextGen_UTF8StringClear(&cx->m_result);
|
||||
|
||||
/* Use the result string given to us to explain what happened. */
|
||||
SSM_ConcatenateUTF8String(&cx->m_result, cx->m_request->errormsg);
|
||||
/* Clear the result string, since we're sending this inline */
|
||||
SSMTextGen_UTF8StringClear(&cx->m_request->errormsg);
|
||||
|
||||
goto done;
|
||||
real_loser:
|
||||
/* If we reach this point, then we are so screwed that we cannot
|
||||
send anything vaguely normal back to the client. Bail. */
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
PR_FREEIF(wrapperStr);
|
||||
if (module)
|
||||
SECMOD_DestroyModule(module);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
ssm_pkcs11_chuck_property(SSMTextGenContext *cx, char *propName)
|
||||
{
|
||||
char *text = NULL;
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSM_GetAndExpandText(cx, propName, &text);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_HTTPSendUTF8String(cx->m_request, text);
|
||||
|
||||
loser:
|
||||
PR_FREEIF(text);
|
||||
SSMTextGen_UTF8StringClear(&cx->m_result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* PKCS11ShowSlots?module=<moduleID> */
|
||||
SSMStatus
|
||||
SSM_ShowSlotsCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
SSMTextGenContext *cx = NULL;
|
||||
char *tmpl = NULL, *type = NULL;
|
||||
char *nomod_ch = NULL;
|
||||
char *modID_ch = NULL;
|
||||
long moduleID;
|
||||
SECMODModule *module = NULL;
|
||||
PRIntn i;
|
||||
SSMStatus rv;
|
||||
|
||||
/* If we have a "no_module" parameter, then there
|
||||
is no module for which to load slots. */
|
||||
rv = SSM_HTTPParamValue(req, "no_module", &nomod_ch);
|
||||
if (rv == SSM_SUCCESS)
|
||||
goto display_stuff;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "module", &modID_ch);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto display_stuff;
|
||||
|
||||
if (modID_ch)
|
||||
{
|
||||
/* Convert the module ID into a real module ID. */
|
||||
PR_sscanf(modID_ch, "%ld", &moduleID);
|
||||
|
||||
/* Find the module we're looking for based on the module ID. */
|
||||
module = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
|
||||
if (!module)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
display_stuff:
|
||||
/* Make a new top-level text gen context to chuck text back. */
|
||||
rv = SSMTextGen_NewTopLevelContext(req, &cx);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_type", &type);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_HTTPSendOKHeader(req, NULL, type);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Chuck out part 1. */
|
||||
rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part1");
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Get the template for the JS slot list. */
|
||||
rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_js_template", &tmpl);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Iterate over the slots from this module. Put relevant info from each
|
||||
into its own copy of the wrapper text. */
|
||||
if (module)
|
||||
{
|
||||
for(i=0;i<module->slotCount;i++)
|
||||
{
|
||||
rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], tmpl,
|
||||
PR_FALSE);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
PR_Free(tmpl);
|
||||
tmpl = NULL;
|
||||
|
||||
/* Chuck out part 2. */
|
||||
rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part2");
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Get the template for the selectable slot list. */
|
||||
rv = SSM_GetAndExpandText(cx, "adv_modules_slotlist_select_template", &tmpl);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Iterate over the slots from this module. Put relevant info from each
|
||||
into its own copy of the wrapper text. */
|
||||
if (module)
|
||||
{
|
||||
for(i=0;i<module->slotCount;i++)
|
||||
{
|
||||
rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], tmpl,
|
||||
PR_FALSE);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chuck out part 3. */
|
||||
rv = ssm_pkcs11_chuck_property(cx, "adv_modules_slotlist_part3");
|
||||
req->sentResponse = PR_TRUE;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
if (cx)
|
||||
SSMTextGen_DestroyContext(cx);
|
||||
PR_FREEIF(tmpl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
ssm_find_module_from_request(HTTPRequest *req, SECMODModule **mod)
|
||||
{
|
||||
char *modID_ch = NULL;
|
||||
PRInt32 moduleID;
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "module", &modID_ch);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (modID_ch)
|
||||
{
|
||||
/* Convert the module ID into a real module ID. */
|
||||
PR_sscanf(modID_ch, "%ld", &moduleID);
|
||||
|
||||
/* Find the module we're looking for based on the module ID. */
|
||||
*mod = SECMOD_FindModuleByID((SECMODModuleID) moduleID);
|
||||
}
|
||||
done:
|
||||
if ((!*mod) && (rv == SSM_SUCCESS))
|
||||
rv = SSM_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PK11SlotInfo *
|
||||
find_slot_by_ID(SECMODModule *mod, CK_SLOT_ID slotID)
|
||||
{
|
||||
int i;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
for (i=0; i < mod->slotCount; i++) {
|
||||
slot = mod->slots[i];
|
||||
if (slot->slotID == (CK_SLOT_ID) slotID)
|
||||
return PK11_ReferenceSlot(slot);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
ssm_find_slot_from_request(HTTPRequest *req, PK11SlotInfo **slot)
|
||||
{
|
||||
char *slotID_ch = NULL;
|
||||
PRInt32 slotID;
|
||||
SECMODModule *mod;
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
|
||||
rv = ssm_find_module_from_request(req, &mod);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto done;
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "slot", &slotID_ch);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (slotID_ch)
|
||||
{
|
||||
/* Convert the module ID into a real module ID. */
|
||||
PR_sscanf(slotID_ch, "%ld", &slotID);
|
||||
|
||||
/* Find the module we're looking for based on the module ID. */
|
||||
*slot = find_slot_by_ID(mod, (CK_SLOT_ID) slotID);
|
||||
}
|
||||
done:
|
||||
if ((!*slot) && (rv == SSM_SUCCESS))
|
||||
rv = SSM_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
ssmpkcs11_show_slot_info(HTTPRequest *req, PK11SlotInfo *slot)
|
||||
{
|
||||
char *wrapperStr = NULL;
|
||||
char *tmpl = NULL;
|
||||
char *type = NULL;
|
||||
SSMTextGenContext *cx;
|
||||
SSMStatus rv;
|
||||
|
||||
/* Make a new top-level text gen context to chuck text back. */
|
||||
rv = SSMTextGen_NewTopLevelContext(req, &cx);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_GetAndExpandText(cx, "adv_modules_slot_info_type", &type);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_HTTPSendOKHeader(req, NULL, type);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
rv = SSM_GetAndExpandText(cx, "adv_modules_slot_info_content", &wrapperStr);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser; /* error string set by the called function */
|
||||
|
||||
rv = ssmpkcs11_convert_slot(cx, 0, slot, wrapperStr, PR_FALSE);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
if (cx)
|
||||
SSMTextGen_DestroyContext(cx);
|
||||
PR_FREEIF(tmpl);
|
||||
PR_FREEIF(type);
|
||||
PR_FREEIF(wrapperStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_ShowSlotCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
/* Find the slot. */
|
||||
rv = ssm_find_slot_from_request(req, &slot);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Display the slot info. */
|
||||
rv = ssmpkcs11_show_slot_info(req, slot);
|
||||
req->sentResponse = PR_TRUE;
|
||||
|
||||
loser:
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_LoginSlotCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
/* Find the slot. */
|
||||
rv = ssm_find_slot_from_request(req, &slot);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Log into the slot. */
|
||||
PK11_Authenticate(slot, PR_TRUE, req->ctrlconn);
|
||||
|
||||
/* Display the slot info. */
|
||||
rv = ssmpkcs11_show_slot_info(req, slot);
|
||||
req->sentResponse = PR_TRUE;
|
||||
|
||||
loser:
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_LogoutSlotCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
/* Find the slot. */
|
||||
rv = ssm_find_slot_from_request(req, &slot);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* Log out of the slot. */
|
||||
PK11_Logout(slot);
|
||||
|
||||
/* Display the slot info. */
|
||||
rv = ssmpkcs11_show_slot_info(req, slot);
|
||||
req->sentResponse = PR_TRUE;
|
||||
|
||||
loser:
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSM_LogoutAllSlotsCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
PK11SlotInfo *slot;
|
||||
|
||||
/* Find the slot. */
|
||||
rv = ssm_find_slot_from_request(req, &slot);
|
||||
/* Not relevant if we find the slot here,
|
||||
just remember to display (or not) whatever slot we have */
|
||||
if (rv != SSM_SUCCESS)
|
||||
slot = NULL;
|
||||
|
||||
/* Log out of all slots. */
|
||||
PK11_LogoutAll();
|
||||
|
||||
/* Display the slot info (if any). */
|
||||
rv = ssmpkcs11_show_slot_info(req, slot);
|
||||
|
||||
req->sentResponse = PR_TRUE;
|
||||
|
||||
if (slot)
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
---------------------------------------------------------
|
||||
FIPS mode code
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
FIPS mode keyword handler.
|
||||
Syntax: {_fipsmode <true_text>,<false_text>}
|
||||
where <true_text> is displayed if FIPS mode is on, <false_text> otherwise.
|
||||
*/
|
||||
SSMStatus
|
||||
SSM_PKCS11FIPSModeKeywordHandler(SSMTextGenContext *cx)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
char *param = NULL;
|
||||
char *tempStr = NULL;
|
||||
|
||||
PR_ASSERT(cx);
|
||||
PR_ASSERT(cx->m_params);
|
||||
PR_ASSERT(cx->m_result);
|
||||
if (!cx || !cx->m_params || !cx->m_result)
|
||||
{
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Figure out if we're in FIPS mode. */
|
||||
if (PK11_IsFIPS())
|
||||
param = (char *) SSM_At(cx->m_params, 0);
|
||||
else
|
||||
param = (char *) SSM_At(cx->m_params, 1);
|
||||
|
||||
/* Display the appropriate string. */
|
||||
rv = SSMTextGen_SubstituteString(cx, param, &tempStr);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser; /* error string set by the called function */
|
||||
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr);
|
||||
if (rv == SSM_SUCCESS)
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
done:
|
||||
PR_FREEIF(tempStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SSM_TrimTrailingWhitespace(char *str)
|
||||
{
|
||||
char *end = &(str[strlen(str)]);
|
||||
char *start = str;
|
||||
|
||||
do
|
||||
{
|
||||
end--;
|
||||
}
|
||||
while ((end >= start) &&
|
||||
((*end == ' ') || (*end == '\0')));
|
||||
*(++end) = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
Command handler to set FIPS mode.
|
||||
Syntax: setFIPSMode?fips={on|off}&baseRef=<baseRef>&target=<ctrlconn>
|
||||
*/
|
||||
SSMStatus
|
||||
SSM_SetFIPSModeCommandHandler(HTTPRequest *req)
|
||||
{
|
||||
char *fips_ch = NULL, *baseRef_ch = NULL;
|
||||
SECStatus srv = SECSuccess;
|
||||
PRBool oldFIPS, newFIPS;
|
||||
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
rv = SSM_HTTPParamValue(req, "fips", &fips_ch);
|
||||
if (rv != SSM_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
newFIPS = !PL_strncmp(fips_ch, "on", 2);
|
||||
oldFIPS = PK11_IsFIPS();
|
||||
|
||||
if (newFIPS != oldFIPS)
|
||||
{
|
||||
/*
|
||||
Turning FIPS mode on/off requires the exact same operation:
|
||||
deleting the built-in PKCS11 module.
|
||||
|
||||
### mwelch We need these calls to differentiate between
|
||||
secmod dbs!
|
||||
*/
|
||||
SECMODModule *internal;
|
||||
CK_INFO modInfo;
|
||||
|
||||
internal = SECMOD_GetInternalModule();
|
||||
if (!internal)
|
||||
goto loser;
|
||||
|
||||
srv = PK11_GetModInfo(internal, &modInfo);
|
||||
if (srv != SECSuccess)
|
||||
goto loser;
|
||||
SSM_TrimTrailingWhitespace((char*) modInfo.libraryDescription);
|
||||
|
||||
/* Delete the {FIPS,non-FIPS} internal module, so that
|
||||
it will be replaced by the {non-FIPS,FIPS} counterpart. */
|
||||
srv = SECMOD_DeleteInternalModule(internal->commonName);
|
||||
if (srv != SECSuccess)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* if there's a baseRef, send it back. otherwise, no content. */
|
||||
rv = SSM_HTTPParamValue(req, "baseRef", &baseRef_ch);
|
||||
if (rv == SSM_SUCCESS)
|
||||
{
|
||||
/* send what was requested */
|
||||
rv = SSM_HTTPCloseAndSleep(req);
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) rv = SSM_FAILURE;
|
||||
SSM_HTTPReportSpecificError(req, "SetFIPSModeCommandHandler: Error %d "
|
||||
"attempting to change FIPS mode.",
|
||||
srv != SECSuccess ? srv : rv);
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
51
security/psm/server/pkcs11ui.h
Normal file
51
security/psm/server/pkcs11ui.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __pkcs11ui_h__
|
||||
#define __pkcs11ui_h__
|
||||
|
||||
#include "textgen.h"
|
||||
#include "minihttp.h"
|
||||
|
||||
SSMStatus SSM_PKCS11ModulesKeywordHandler(SSMTextGenContext *cx);
|
||||
SSMStatus SSM_PKCS11SlotsKeywordHandler(SSMTextGenContext *cx);
|
||||
SSMStatus SSM_PKCS11FIPSModeKeywordHandler(SSMTextGenContext *cx);
|
||||
|
||||
SSMStatus SSM_SetFIPSModeCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_ShowSlotsCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_ShowSlotCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_LoginSlotCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_LogoutSlotCommandHandler(HTTPRequest *req);
|
||||
SSMStatus SSM_LogoutAllSlotsCommandHandler(HTTPRequest *req);
|
||||
|
||||
#endif
|
1234
security/psm/server/prefs.c
Normal file
1234
security/psm/server/prefs.c
Normal file
File diff suppressed because it is too large
Load Diff
344
security/psm/server/prefs.h
Normal file
344
security/psm/server/prefs.h
Normal file
@ -0,0 +1,344 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _PREFS_H_
|
||||
#define _PREFS_H_
|
||||
|
||||
#if 0
|
||||
#include "prtypes.h"
|
||||
#include "ssmdefs.h"
|
||||
|
||||
typedef struct PrefFileStr PrefFile;
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: PREF_OpenPrefs
|
||||
**
|
||||
** DESCRIPTION: Creates a PrefFile object for the preferences file.
|
||||
** If the file does not exist, it does not create it, and
|
||||
** returns a default set of preferences. To create the
|
||||
** preference file you must call PREF_WritePrefs() or
|
||||
** PREF_ClosePrefs(). If the file has already been
|
||||
** opened, the reference count is incremented and the
|
||||
** same object is returned.
|
||||
**
|
||||
** INPUTS:
|
||||
** filename
|
||||
** The name of the preferences file to open.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns a pointer to a PrefFile object.
|
||||
** If failed, returns NULL.
|
||||
**
|
||||
*************************************************************/
|
||||
PrefFile *
|
||||
PREF_OpenPrefs(char *filename);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: PREF_WritePrefs
|
||||
**
|
||||
** DESCRIPTION: Writes out the contents of prefs to the preferences
|
||||
** file. If the file does not exist, it is created.
|
||||
**
|
||||
** INPUTS:
|
||||
** prefs
|
||||
** The PrefFile object to write.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns PR_FAILURE.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus
|
||||
PREF_WritePrefs(PrefFile *prefs);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: PREF_ClosePrefs
|
||||
**
|
||||
** DESCRIPTION: Closes the PrefFile object. If this is the last
|
||||
** reference to to object, the contents are written out
|
||||
** and the object is destroyed.
|
||||
**
|
||||
** INPUTS:
|
||||
** prefs
|
||||
** The PrefFile object to close.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns PR_FAILURE.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus
|
||||
PREF_ClosePrefs(PrefFile *prefs);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: PREF_SetStringPref
|
||||
**
|
||||
** DESCRIPTION: Sets a preference with a string value. The preference
|
||||
** will be created if it does not already exist.
|
||||
**
|
||||
** INPUTS:
|
||||
** prefs
|
||||
** The PrefFile object.
|
||||
** name
|
||||
** The name of the preference.
|
||||
** value
|
||||
** The value of the preference.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns PR_FAILURE.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus
|
||||
PREF_SetStringPref(PrefFile *prefs, char *name, char *value);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: PREF_GetStringPref
|
||||
**
|
||||
** DESCRIPTION: Gets the value of a string preference. The returned
|
||||
** string must be freed with PR_Free().
|
||||
**
|
||||
** INPUTS:
|
||||
** prefs
|
||||
** The PrefFile object.
|
||||
** name
|
||||
** The name of the preference.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns a new string containing the value of
|
||||
** the preference.
|
||||
** If failed, returns NULL.
|
||||
**
|
||||
*************************************************************/
|
||||
char *
|
||||
PREF_GetStringPref(PrefFile *prefs, char *name);
|
||||
|
||||
|
||||
#else /* PREFS LITE (tm) */
|
||||
/* XXX sjlee
|
||||
* The following set of APIs describe the preference management system which
|
||||
* we will use for the time being until a fully-functional prefs/profs library
|
||||
* comes online, thus the name PREFS LITE.
|
||||
*/
|
||||
#include "prtypes.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "plhash.h"
|
||||
|
||||
/* pref types used for sending (and receiving) pref messages */
|
||||
#define STRING_PREF 0
|
||||
#define BOOL_PREF 1
|
||||
#define INT_PREF 2
|
||||
|
||||
typedef struct PrefSetStr PrefSet;
|
||||
|
||||
/*
|
||||
* Function: PrefSet* PREF_NewPrefs()
|
||||
* Purpose: Creates a PrefSet object. The object is not associated with a
|
||||
* file, and the values are initially filled with default values.
|
||||
* Return values:
|
||||
* - a pointer to a PrefSet object; if failure, returns NULL
|
||||
*/
|
||||
PrefSet* PREF_NewPrefs(void);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_ClosePrefs()
|
||||
* Purpose: Closes the PrefSet object and frees the memory. We do not write
|
||||
* changes back to the client at this time.
|
||||
* Arguments and return values:
|
||||
* - prefs: the PrefSet object to close
|
||||
* - returns: PR_SUCCESS if successful; PR_FAILURE if failure
|
||||
*/
|
||||
SSMStatus PREF_ClosePrefs(PrefSet* prefs);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_GetStringPref()
|
||||
* Purpose: Retrieves the string pref for (key) from (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: on return, filled with a pointer to the string pref value (or it
|
||||
* be NULL if NULL was the legally assigned value). Since this
|
||||
* points to an existing string (not a new string), the caller
|
||||
* should not free it. If the pref item does not exist, (*value) is
|
||||
* NULL.
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Notes: Note that NULL is a legal string value for a pref item. One should
|
||||
* check the return value (SSMStatus) to see if an error occurred.
|
||||
*/
|
||||
SSMStatus PREF_GetStringPref(PrefSet* prefs, char* key, char** value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_CopyStringPref()
|
||||
* Purpose: identical to PREF_GetStringPref() except that it creates a new
|
||||
* string
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: on return, filled with a pointer to the string newly allocated
|
||||
* that contains the pref value (or NULL if the value is NULL).
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Notes: Use this function instead of PREF_GetStringPref() if you need a
|
||||
* newly allocated string. The caller is responsible for freeing
|
||||
* the string when done.
|
||||
*/
|
||||
SSMStatus PREF_CopyStringPref(PrefSet* prefs, char* key, char** value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_SetStringPref()
|
||||
* Purpose: Sets the string pref for (key) in (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: the string value to set for the key. NULL may be used for a
|
||||
* value.
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*/
|
||||
SSMStatus PREF_SetStringPref(PrefSet* prefs, char* key, char* value);
|
||||
|
||||
/*
|
||||
* Function: PRBool PREF_StringPrefChanged()
|
||||
* Purpose: Compares the value in the set with the given value and determines
|
||||
* if it has changed
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: the string value to compare. NULL may be used for a value.
|
||||
* - returns: PR_TRUE if the value does not match or the key was not found
|
||||
* (i.e. change needs to be saved); otherwise PR_FALSE
|
||||
*
|
||||
* Notes: this is useful when one wants to determine the items that need
|
||||
* to be permanently saved.
|
||||
*/
|
||||
PRBool PREF_StringPrefChanged(PrefSet* prefs, char* key, char* value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_GetBoolPref()
|
||||
* Purpose: Retrieves the boolean pref for (key) from (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: on return, filled with the boolean pref value.
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*/
|
||||
SSMStatus PREF_GetBoolPref(PrefSet* prefs, char* key, PRBool* value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_SetBoolPref()
|
||||
* Purpose: Sets the boolean pref for (key) in (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: the boolean value to set for the key.
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*/
|
||||
SSMStatus PREF_SetBoolPref(PrefSet* prefs, char* key, PRBool value);
|
||||
|
||||
/*
|
||||
* Function: PRBool PREF_BoolPrefChanged()
|
||||
* Purpose: Compares the value in the set with the given value and determines
|
||||
* if it has changed
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: the boolean value to compare.
|
||||
* - returns: PR_TRUE if the value does not match or the key was not found
|
||||
* (i.e. change needs to be saved); otherwise PR_FALSE
|
||||
*
|
||||
* Notes: this is useful when one wants to determine the items that need
|
||||
* to be permanently saved.
|
||||
*/
|
||||
PRBool PREF_BoolPrefChanged(PrefSet* prefs, char* key, PRBool value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_GetIntPref()
|
||||
* Purpose: Retrieves the integer pref for (key) from (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: on return, filled with the integer pref value
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*/
|
||||
SSMStatus PREF_GetIntPref(PrefSet* prefs, char* key, PRIntn* value);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus PREF_SetIntPref()
|
||||
* Purpose: Sets the integer pref (key) in (prefs).
|
||||
* Arguments and return values:
|
||||
* - prefs: the prefs set
|
||||
* - key: the key for the pref item
|
||||
* - value: the integer value to set for the key
|
||||
* - returns: PR_SUCCESS if successful; error code otherwise
|
||||
*/
|
||||
SSMStatus PREF_SetIntPref(PrefSet* prefs, char* key, PRIntn value);
|
||||
|
||||
/*
|
||||
* Function: PRBool PREF_IntPrefChanged()
|
||||
* Purpose: Compares the value in the set with the given value and determines
|
||||
* if it has changed
|
||||
* Arguments and return values:
|
||||
* - prefs: the pref set
|
||||
* - key: the key for the pref item
|
||||
* - value: the integer value to compare.
|
||||
* - returns: PR_TRUE if the value does not match or the key was not found
|
||||
* (i.e. change needs to be saved); otherwise PR_FALSE
|
||||
*
|
||||
* Notes: this is useful when one wants to determine the items that need
|
||||
* to be permanently saved.
|
||||
*/
|
||||
PRBool PREF_IntPrefChanged(PrefSet* prefs, char* key, PRIntn value);
|
||||
|
||||
/****
|
||||
* Functions and typedefs needed to iterated over multiple similar pref items.
|
||||
* Used to find all specified LDAP servers for UI lookup.
|
||||
***/
|
||||
typedef struct
|
||||
{
|
||||
char* childList;
|
||||
char* parent;
|
||||
unsigned int bufsize;
|
||||
} PrefChildIter;
|
||||
|
||||
|
||||
SSMStatus PREF_CreateChildList(PrefSet * prefs, const char* parent_key,
|
||||
char ***child_list);
|
||||
SSMStatus pref_append_value(char *** list, char * value);
|
||||
|
||||
|
||||
#endif /* PREFS LITE (tm) */
|
||||
#endif /* _PREFS_H_ */
|
2717
security/psm/server/processmsg.c
Normal file
2717
security/psm/server/processmsg.c
Normal file
File diff suppressed because it is too large
Load Diff
66
security/psm/server/processmsg.h
Normal file
66
security/psm/server/processmsg.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef PROCESSMSG_H_
|
||||
#define PROCESSMSG_H_
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessDecodeAndCreateTempCert(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessDestroyCert(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessGetKeyChoiceList(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
/* This function runs on a separate thread and has a single argument */
|
||||
typedef struct {
|
||||
SSMControlConnection * ctrl;
|
||||
SECItem * msg;
|
||||
} genKeyArg;
|
||||
void
|
||||
SSMControlConnection_ProcessGenKeyOldStyle(void * arg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessDecodeCertRequest(SSMControlConnection * ctrl,
|
||||
SECItem * msg);
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessFindCertByNickname(SSMControlConnection *ctrl, SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessFindCertByKey(SSMControlConnection *ctrl, SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessFindCertByEmailAddr(SSMControlConnection *ctrl, SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessAddCertToDB(SSMControlConnection *ctrl, SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessMatchUserCert(SSMControlConnection *ctrl, SECItem *msg);
|
||||
|
||||
SSMStatus SSMControlConnection_ProcessPickleSecurityStatusRequest(SSMControlConnection* ctrl,
|
||||
SECItem* msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessLocalizedTextRequest(SSMControlConnection *ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessRedirectCompare(SSMControlConnection *ctrl,
|
||||
SECItem * msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessDecodeCRLRequest(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
|
||||
PRStatus
|
||||
SSMControlConnection_ProcessSecurityAdvsiorRequest(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessGetExtensionRequest(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
SSMStatus
|
||||
SSMControlConnection_ProcessHTMLCertInfoRequest(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
#endif /*PROCESSMSG_H_*/
|
412
security/psm/server/profile.c
Normal file
412
security/psm/server/profile.c
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "ctrlconn.h"
|
||||
#include "serv.h"
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winreg.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* local prototypes */
|
||||
char* SSM_PREF_WinRegQueryCharValueEx(HKEY key, const char* subKey);
|
||||
|
||||
char* SSM_PROF_WinGetNetworkProfileDir(void);
|
||||
char* SSM_PROF_WinGetProfileDirFromName(const char* profName);
|
||||
char* SSM_PROF_WinGetDefaultProfileDB(void);
|
||||
#endif
|
||||
|
||||
|
||||
char* SSM_PROF_GetProfileDirectory(SSMControlConnection* conn)
|
||||
{
|
||||
char* path = NULL;
|
||||
PRFileInfo info;
|
||||
#ifdef WIN32
|
||||
char* profDB = NULL;
|
||||
#endif
|
||||
|
||||
if (conn == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
path = PR_smprintf("%s/.netscape", PR_GetEnv("HOME"));
|
||||
if (path == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
/* Folks tell me that the correct way to get it is through the Netscape
|
||||
* registry, not the Windows registry, but I can't confirm that story.
|
||||
* I will keep investigating.
|
||||
* Furthermore, if we complete migration and once Cartman owns its own
|
||||
* registry space, we will not have to worry about locating the profile
|
||||
* directory this way.
|
||||
*/
|
||||
#if 0 /* XXX for now we only get the default directory */
|
||||
/* check network installations */
|
||||
path = SSM_PROF_WinGetNetworkProfileDir();
|
||||
if (path != NULL) {
|
||||
goto check;
|
||||
}
|
||||
|
||||
/* next, try to get it directly from the user registry */
|
||||
path = SSM_PROF_WinGetProfileDirFromName(conn->m_profileName);
|
||||
if (path != NULL) {
|
||||
goto check;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* couldn't find the profile; look for the default */
|
||||
profDB = SSM_PROF_WinGetDefaultProfileDB();
|
||||
if (profDB == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the profile directory */
|
||||
path = PR_smprintf("%s\\%s", profDB, conn->m_profileName);
|
||||
if ((PR_GetFileInfo(path, &info) != PR_SUCCESS) ||
|
||||
(info.type != PR_FILE_DIRECTORY)) {
|
||||
/* couldn't find it there either; try to guess it */
|
||||
SSM_DEBUG("Cannot find a profile in %s. Trying again...\n", path);
|
||||
PR_Free(path);
|
||||
path = PR_smprintf("C:\\Program Files\\Netscape\\Users\\%s",
|
||||
conn->m_profileName);
|
||||
if (path == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
else {
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check whether the directory exists */
|
||||
if ((PR_GetFileInfo(path, &info) != PR_SUCCESS) ||
|
||||
(info.type != PR_FILE_DIRECTORY)) {
|
||||
SSM_DEBUG("Can't find a profile in %s.\n", path);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
SSM_DEBUG("The directory is %s.\n", path);
|
||||
goto done;
|
||||
loser:
|
||||
if (path != NULL) {
|
||||
PR_Free(path);
|
||||
path = NULL;
|
||||
}
|
||||
done:
|
||||
#ifdef WIN32
|
||||
if (profDB != NULL) {
|
||||
PR_Free(profDB);
|
||||
}
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
/* Function: char* SSM_PROF_WinGetNetworkProfileDir(void)
|
||||
* Purpose: returns the profile directory from Windows registry in case of
|
||||
* network installation
|
||||
* Arguments and return values:
|
||||
* - returns: profile directory; NULL otherwise
|
||||
*
|
||||
* Note: this is still Nova-specific. Seamonkey does not support network
|
||||
* installations?
|
||||
* Key: "HKEY_CURRENT_USER\SOFTWARE\Netscape\Netscape Navigator\UserInfo\
|
||||
* DirRoot"
|
||||
*/
|
||||
char* SSM_PROF_WinGetNetworkProfileDir(void)
|
||||
{
|
||||
char* subKey = "SOFTWARE\\Netscape\\Netscape Navigator\\UserInfo";
|
||||
LONG rv;
|
||||
char* ret = NULL;
|
||||
HKEY keyRet = NULL;
|
||||
|
||||
rv = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, (DWORD)0, KEY_QUERY_VALUE,
|
||||
&keyRet);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = SSM_PREF_WinRegQueryCharValueEx(keyRet, "DirRoot");
|
||||
if (ret == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
goto done;
|
||||
loser:
|
||||
if (ret != NULL) {
|
||||
PR_Free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
done:
|
||||
if (keyRet != NULL) {
|
||||
RegCloseKey(keyRet);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Function: char* SSM_PROF_WinGetProfileDirFromName()
|
||||
* Purpose: returns the profile directory that belongs to the profile from
|
||||
* the registry
|
||||
* Arguments and return values:
|
||||
* - profName: profile name
|
||||
* - returns: profile directory; NULL if failure
|
||||
*
|
||||
* Note: this is still Nova-specific. A lot has to be ifdef'd when Seamonkey
|
||||
* comes online.
|
||||
* key: "HKEY_LOCAL_MACHINE\SOFTWARE\Netscape\Netscape Navigator\Users\(name)\
|
||||
* DirRoot"
|
||||
*/
|
||||
char* SSM_PROF_WinGetProfileDirFromName(const char* profName)
|
||||
{
|
||||
char* subKey = NULL;
|
||||
LONG rv;
|
||||
char* ret = NULL;
|
||||
HKEY keyRet = NULL;
|
||||
|
||||
PR_ASSERT(profName != NULL);
|
||||
|
||||
subKey = PR_smprintf("SOFTWARE\\Netscape\\Netscape Navigator\\Users\\%s",
|
||||
profName);
|
||||
if (subKey == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* open the user's registry key */
|
||||
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, (DWORD)0, KEY_QUERY_VALUE,
|
||||
&keyRet);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the string */
|
||||
ret = SSM_PREF_WinRegQueryCharValueEx(keyRet, "DirRoot");
|
||||
if (ret == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
goto done;
|
||||
loser:
|
||||
if (ret != NULL) {
|
||||
PR_Free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
done:
|
||||
if (keyRet != NULL) {
|
||||
RegCloseKey(keyRet);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ssm_prof_cut_idstring(char** idString)
|
||||
{
|
||||
char* marker = NULL;
|
||||
char* subString = NULL;
|
||||
PRUint32 fullLength;
|
||||
int subSize;
|
||||
|
||||
PR_ASSERT(*idString != NULL);
|
||||
|
||||
fullLength = strlen(*idString);
|
||||
/* traverse backward to find the last backslash */
|
||||
marker = strrchr(*idString, '\\');
|
||||
if (marker == NULL) {
|
||||
/* no backslash? strange but return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* found the backslash */
|
||||
subSize = marker - *idString;
|
||||
subString = (char*)PR_Calloc(fullLength-subSize+1, sizeof(char));
|
||||
if (subString == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
memcpy(subString, marker, fullLength-subSize);
|
||||
if (_stricmp(subString, "Communicator") == 0 ||
|
||||
_stricmp(subString, "Commun~1") == 0) {
|
||||
/* "Communicator" is at the end of the installation directory path.
|
||||
* Take it out.
|
||||
*/
|
||||
char* newID = NULL;
|
||||
|
||||
newID = (char*)PR_Calloc(subSize+1, sizeof(char));
|
||||
if (newID != NULL) {
|
||||
memcpy(newID, *idString, subSize);
|
||||
PR_Free(*idString);
|
||||
*idString = PL_strdup(newID);
|
||||
PR_Free(newID);
|
||||
}
|
||||
}
|
||||
loser:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function: char* SSM_PROF_WinGetDefaultProfileDB()
|
||||
* Purpose: tries to deduce the default profile db of the current version of
|
||||
* Communicator
|
||||
* Arguments and return values:
|
||||
* - returns: newly allocated profile db string; NULL if failure
|
||||
*
|
||||
* Note: This is Nova-specific. Now, this function is being used to supply
|
||||
* the "default" profile directory for 3rd party applications.
|
||||
* Key: "HKEY_LOCAL_MACHINE\SOFTWARE\Netscape\Netscape Navigator\(current
|
||||
* version)\Main\Install Directory"
|
||||
*/
|
||||
char* SSM_PROF_WinGetDefaultProfileDB(void)
|
||||
{
|
||||
char* subKey = "SOFTWARE\\Netscape\\Netscape Navigator";
|
||||
LONG rv;
|
||||
char* ret = NULL;
|
||||
HKEY keyRet = NULL;
|
||||
char* cvString = NULL;
|
||||
char* idKey = NULL;
|
||||
char* idString = NULL;
|
||||
|
||||
/* open the program registry */
|
||||
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, (DWORD)0, KEY_QUERY_VALUE,
|
||||
&keyRet);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the current version info first */
|
||||
cvString = SSM_PREF_WinRegQueryCharValueEx(keyRet, "currentVersion");
|
||||
if (cvString == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* now, get the actual default install directory for the current version */
|
||||
idKey = PR_smprintf("%s\\%s\\Main", subKey, cvString);
|
||||
if (idKey == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* open a new key for the install directory */
|
||||
RegCloseKey(keyRet);
|
||||
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, idKey, (DWORD)0, KEY_QUERY_VALUE,
|
||||
&keyRet);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
idString = SSM_PREF_WinRegQueryCharValueEx(keyRet, "Install Directory");
|
||||
if (idString == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* wait, we would like to remove "Communicator" at the end of the
|
||||
* installation path to get the profiles directory correctly
|
||||
*/
|
||||
ssm_prof_cut_idstring(&idString);
|
||||
if (idString == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* append the user name */
|
||||
ret = PR_smprintf("%s\\Users", idString);
|
||||
if (ret == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (ret != NULL) {
|
||||
PR_Free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
done:
|
||||
if (cvString != NULL) {
|
||||
PR_Free(cvString);
|
||||
}
|
||||
if (idKey != NULL) {
|
||||
PR_Free(idKey);
|
||||
}
|
||||
if (idString != NULL) {
|
||||
PR_Free(idString);
|
||||
}
|
||||
if (keyRet != NULL) {
|
||||
RegCloseKey(keyRet);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* allocates memory for and retrieves string data from the Windows registry
|
||||
* (wrapper for RegQueryValueEx())
|
||||
* this should be incorporated in the prefs headers later
|
||||
* Warning: key should have been already opened with RegOpenKeyEx()!
|
||||
*/
|
||||
char* SSM_PREF_WinRegQueryCharValueEx(HKEY key, const char* subKey)
|
||||
{
|
||||
LONG rv;
|
||||
DWORD type;
|
||||
DWORD size = 0;
|
||||
char* data = NULL;
|
||||
|
||||
PR_ASSERT(key != NULL && subKey != NULL);
|
||||
|
||||
/* size the string */
|
||||
rv = RegQueryValueEx(key, (LPTSTR)subKey, NULL, &type, NULL, &size);
|
||||
if (rv != ERROR_SUCCESS || size == 0) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
data = (char*)PR_Malloc(size);
|
||||
if (data == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = RegQueryValueEx(key, (LPTSTR)subKey, NULL, &type, (LPBYTE)data,
|
||||
&size);
|
||||
if (rv != ERROR_SUCCESS || size == 0) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (data != NULL) {
|
||||
PR_Free(data);
|
||||
data = NULL;
|
||||
}
|
||||
done:
|
||||
return data;
|
||||
}
|
||||
#endif
|
50
security/psm/server/profile.h
Normal file
50
security/psm/server/profile.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_PROFILE_H__
|
||||
#define __SSM_PROFILE_H__
|
||||
|
||||
#include "ctrlconn.h"
|
||||
|
||||
/* Function: char* SSM_PROF_GetProfileDirectory()
|
||||
* Purpose: given the control connection, locates the profile directory which
|
||||
* contains the cert/key database
|
||||
* Arguments and return values:
|
||||
* - conn: control connection; the most useful information here is the
|
||||
* profile name (or lack thereof) and the type of client (not used
|
||||
* actively yet)
|
||||
* - returns: char* string for the profile path; the existence of the directory
|
||||
* is also checked; the string should be freed by the caller
|
||||
*/
|
||||
char* SSM_PROF_GetProfileDirectory(SSMControlConnection* conn);
|
||||
|
||||
#endif
|
1108
security/psm/server/resource.c
Normal file
1108
security/psm/server/resource.c
Normal file
File diff suppressed because it is too large
Load Diff
576
security/psm/server/resource.h
Normal file
576
security/psm/server/resource.h
Normal file
@ -0,0 +1,576 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
SSMResource is the base class for anything that wants to be accessible
|
||||
to the NSM client.
|
||||
|
||||
To subclass from SSMResource, you *must* do the following:
|
||||
|
||||
* Define a resource type for your class in the SSMResourceType enumerated
|
||||
type below.
|
||||
|
||||
* Embed an SSMResource struct as the first member of your class struct.
|
||||
This is the way that polymorphism works in this class system: you can freely
|
||||
change type on a pointer to an SSMResource or its subclasses, because
|
||||
the memory pointed to is guaranteed to consist of the base class followed
|
||||
by subclass members. Subsequently, to subclass from any subclass of
|
||||
SSMResource, you must embed an instance of the existing class as the
|
||||
first member of your subclass.
|
||||
|
||||
(This is how it's done in C++, btw. Why don't we use C++, you ask?
|
||||
Because of variations among C++ compilers, and because the rest of the
|
||||
group will hate us if we do.)
|
||||
|
||||
* Provide the following member functions for your class:
|
||||
|
||||
- SSMStatus YourClassName_Create (void *arg, SSMResource **res)
|
||||
Requirement: MANDATORY
|
||||
Description: This creates an instance of your class. Necessary because
|
||||
you need to allocate a properly sized chunk of memory,
|
||||
and because the _Create routine also must call the correct
|
||||
_Init method to properly initialize member data.
|
||||
Parameters: arg - an initialization argument specific to the class.
|
||||
res - Returns the newly created instance, or NULL if error.
|
||||
Return value - PR_SUCCESS for success, etc.
|
||||
|
||||
- SSMStatus YourClassName_Init([signature varies])
|
||||
Requirement: MANDATORY
|
||||
Description: This initializes member data in your class.
|
||||
Parameters: Dependent on how your class needs to be initialized.
|
||||
The calling convention is used only by your _Create method,
|
||||
and by the _Init method of all subclasses of your class.
|
||||
|
||||
- SSMStatus YourClassName_Destroy(SSMResource *res, PRBool doFree)
|
||||
Requirement: MANDATORY
|
||||
Description: This deallocates member data in an instance of your
|
||||
class, and optionally deallocates the class instance
|
||||
itself (if doFree is true). When calling superclass
|
||||
_Destroy functions, should always pass PR_FALSE in
|
||||
doFree. The default method deallocates the object with
|
||||
PR_Free.
|
||||
Parameters: res - An instance of your class.
|
||||
doFree - if PR_TRUE, you must free (res). Presumably,
|
||||
if doFree is true, then this object was created
|
||||
by your _Create method above, so use whatever
|
||||
memory deallocator corresponds to how the
|
||||
instance was allocated in _Create.
|
||||
Return value - PR_SUCCESS if successful, etc.
|
||||
|
||||
- SSMStatus YourClassName_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
Requirement: MANDATORY
|
||||
Description: This is called when the client or part of the NSM server
|
||||
wants to know all the available attributes of a particular
|
||||
object.
|
||||
Parameters: res - An instance of your class.
|
||||
ids - Returns an array (allocated with PR_CALLOC) of
|
||||
the available IDs.
|
||||
count - Returns the number of IDs in (ids).
|
||||
Return value - PR_SUCCESS if successful
|
||||
(Other underlying errors as appropriate)
|
||||
|
||||
- SSMStatus YourClassName_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value)
|
||||
Requirement: MANDATORY
|
||||
Description: This is called when a client requests data from an
|
||||
instance of your class. The default method simply
|
||||
returns PR_FAILURE.
|
||||
Parameters: res - An instance of your class.
|
||||
attrID - The ID of the requested member data.
|
||||
value - The attribute value struct to be filled in.
|
||||
Return value - PR_SUCCESS if successful
|
||||
SSM_ERR_BAD_FID: Field ID is incorrect.
|
||||
(Other underlying errors as appropriate)
|
||||
|
||||
- SSMStatus YourClassName_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value)
|
||||
Requirement: Optional
|
||||
Description: This is called when a client wants to change a member
|
||||
of an instance of your class. This only needs to be
|
||||
implemented if you want to accept values from the
|
||||
client (most classes will not want to do this). The
|
||||
default method simply returns PR_FAILURE.
|
||||
Parameters: res - An instance of your class.
|
||||
attrID - The ID of the member to be changed.
|
||||
value - The value to set the attribute to.
|
||||
Return value - PR_SUCCESS if successful
|
||||
SSM_ERR_BAD_FID: Field ID is incorrect.
|
||||
SSM_ERR_ATTRTYPE_MISMATCH: Type mismatch
|
||||
(Other underlying errors as appropriate)
|
||||
|
||||
|
||||
- void YourClassName_Invariant(YourClassName *obj)
|
||||
Requirement: Optional (but recommended)
|
||||
Description: Performs invariant checking on member data particular
|
||||
to your class. Normally this is done by calling PR_ASSERT
|
||||
on typical expected conditions in your member data.
|
||||
Your invariant method should call the superclass' Invariant
|
||||
method to ensure proper invariant checking of the whole
|
||||
instance.
|
||||
Parameters: obj - An instance of your class.
|
||||
Return value - PR_SUCCESS if successful
|
||||
(Errors as appropriate)
|
||||
|
||||
* Register your class by making a call to SSM_RegisterResourceType
|
||||
from inside SSM_ResourceInit in resource.c, passing whatever
|
||||
methods your class overrides. Note that in some subclasses (such as
|
||||
SSMConnection), additional virtual functions are provided for other
|
||||
polymorphic functionality. You'll need to override those methods
|
||||
inside your _Init routine directly.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __SSM_RESOURCE_H__
|
||||
#define __SSM_RESOURCE_H__
|
||||
|
||||
#include "ssmdefs.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "rsrcids.h"
|
||||
#include "hashtbl.h"
|
||||
#include "protocol.h"
|
||||
#include "protocolf.h"
|
||||
#include "prtypes.h"
|
||||
#include "nspr.h"
|
||||
#include "serv.h"
|
||||
#include "collectn.h"
|
||||
|
||||
|
||||
/* typedef struct SSMResource SSMResource; */
|
||||
/* SSMControlConnection is defined in ctrlcon.h */
|
||||
/* typedef struct SSMControlConnection SSMControlConnection; */
|
||||
typedef struct HTTPRequest HTTPRequest;
|
||||
|
||||
typedef SSMStatus (*SSMResourceCreateFunc) (void *arg,
|
||||
SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
|
||||
typedef SSMStatus (*SSMResourceDestroyFunc)(SSMResource *res, PRBool doFree);
|
||||
|
||||
typedef SSMStatus (*SSMResourceGetAttrIDsFunc)(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
typedef SSMStatus (*SSMResourceGetAttrFunc)(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
typedef SSMStatus (*SSMResourceSetAttrFunc)(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
typedef SSMStatus (*SSMResourceShutdownFunc)(SSMResource *res,
|
||||
SSMStatus status);
|
||||
|
||||
typedef SSMStatus (*SSMResourcePickleFunc)(SSMResource *res,
|
||||
PRIntn * len,
|
||||
void **value);
|
||||
|
||||
typedef SSMStatus (*SSMResourceUnpickleFunc)(SSMResource ** res,
|
||||
SSMControlConnection * conn,
|
||||
PRIntn len, void * value);
|
||||
|
||||
typedef SSMStatus (*SSMResourceHTMLFunc)(SSMResource *res,
|
||||
PRIntn * len,
|
||||
void ** value);
|
||||
|
||||
/* be sure to include <nlsutil.h> before your implementations */
|
||||
typedef SSMStatus (*SSMResourcePrintFunc)(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParams,
|
||||
char ** value,
|
||||
char **resultStr);
|
||||
|
||||
typedef SSMStatus (*SSMSubmitHandlerFunc)(struct SSMResource *res,
|
||||
HTTPRequest *req);
|
||||
|
||||
/* What do we do with a resource when the client wants to destroy it? */
|
||||
typedef enum
|
||||
{
|
||||
SSM_CLIENTDEST_NOTHING = (PRUint32) 0, /* take no action */
|
||||
SSM_CLIENTDEST_FREE, /* free the resource */
|
||||
SSM_CLIENTDEST_SHUTDOWN /* shut down threads
|
||||
before freeing object */
|
||||
} SSMClientDestroyAction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SSM_BUTTON_NONE = 0,
|
||||
SSM_BUTTON_CANCEL,
|
||||
SSM_BUTTON_OK
|
||||
} SSMUIButtonType;
|
||||
|
||||
typedef struct SSMResourceClass SSMResourceClass;
|
||||
|
||||
/* typedef struct SSMResource SSMResource; */
|
||||
|
||||
struct SSMResource
|
||||
{
|
||||
SSMResourceClass *m_class; /* Pointer to class object */
|
||||
SSMResourceID m_id;
|
||||
SSMResourceType m_classType;
|
||||
SSMControlConnection* m_connection; /* Control connection
|
||||
that owns the resource */
|
||||
SSMStatus m_status; /* Status of last closing thread.
|
||||
Indicates whether to do an
|
||||
emergency shutdown (interrupt all
|
||||
threads, post shutdown msgs, etc.)
|
||||
or to allow continuing operation. */
|
||||
PRIntn m_threadCount; /* Number of service threads */
|
||||
PRMonitor * m_lock; /* Thread lock for this connection
|
||||
object */
|
||||
PRMonitor * m_UILock; /* Use this lock for waiting and
|
||||
* notifying for UI events.
|
||||
*/
|
||||
PRBool m_UIBoolean; /* This value is set by the Notify
|
||||
* on UILock.
|
||||
*/
|
||||
PRIntn m_refCount; /* Reference count */
|
||||
PRIntn m_clientCount; /* Number of client references */
|
||||
SSMUIButtonType m_buttonType; /* This will be set when a UI event
|
||||
* button event happens and the
|
||||
* target is the resource.
|
||||
*/
|
||||
char * m_formName; /* The name of the form that created
|
||||
* the UI event causing the form submit
|
||||
* handler to get called.
|
||||
*/
|
||||
char * m_fileName; /* If this object requested a file path,
|
||||
* then this field will be used to
|
||||
* store the returned value.
|
||||
*/
|
||||
void * m_uiData; /* Using this value to pass misc UI
|
||||
* information.
|
||||
*/
|
||||
|
||||
CMTItem m_clientContext; /* This is set by client and passed back
|
||||
* to client during UI operations */
|
||||
|
||||
PRThread * m_waitThread; /*Thread waiting for us to shut down*/
|
||||
SSMClientDestroyAction m_clientDest;/* what to do if client destroys us */
|
||||
|
||||
SSMResourceDestroyFunc m_destroy_func;
|
||||
SSMResourceShutdownFunc m_shutdown_func;
|
||||
SSMResourceGetAttrIDsFunc m_getids_func;
|
||||
SSMResourceGetAttrFunc m_get_func;
|
||||
SSMResourceSetAttrFunc m_set_func;
|
||||
SSMResourcePickleFunc m_pickle_func;
|
||||
SSMResourceHTMLFunc m_html_func;
|
||||
SSMResourcePrintFunc m_print_func;
|
||||
SSMSubmitHandlerFunc m_submit_func;
|
||||
PRBool m_resourceShutdown;
|
||||
};
|
||||
|
||||
/* Macros */
|
||||
#define RESOURCE_CLASS(x) ( ((SSMResource *) (x))->m_classType )
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_CreateResource
|
||||
**
|
||||
** DESCRIPTION: Create a new resource of type (type). If (rawData)
|
||||
** is not NULL, get initial values from that structure.
|
||||
** rawData is treated differently depending on the type
|
||||
** of resource being created; for example, a certificate
|
||||
** object will store a reference to the certificate
|
||||
** structure in (rawData), whereas a connection resource
|
||||
** will copy values out of an SSMHashTable pointed to
|
||||
** by (rawData).
|
||||
** INPUTS:
|
||||
** type
|
||||
** The type of resource to be created.
|
||||
** arg
|
||||
** A type-dependent initial value for attribute(s) of the newly
|
||||
** created resource.
|
||||
** resID
|
||||
** Returns the ID of the newly created resource.
|
||||
** result
|
||||
** Returns a pointer to the newly created resource.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
*************************************************************/
|
||||
SSMStatus SSM_CreateResource(SSMResourceType type,
|
||||
void *arg,
|
||||
SSMControlConnection * conn,
|
||||
SSMResourceID *resID,
|
||||
SSMResource **result);
|
||||
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_GetResAttribute
|
||||
**
|
||||
** DESCRIPTION: Get an attribute from an SSMResource object.
|
||||
**
|
||||
** INPUTS:
|
||||
** res
|
||||
** The resource from which an attribute is to be retrieved.
|
||||
** attrID
|
||||
** The field/resource ID of the attribute.
|
||||
** attrType
|
||||
** The expected type of the retrieved attribute.
|
||||
** value
|
||||
** The attribute value to be filled in.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
**
|
||||
** NOTES:
|
||||
** ### mwelch All this memory allocation can be problematic.
|
||||
*************************************************************/
|
||||
SSMStatus SSM_GetResAttribute(SSMResource *res, SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_SetResAttribute
|
||||
**
|
||||
** DESCRIPTION: Set an attribute on an SSMResource object. If
|
||||
** the attribute does not yet exist, it is created.
|
||||
**
|
||||
** INPUTS:
|
||||
** res
|
||||
** The resource in which an attribute is to be changed.
|
||||
** attrID
|
||||
** The field/resource ID of the attribute.
|
||||
** value
|
||||
** A pointer to the value of the newly changed attribute. The value
|
||||
** is copied into the resource.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
*************************************************************/
|
||||
SSMStatus SSM_SetResAttribute(SSMResource *res, SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_PickleResource
|
||||
**
|
||||
** DESCRIPTION: Pickle resource.
|
||||
**
|
||||
** INPUTS:
|
||||
** res
|
||||
** The resource to be pickled.
|
||||
**
|
||||
** OUTPUTS:
|
||||
** len
|
||||
** Length of the pickled blob.
|
||||
** value
|
||||
** Pickled resource.
|
||||
**
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or NSPR error code.
|
||||
*************************************************************/
|
||||
SSMStatus
|
||||
SSM_PickleResource(SSMResource * res, PRIntn * len, void ** value);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_FreeResource
|
||||
**
|
||||
** DESCRIPTION: Free a reference on (res). If the reference count
|
||||
** reaches 0, (res) is destroyed.
|
||||
**
|
||||
** INPUTS:
|
||||
** res
|
||||
** The resource to be dereferenced.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
*************************************************************/
|
||||
SSMStatus SSM_FreeResource(SSMResource *res);
|
||||
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_GetResourceReference
|
||||
**
|
||||
** DESCRIPTION: Get a reference on (res).
|
||||
**
|
||||
** INPUTS:
|
||||
** res
|
||||
** The resource to be referenced.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE or the underlying NSPR error,
|
||||
** if it is available.
|
||||
*************************************************************/
|
||||
SSMStatus SSM_GetResourceReference(SSMResource *res);
|
||||
|
||||
/************************************************************
|
||||
** FUNCTION: SSM_RegisterResourceType
|
||||
**
|
||||
** DESCRIPTION: Register a resource type within the Cartman server.
|
||||
**
|
||||
** INPUTS:
|
||||
** type
|
||||
** The new type to be registered.
|
||||
** superClass
|
||||
** Inherit functions from the already-registered superclass.
|
||||
** if (superClass) is not SSM_RESTYPE_NULL and any function
|
||||
** parameters below are NULL, those functions are inherited
|
||||
** from the indicated superclass.
|
||||
** createFunc, rDestFunc, setFunc, getFunc
|
||||
** Accessor functions for the resource.
|
||||
** RETURNS:
|
||||
** If successful, returns PR_SUCCESS.
|
||||
** If failed, returns either PR_FAILURE, the underlying NSPR error,
|
||||
** or the following values:
|
||||
** SSM_ERR_INVALID_FUNC: (superClass) was SSM_RESTYPE_NULL
|
||||
** and one or more of the function parameters
|
||||
** was also NULL.
|
||||
*************************************************************/
|
||||
|
||||
SSMStatus SSM_RegisterResourceType(char * className,
|
||||
SSMResourceType type,
|
||||
SSMResourceType superClass,
|
||||
SSMClientDestroyAction cDestAction,
|
||||
SSMResourceCreateFunc createFunc,
|
||||
SSMResourceDestroyFunc destFunc,
|
||||
SSMResourceShutdownFunc shutdownFunc,
|
||||
SSMResourceGetAttrIDsFunc getIDsFunc,
|
||||
SSMResourceGetAttrFunc getFunc,
|
||||
SSMResourceSetAttrFunc setFunc,
|
||||
SSMResourcePickleFunc pickleFunc,
|
||||
SSMResourceUnpickleFunc unpickleFunc,
|
||||
SSMResourceHTMLFunc htmlFunc,
|
||||
SSMResourcePrintFunc printFunc,
|
||||
SSMSubmitHandlerFunc submitFunc);
|
||||
|
||||
PRBool SSM_IsA(SSMResource *res, SSMResourceType type);
|
||||
PRBool SSM_IsAKindOf(SSMResource *res, SSMResourceType type);
|
||||
|
||||
SSMStatus SSM_ClientGetResourceReference(SSMResource *res, SSMResourceID *id);
|
||||
SSMStatus SSM_ShutdownResource(SSMResource *res, SSMStatus status);
|
||||
SSMStatus SSM_ClientDestroyResource(SSMControlConnection *connection,
|
||||
SSMResourceID rid, SSMResourceType type);
|
||||
void SSM_LockResource(SSMResource *res);
|
||||
SSMStatus SSM_UnlockResource(SSMResource *res);
|
||||
SSMStatus SSM_WaitResource(SSMResource *res, PRIntervalTime ticks);
|
||||
SSMStatus SSM_WaitForOKCancelEvent(SSMResource *res, PRIntervalTime ticks);
|
||||
SSMStatus SSM_NotifyOKCancelEvent(SSMResource *res);
|
||||
SSMStatus SSM_NotifyResource(SSMResource *res);
|
||||
|
||||
void SSM_LockUIEvent(SSMResource *res);
|
||||
SSMStatus SSM_UnlockUIEvent(SSMResource *res);
|
||||
SSMStatus SSM_WaitUIEvent(SSMResource *res, PRIntervalTime ticks);
|
||||
SSMStatus SSM_NotifyUIEvent(SSMResource *);
|
||||
|
||||
SSMStatus SSM_PickleResource(SSMResource * res, PRIntn * len, void ** value);
|
||||
SSMStatus SSM_UnpickleResource(SSMResource ** res, SSMResourceType type,
|
||||
SSMControlConnection * connection,
|
||||
PRIntn len, void * value);
|
||||
|
||||
SSMStatus SSM_MessageFormatResource(SSMResource *res, char *fmt, PRIntn numParam,
|
||||
char ** value,
|
||||
char **resultStr);
|
||||
|
||||
SSMStatus SSMResource_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMResource_Destroy(SSMResource *res, PRBool doFree);
|
||||
SSMStatus SSMResource_Shutdown(SSMResource *res, SSMStatus status);
|
||||
SSMStatus SSMResource_Init(SSMControlConnection * conn, SSMResource *res,
|
||||
SSMResourceType type);
|
||||
void SSMResource_Invariant(SSMResource *res);
|
||||
|
||||
SSMStatus SSMResource_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMResource_SetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMResource_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMResource_Pickle(SSMResource *res,
|
||||
PRIntn * len,
|
||||
void **value);
|
||||
|
||||
SSMStatus SSMResource_Unpickle(SSMResource ** res,
|
||||
SSMControlConnection *conn,
|
||||
PRIntn len,
|
||||
void * value);
|
||||
|
||||
SSMStatus SSMResource_HTML(SSMResource *res,
|
||||
PRIntn * len,
|
||||
void ** value);
|
||||
|
||||
SSMStatus SSMResource_Print(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParam,
|
||||
char **value,
|
||||
char **resultStr);
|
||||
|
||||
SSMStatus SSMResource_FormSubmitHandler(SSMResource *res,
|
||||
HTTPRequest *req);
|
||||
|
||||
/* ALWAYS pass in msg a string allocated by NSPR (PR_smprintf for example),
|
||||
because the string is freed from within SSM_Debug. */
|
||||
void SSM_Debug(SSMResource *res, char *msg);
|
||||
|
||||
char * SSM_ResourceClassName(SSMResource *res);
|
||||
|
||||
/* Wait for a resource to shut down. */
|
||||
SSMStatus SSM_WaitForResourceShutdown(SSMResource *res);
|
||||
|
||||
/* Register a thread with a resource (or pass arg==NULL for standalone) */
|
||||
void SSM_RegisterThread(char *threadName, SSMResource *arg);
|
||||
void SSM_RegisterNewThread(char *threadName, SSMResource *ptr);
|
||||
|
||||
SSMStatus
|
||||
SSM_ShutdownResource(SSMResource *res, SSMStatus status);
|
||||
|
||||
SSMStatus SSM_HandlePromptReply(SSMResource *res, char *reply);
|
||||
|
||||
/* Initialize resources. Only called by main. */
|
||||
SSMStatus SSM_ResourceInit();
|
||||
|
||||
/* Create a resource thread */
|
||||
PRThread *
|
||||
SSM_CreateThread(SSMResource *res, void (*func)(void *arg));
|
||||
|
||||
#endif
|
179
security/psm/server/serv.h
Normal file
179
security/psm/server/serv.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SERV_H__
|
||||
#define __SERV_H__
|
||||
|
||||
#include "prio.h"
|
||||
#include "prtypes.h"
|
||||
#include "prnetdb.h"
|
||||
#include "prprf.h"
|
||||
#include "prinit.h"
|
||||
#include "prthread.h"
|
||||
#include "prinrval.h"
|
||||
#include "prmon.h"
|
||||
#include "prmem.h"
|
||||
#include "prerror.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "seccomon.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "servimpl.h"
|
||||
#include "protocol.h"
|
||||
#include "ssmerrs.h"
|
||||
|
||||
/* extern int errno; */
|
||||
|
||||
#undef ALLOW_STANDALONE
|
||||
|
||||
#ifdef ALLOW_STANDALONE
|
||||
extern PRBool standalone;
|
||||
#define SSM_ENV_STANDALONE "NSM_STANDALONE"
|
||||
#endif
|
||||
|
||||
/* Environment variables we pay attention to */
|
||||
#ifdef DEBUG
|
||||
#define SSM_ENV_SUPPRESS_CONSOLE "NSM_SUPPRESS_CONSOLE"
|
||||
#define SSM_ENV_LOG_FILE "NSM_LOG_FILE"
|
||||
/* Password must be base64 encoded. */
|
||||
#define SSM_ENV_STATIC_PASSWORD "NSM_PASSWORD"
|
||||
#endif
|
||||
|
||||
#define MAX_CONNECTIONS 5
|
||||
#define LINESIZE 512
|
||||
#define DATA_CONN_MSG_SIZE sizeof(PRFileDesc *)
|
||||
|
||||
|
||||
#define CARTMAN_WAIT_BEFORE_SLEEP (PR_TicksPerSecond() * 60)
|
||||
#define CARTMAN_SPINTIME CARTMAN_WAIT_BEFORE_SLEEP
|
||||
#define CARTMAN_KEEP_CONNECTION_ALIVE (CARTMAN_WAIT_BEFORE_SLEEP * 900)
|
||||
|
||||
/* Some macros to cut down typing when doing memory allocation.*/
|
||||
#define SSM_NEW PR_NEW
|
||||
#define SSM_ZNEW PR_NEWZAP
|
||||
#define SSM_NEW_ARRAY(type,size) (type*)PR_Malloc((size)*sizeof(type))
|
||||
#define SSM_ZNEW_ARRAY(type,size) (type*)PR_Calloc((size),sizeof(type))
|
||||
|
||||
/* Safe strcmp() which compares only based on the shorter
|
||||
of the two lengths. DO NOT USE if you really want to determine
|
||||
string equality -- this is used for sloppy parameter matches. */
|
||||
#define MIN_STRCMP(x,y) strncmp((x), (y), MIN(strlen(x),strlen(y)))
|
||||
|
||||
/* forward declare this type to eliminate circular dependencies */
|
||||
typedef struct SSMResource SSMResource;
|
||||
typedef struct SSMControlConnection SSMControlConnection;
|
||||
|
||||
extern PRUint32 httpPort;
|
||||
|
||||
PRIntn mainLoop(PRIntn argc, char ** argv);
|
||||
PRFileDesc * SSM_OpenControlPort(void);
|
||||
PRFileDesc * SSM_OpenPort(void);
|
||||
PRBool SSM_SocketPeerCheck(PRFileDesc *sock, PRBool isCtrl);
|
||||
|
||||
SSMPolicyType SSM_GetPolicy(void);
|
||||
|
||||
#define THREAD_NAME_LEN 128
|
||||
|
||||
SSMStatus SSM_AddLogSocket(PRFileDesc *sock);
|
||||
void SSM_DebugP(char *fmt, ...);
|
||||
|
||||
#if defined(WIN32)
|
||||
#define STRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
|
||||
#elif defined(XP_UNIX)
|
||||
#define STRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
|
||||
#else
|
||||
/* Should really figure out how this platform does this */
|
||||
int SSM_strncasecmp(const char *s1, const char *s2, size_t count);
|
||||
#define STRNCASECMP(s1,s2,n) SSM_strncasecmp((s1),(s2),(n))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define SSM_DEBUG SSM_DebugP
|
||||
#else
|
||||
#define SSM_DEBUG if(0) SSM_DebugP
|
||||
#endif
|
||||
void SSM_DumpBuffer(char *buf, PRIntn len);
|
||||
|
||||
SECItem * SSM_ConstructMessage(PRUintn size);
|
||||
void SSM_FreeEvent(SECItem * event);
|
||||
void SSM_FreeResponse(SSMResponse * response);
|
||||
void SSM_FreeMessage(SECItem * msg);
|
||||
int ssm_ReadThisMany(PRFileDesc * sockID, void * buffer, int thisMany);
|
||||
int ssm_WriteThisMany(PRFileDesc * sockID, void * buffer, int thisMany);
|
||||
|
||||
/* Macros used in http and base64 processing */
|
||||
#undef IS_EOL
|
||||
#define IS_EOL(c) (((c) == 0x0A) || ((c) == 0x0D))
|
||||
#undef IS_WHITESPACE
|
||||
#define IS_WHITESPACE(c) (((c) == '\t') || ((c) == '\n') \
|
||||
|| ((c) == '\r') || ((c) == ' '))
|
||||
|
||||
extern SSMPolicyType policyType;
|
||||
|
||||
SSMStatus SSM_CloseSocketWithLinger(PRFileDesc *sock);
|
||||
|
||||
SSMStatus SSM_RequestFilePathFromUser(SSMResource *res,
|
||||
const char *promptKey,
|
||||
const char *fileRegEx,
|
||||
PRBool getExistingFile);
|
||||
|
||||
char* SSM_GetCharFromKey(const char *key, const char *locale);
|
||||
|
||||
void SSM_HandleFilePathReply(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
void SSM_HandleUserPromptReply(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
char * SSM_ConvertStringToHTMLString(char * string);
|
||||
|
||||
SSMStatus SSM_CopyCMTItem(CMTItem *dest, CMTItem *source);
|
||||
|
||||
#ifdef XP_UNIX
|
||||
void SSM_ReleaseLockFile();
|
||||
#endif /*XP_UNIX*/
|
||||
|
||||
/* Function used on Mac to register threads for later destruction at app quit time. */
|
||||
#ifdef XP_MAC
|
||||
PRThread * SSM_CreateAndRegisterThread(PRThreadType type,
|
||||
void (*start)(void *arg),
|
||||
void *arg,
|
||||
PRThreadPriority priority,
|
||||
PRThreadScope scope,
|
||||
PRThreadState state,
|
||||
PRUint32 stackSize);
|
||||
|
||||
void SSM_KillAllThreads(void);
|
||||
#else
|
||||
#define SSM_CreateAndRegisterThread PR_CreateThread
|
||||
#endif
|
||||
|
||||
#endif
|
83
security/psm/server/servimpl.h
Normal file
83
security/psm/server/servimpl.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SERVIMPL_H__
|
||||
#define __SERVIMPL_H__
|
||||
|
||||
#include "ssmdefs.h"
|
||||
#include "collectn.h"
|
||||
#include "hashtbl.h"
|
||||
|
||||
/* Doc subdirectory */
|
||||
#ifdef XP_UNIX
|
||||
#define PSM_DOC_DIR "./doc/"
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#define PSM_DOC_DIR ":doc:"
|
||||
#else
|
||||
#define PSM_DOC_DIR ".\\doc\\"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Messages passed between data service threads */
|
||||
typedef enum
|
||||
{
|
||||
SSM_DATA_BUFFER = (PRIntn) 0, /* "Here's data to write" */
|
||||
SSM_DATA_PROVIDER_OPEN, /* "My end is open, about to queue data" */
|
||||
SSM_DATA_PROVIDER_SHUTDOWN /* "My socket has closed" */
|
||||
} SSMDataMessageType;
|
||||
|
||||
typedef struct _SSMResponse SSMResponse;
|
||||
typedef struct _SSMResponseQueue SSMResponseQueue;
|
||||
|
||||
void SSM_InitNLS(char *dataDirectory);
|
||||
SECItem * SSM_ConstructMessage(PRUintn size);
|
||||
void SSM_FreeEvent(SECItem * event);
|
||||
void SSM_FreeResponse(SSMResponse * response);
|
||||
void SSM_FreeMessage(SECItem * msg);
|
||||
int SSM_ReadThisMany(PRFileDesc * sockID, void * buffer, int thisMany);
|
||||
int SSM_WriteThisMany(PRFileDesc * sockID, void * buffer, int thisMany);
|
||||
|
||||
SSMStatus SSM_SendQMessage(SSMCollection *c,
|
||||
PRIntn priority,
|
||||
PRIntn type, PRIntn length, char *data,
|
||||
PRBool doBlock);
|
||||
|
||||
SSMStatus SSM_RecvQMessage(SSMCollection *c,
|
||||
PRIntn priority,
|
||||
PRIntn *type, PRIntn *length, char **data,
|
||||
PRBool doBlock);
|
||||
|
||||
void ssm_DrainAndDestroyQueue(SSMCollection **coll);
|
||||
|
||||
#endif
|
||||
|
1303
security/psm/server/servutil.c
Normal file
1303
security/psm/server/servutil.c
Normal file
File diff suppressed because it is too large
Load Diff
584
security/psm/server/signtextres.c
Normal file
584
security/psm/server/signtextres.c
Normal file
@ -0,0 +1,584 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "serv.h"
|
||||
#include "minihttp.h"
|
||||
#include "signtextres.h"
|
||||
#include "protocolf.h"
|
||||
#include "base64.h"
|
||||
#include "secmime.h"
|
||||
#include "newproto.h"
|
||||
#include "messages.h"
|
||||
#include "certres.h"
|
||||
|
||||
#define SSMRESOURCE(object) (&(object)->super)
|
||||
|
||||
SSMStatus
|
||||
SSM_CreateSignTextRequest(SECItem *msg, SSMControlConnection *conn)
|
||||
{
|
||||
SSMStatus rv;
|
||||
SSMSignTextResource *signTextRes = NULL;
|
||||
int i;
|
||||
SignTextRequest request;
|
||||
|
||||
/* Decode the sign text protocol message */
|
||||
if (CMT_DecodeMessage(SignTextRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the resource */
|
||||
rv = SSMControlConnection_GetResource(conn, (SSMResourceID)request.resID,
|
||||
(SSMResource**)&signTextRes);
|
||||
if ((rv != PR_SUCCESS) || (signTextRes == NULL)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get a reference to it */
|
||||
SSM_GetResourceReference(SSMRESOURCE(signTextRes));
|
||||
if (!SSM_IsAKindOf(SSMRESOURCE(signTextRes), SSM_RESTYPE_SIGNTEXT)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request data */
|
||||
signTextRes->m_stringToSign = PL_strdup(request.stringToSign);
|
||||
signTextRes->m_hostName = PL_strdup(request.hostName);
|
||||
if (PL_strcasecmp(request.caOption, "auto") == 0) {
|
||||
signTextRes->m_autoFlag = PR_TRUE;
|
||||
} else if (PL_strcasecmp(request.caOption, "ask") == 0) {
|
||||
signTextRes->m_autoFlag = PR_FALSE;
|
||||
} else {
|
||||
goto loser;
|
||||
}
|
||||
signTextRes->m_numCAs = request.numCAs;
|
||||
if (signTextRes->m_numCAs > 0) {
|
||||
signTextRes->m_caNames = (char **) PR_CALLOC(sizeof(char*)*(signTextRes->m_numCAs));
|
||||
if (!signTextRes->m_caNames) {
|
||||
goto loser;
|
||||
}
|
||||
for (i=0;i<signTextRes->m_numCAs;i++) {
|
||||
signTextRes->m_caNames[i] = PL_strdup(request.caNames[i]);
|
||||
}
|
||||
}
|
||||
signTextRes->m_conn = conn;
|
||||
signTextRes->m_action = SIGN_TEXT_WAITING;
|
||||
signTextRes->m_thread = SSM_CreateAndRegisterThread(PR_USER_THREAD,
|
||||
SSMSignTextResource_ServiceThread,
|
||||
(void*)signTextRes,
|
||||
PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, 0);
|
||||
if (!signTextRes->m_thread) {
|
||||
goto loser;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
/* XXX Free request */
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSignTextResource_Create(void *arg, SSMControlConnection * conn, SSMResource **res)
|
||||
{
|
||||
SSMSignTextResource *signTextRes;
|
||||
SSMStatus rv;
|
||||
|
||||
signTextRes = PR_NEWZAP(SSMSignTextResource);
|
||||
if (!signTextRes) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SSMSignTextResource_Init(conn, signTextRes, SSM_RESTYPE_SIGNTEXT);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
*res = SSMRESOURCE(signTextRes);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (signTextRes != NULL) {
|
||||
SSM_FreeResource(SSMRESOURCE(signTextRes));
|
||||
}
|
||||
*res = NULL;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSignTextResource_Init(SSMControlConnection *conn, SSMSignTextResource *in,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMResource_Init(conn, SSMRESOURCE(in), type);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set all our data to zero */
|
||||
in->m_stringToSign = NULL;
|
||||
in->m_hostName = NULL;
|
||||
in->m_autoFlag = PR_FALSE;
|
||||
in->m_numCAs = 0;
|
||||
in->m_caNames = NULL;
|
||||
in->m_conn = conn;
|
||||
in->m_thread = NULL;
|
||||
in->m_certs = NULL;
|
||||
in->m_action = SIGN_TEXT_INIT;
|
||||
in->m_nickname = NULL;
|
||||
in->m_resultString = NULL;
|
||||
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus SSMSignTextResource_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMSignTextResource *signTextRes = (SSMSignTextResource*)res;
|
||||
|
||||
if (res == NULL) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Free our data */
|
||||
|
||||
/* Destroy the super class */
|
||||
SSMResource_Destroy(res, PR_FALSE);
|
||||
|
||||
/* Free our memory */
|
||||
if (doFree) {
|
||||
PR_DELETE(signTextRes);
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SSMStatus SSMSignTextResource_Shutdown(SSMResource *arg, SSMStatus status)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMSignTextResource_SendTaskCompletedEvent(SSMSignTextResource *res)
|
||||
{
|
||||
SECItem msg;
|
||||
SSMStatus rv;
|
||||
TaskCompletedEvent event;
|
||||
|
||||
/* Assemble the event. */
|
||||
SSM_DEBUG("Sign Text Resource Task completed event: id %ld, status %d\n",
|
||||
SSMRESOURCE(res)->m_id, SSMRESOURCE(res)->m_status);
|
||||
event.resourceID = SSMRESOURCE(res)->m_id;
|
||||
event.numTasks = 0;
|
||||
event.result = SSMRESOURCE(res)->m_status;
|
||||
if (CMT_EncodeMessage(TaskCompletedEventTemplate, (CMTItem*)&msg, &event) != CMTSuccess) {
|
||||
return;
|
||||
}
|
||||
if (msg.data) {
|
||||
/* Send the event to the control queue. */
|
||||
rv = SSM_SendQMessage(SSMRESOURCE(res)->m_connection->m_controlOutQ,
|
||||
SSM_PRIORITY_NORMAL,
|
||||
SSM_EVENT_MESSAGE | SSM_TASK_COMPLETED_EVENT,
|
||||
(int) msg.len, (char *) msg.data, PR_FALSE);
|
||||
SSM_DEBUG("Sent message, rv = %d.\n", rv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SSMSignTextResource_ServiceThread(void *arg)
|
||||
{
|
||||
SSMSignTextResource *signTextRes = (SSMSignTextResource*)arg;
|
||||
SSMStatus rv;
|
||||
unsigned char hashVal[SHA1_LENGTH];
|
||||
SECItem digest, signedResult, *tmpItem;
|
||||
SEC_PKCS7ContentInfo *ci = NULL;
|
||||
CERTCertificate *cert = NULL;
|
||||
CERTCertListNode *node;
|
||||
int i,numCerts;
|
||||
|
||||
SSM_LockResource(SSMRESOURCE(signTextRes));
|
||||
|
||||
PR_ASSERT(signTextRes);
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(signTextRes), SSM_RESTYPE_SIGNTEXT));
|
||||
|
||||
memset(&signedResult, 0, sizeof(SECItem));
|
||||
|
||||
/* Get the certificates */
|
||||
signTextRes->m_certs = CERT_MatchUserCert(signTextRes->m_conn->m_certdb,
|
||||
certUsageEmailSigner,
|
||||
signTextRes->m_numCAs,
|
||||
signTextRes->m_caNames,
|
||||
signTextRes->m_conn);
|
||||
numCerts = SSM_CertListCount(signTextRes->m_certs);
|
||||
if((signTextRes->m_certs == NULL) || (numCerts == 0)) {
|
||||
signTextRes->m_resultString = strdup("error:noMatchingCert");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send UI event to client */
|
||||
if (signTextRes->m_autoFlag == PR_TRUE) {
|
||||
rv = SSMControlConnection_SendUIEvent(signTextRes->m_conn, "get", "signtext_auto", SSMRESOURCE(signTextRes), NULL,
|
||||
&SSMRESOURCE(signTextRes)->m_clientContext);
|
||||
} else {
|
||||
rv = SSMControlConnection_SendUIEvent(signTextRes->m_conn, "get", "signtext_ask", SSMRESOURCE(signTextRes), NULL,
|
||||
&SSMRESOURCE(signTextRes)->m_clientContext);
|
||||
}
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Here we wait for the user to confirm or deny the signing */
|
||||
SSM_WaitResource(SSMRESOURCE(signTextRes), PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
switch (SSMRESOURCE(signTextRes)->m_buttonType) {
|
||||
case SSM_BUTTON_OK:
|
||||
/* Get the signing cert */
|
||||
node = (CERTCertListNode *)PR_LIST_HEAD(&signTextRes->m_certs->list);
|
||||
if (signTextRes->m_nickname == NULL ) {
|
||||
/* this is the "auto" case */
|
||||
cert = node->cert;
|
||||
} else {
|
||||
/* this is the "ask" case */
|
||||
for ( i = 0; i < numCerts; i++ ) {
|
||||
if ( PL_strcasecmp(signTextRes->m_nickname, node->cert->nickname) == 0 ) {
|
||||
cert = node->cert;
|
||||
break;
|
||||
}
|
||||
node = (struct CERTCertListNodeStr *) node->links.next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash the string to be signed */
|
||||
rv = HASH_HashBuf(HASH_AlgSHA1, hashVal,
|
||||
(unsigned char *) signTextRes->m_stringToSign,
|
||||
strlen(signTextRes->m_stringToSign));
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
digest.len = SHA1_LENGTH;
|
||||
digest.data = hashVal;
|
||||
|
||||
/* Sign the hash */
|
||||
ci = SECMIME_CreateSigned(cert, cert, cert->dbhandle, SEC_OID_SHA1,
|
||||
&digest, NULL, signTextRes->m_conn);
|
||||
if (ci == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Create the PKCS#7 object */
|
||||
tmpItem = SEC_PKCS7EncodeItem(NULL, &signedResult, ci, NULL, NULL,
|
||||
signTextRes->m_conn);
|
||||
if (tmpItem != &signedResult) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Convert the result to base 64 */
|
||||
signTextRes->m_resultString = BTOA_DataToAscii(signedResult.data, signedResult.len);
|
||||
if (signTextRes->m_resultString == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
break;
|
||||
case SSM_BUTTON_CANCEL:
|
||||
signTextRes->m_resultString= PL_strdup("error:userCancel");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SSM_UnlockResource(SSMRESOURCE(signTextRes));
|
||||
loser:
|
||||
/* Free data */
|
||||
if (signTextRes->m_stringToSign) {
|
||||
PR_Free(signTextRes->m_stringToSign);
|
||||
}
|
||||
if (signTextRes->m_hostName) {
|
||||
PR_Free(signTextRes->m_hostName);
|
||||
}
|
||||
if (signTextRes->m_certs) {
|
||||
CERT_DestroyCertList(signTextRes->m_certs);
|
||||
}
|
||||
|
||||
/* Send the task complete event here */
|
||||
SSMSignTextResource_SendTaskCompletedEvent(signTextRes);
|
||||
return;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSignTextResource_Print(SSMResource *res,
|
||||
char *fmt,
|
||||
PRIntn numParam,
|
||||
char ** value,
|
||||
char **resultStr)
|
||||
{
|
||||
char *hostName = NULL, *stringToSign = NULL;
|
||||
SSMSignTextResource *signTextRes = (SSMSignTextResource*)res;
|
||||
|
||||
hostName = signTextRes->m_hostName;
|
||||
stringToSign = signTextRes->m_stringToSign;
|
||||
if (numParam)
|
||||
SSMResource_Print(res, fmt, numParam, value, resultStr);
|
||||
else if (signTextRes->m_autoFlag) {
|
||||
CERTCertListNode *node;
|
||||
CERTCertificate *cert;
|
||||
|
||||
/* Get the cert nickname */
|
||||
node = (CERTCertListNode*)PR_LIST_HEAD(&signTextRes->m_certs->list);
|
||||
cert = node->cert;
|
||||
|
||||
/* Get the nickname */
|
||||
*resultStr = PR_smprintf(fmt, signTextRes->super.m_id, hostName,
|
||||
stringToSign, cert->nickname);
|
||||
} else {
|
||||
*resultStr = PR_smprintf(fmt, signTextRes->super.m_id, hostName,
|
||||
stringToSign);
|
||||
|
||||
}
|
||||
return (*resultStr != NULL) ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSignTextResource_GetAttr(SSMResource *res, SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMSignTextResource *signTextRes = (SSMSignTextResource*)res;
|
||||
|
||||
if (!signTextRes || !signTextRes->m_resultString) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
switch (attrID) {
|
||||
case SSM_FID_SIGNTEXT_RESULT:
|
||||
if (!signTextRes->m_resultString) {
|
||||
goto loser;
|
||||
}
|
||||
value->type = SSM_STRING_ATTRIBUTE;
|
||||
value->u.string.len = PL_strlen(signTextRes->m_resultString);
|
||||
value->u.string.data = (unsigned char *) PL_strdup(signTextRes->m_resultString);
|
||||
break;
|
||||
default:
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSignTextResource_FormSubmitHandler(SSMResource* res,
|
||||
HTTPRequest* req)
|
||||
{
|
||||
SSMStatus rv;
|
||||
char* tmpStr;
|
||||
SSMSignTextResource *signTextRes = (SSMSignTextResource*)res;
|
||||
|
||||
SSM_LockResource(res);
|
||||
|
||||
rv = SSM_HTTPParamValue(req, "baseRef", &tmpStr);
|
||||
if (rv != SSM_SUCCESS ||
|
||||
PL_strcmp(tmpStr, "windowclose_doclose_js") != 0) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Detect which button was pressed */
|
||||
if (res->m_buttonType == SSM_BUTTON_OK) {
|
||||
/* Get the certificate nickname */
|
||||
SSM_HTTPParamValue(req, "chose", &signTextRes->m_nickname);
|
||||
}
|
||||
|
||||
loser:
|
||||
/* Close the window */
|
||||
SSM_HTTPCloseAndSleep(req);
|
||||
|
||||
/* Unblock the sign text thread waiting on this */
|
||||
SSM_NotifyResource(res);
|
||||
SSM_UnlockResource(res);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSM_SignTextCertListKeywordHandler(SSMTextGenContext* cx)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
SSMResource* target = NULL;
|
||||
SSMSignTextResource* res;
|
||||
char* prefix = NULL;
|
||||
char* wrapper = NULL;
|
||||
char* suffix = NULL;
|
||||
char* tmpStr = NULL;
|
||||
char* fmt = NULL;
|
||||
const PRIntn CERT_LIST_PREFIX = (PRIntn)0;
|
||||
const PRIntn CERT_LIST_WRAPPER = (PRIntn)1;
|
||||
const PRIntn CERT_LIST_SUFFIX = (PRIntn)2;
|
||||
const PRIntn CERT_LIST_PARAM_COUNT = (PRIntn)3;
|
||||
|
||||
/*
|
||||
* make sure cx, cx->m_request, cx->m_params, cx->m_result are not
|
||||
* NULL
|
||||
*/
|
||||
PR_ASSERT(cx != NULL && cx->m_request != NULL && cx->m_params != NULL &&
|
||||
cx->m_result != NULL);
|
||||
if (cx == NULL || cx->m_request == NULL || cx->m_params == NULL ||
|
||||
cx->m_result == NULL) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (SSM_Count(cx->m_params) != CERT_LIST_PARAM_COUNT) {
|
||||
SSM_HTTPReportSpecificError(cx->m_request, "_signtext_certList: ",
|
||||
"Incorrect number of parameters "
|
||||
" (%d supplied, %d needed).\n",
|
||||
SSM_Count(cx->m_params),
|
||||
CERT_LIST_PARAM_COUNT);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the connection object */
|
||||
target = SSMTextGen_GetTargetObject(cx);
|
||||
PR_ASSERT(target != NULL);
|
||||
res = (SSMSignTextResource*)target;
|
||||
|
||||
/* form the MessageFormat object */
|
||||
/* find arguments (prefix, wrapper, and suffix) */
|
||||
prefix = (char *) SSM_At(cx->m_params, CERT_LIST_PREFIX);
|
||||
wrapper = (char *) SSM_At(cx->m_params, CERT_LIST_WRAPPER);
|
||||
suffix = (char *) SSM_At(cx->m_params, CERT_LIST_SUFFIX);
|
||||
PR_ASSERT(prefix != NULL && wrapper != NULL && suffix != NULL);
|
||||
|
||||
/* grab the prefix and expand it */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, prefix, &tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* append the prefix */
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
|
||||
SSMTextGen_UTF8StringClear(&tmpStr);
|
||||
SSM_DebugUTF8String("signtext cert list prefix", cx->m_result);
|
||||
|
||||
/* grab the wrapper */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, wrapper, &tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DebugUTF8String("sign text cert list wrapper", fmt);
|
||||
|
||||
/* form the wrapped cert list UnicodeString */
|
||||
rv = ssm_signtext_get_unicode_cert_list(res, tmpStr, &tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* append the wrapped cert list */
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
SSMTextGen_UTF8StringClear(&tmpStr);
|
||||
|
||||
/* grab the suffix and expand it */
|
||||
rv = SSM_GetAndExpandTextKeyedByString(cx, suffix, &tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
SSM_DebugUTF8String("client cert list suffix", tmpStr);
|
||||
|
||||
/* append the suffix */
|
||||
rv = SSM_ConcatenateUTF8String(&cx->m_result, tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == SSM_SUCCESS) {
|
||||
rv = SSM_FAILURE;
|
||||
}
|
||||
done:
|
||||
PR_FREEIF(fmt);
|
||||
PR_FREEIF(tmpStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: SSMStatus ssm_client_auth_get_unicode_cert_list()
|
||||
* Purpose: forms the cert list UnicodeString
|
||||
*
|
||||
* Arguments and return values:
|
||||
* - conn: SSL connection object
|
||||
* - fmt: cert wrapper UnicodeString format
|
||||
* - result: resulting UnicodeString
|
||||
*
|
||||
* Note: if we include the expired certs, we need to append to the end as
|
||||
* well
|
||||
*/
|
||||
SSMStatus ssm_signtext_get_unicode_cert_list(SSMSignTextResource* res,
|
||||
char* fmt,
|
||||
char** result)
|
||||
{
|
||||
SSMStatus rv = SSM_SUCCESS;
|
||||
char * tmpStr = NULL;
|
||||
char * finalStr = NULL;
|
||||
int i;
|
||||
CERTCertListNode *head = NULL;
|
||||
int numCerts;
|
||||
|
||||
PR_ASSERT(res != NULL && fmt != NULL && result != NULL);
|
||||
/* in case we fail */
|
||||
*result = NULL;
|
||||
|
||||
/* concatenate the string using the nicknames */
|
||||
head = (CERTCertListNode *)PR_LIST_HEAD(&res->m_certs->list);
|
||||
numCerts = SSM_CertListCount(res->m_certs);
|
||||
for (i = 0; i < numCerts; i++) {
|
||||
tmpStr = PR_smprintf(fmt, i, head->cert->nickname);
|
||||
rv = SSM_ConcatenateUTF8String(&finalStr, tmpStr);
|
||||
if (rv != SSM_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
PR_Free(tmpStr);
|
||||
tmpStr = NULL;
|
||||
head = (CERTCertListNode *)head->links.next;
|
||||
}
|
||||
|
||||
SSM_DebugUTF8String("client auth: final cert list", finalStr);
|
||||
*result = finalStr;
|
||||
return SSM_SUCCESS;
|
||||
loser:
|
||||
SSM_DEBUG("client auth: wrapping cert list failed.\n");
|
||||
if (rv == SSM_SUCCESS) {
|
||||
rv = SSM_FAILURE;
|
||||
}
|
||||
PR_FREEIF(finalStr);
|
||||
PR_FREEIF(tmpStr);
|
||||
return rv;
|
||||
}
|
81
security/psm/server/signtextres.h
Normal file
81
security/psm/server/signtextres.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SIGNTEXTRES_H__
|
||||
#define __SIGNTEXTRES_H__
|
||||
|
||||
#include "resource.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "textgen.h"
|
||||
|
||||
typedef enum {
|
||||
SIGN_TEXT_INIT,
|
||||
SIGN_TEXT_WAITING,
|
||||
SIGN_TEXT_OK,
|
||||
SIGN_TEXT_CANCEL
|
||||
} SignTextAction;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SSMResource super;
|
||||
char *m_stringToSign;
|
||||
char *m_hostName;
|
||||
PRBool m_autoFlag;
|
||||
PRInt32 m_numCAs;
|
||||
char **m_caNames;
|
||||
SSMControlConnection *m_conn;
|
||||
PRThread *m_thread;
|
||||
CERTCertList *m_certs;
|
||||
SignTextAction m_action;
|
||||
char *m_nickname;
|
||||
char *m_resultString;
|
||||
} SSMSignTextResource;
|
||||
|
||||
SSMStatus SSM_CreateSignTextRequest(SECItem* msg, SSMControlConnection* conn);
|
||||
SSMStatus SSM_CreateNewSignTextRequest(SECItem *msg, SSMControlConnection *conn);
|
||||
SSMStatus SSMSignTextResource_Create(void *arg, SSMControlConnection *conn, SSMResource **res);
|
||||
SSMStatus SSMSignTextResource_Init(SSMControlConnection *conn, SSMSignTextResource *res, SSMResourceType type);
|
||||
SSMStatus SSMSignTextResource_Destroy(SSMResource *res, PRBool doFree);
|
||||
SSMStatus SSMSignTextResource_Shutdown(SSMResource *res, SSMStatus status);
|
||||
SSMStatus SSMSignTextResource_GetAttr(SSMResource *res, SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMSignTextResource_Print(SSMResource *res, char *fmt, PRIntn numParam,
|
||||
char ** value, char **resultStr);
|
||||
SSMStatus SSMSignTextResource_FormSubmitHandler(SSMResource* res, HTTPRequest* req);
|
||||
void SSMSignTextResource_ServiceThread(void *arg);
|
||||
SSMStatus SSM_SignTextCertListKeywordHandler(SSMTextGenContext* cx);
|
||||
SSMStatus ssm_signtext_get_unicode_cert_list(SSMSignTextResource* res,
|
||||
char* fmt,
|
||||
char** result);
|
||||
SSMStatus SSM_CreateSignTextRequest(SECItem *msg, SSMControlConnection *conn);
|
||||
#endif /* __SIGNTEXTRES_H__ */
|
280
security/psm/server/slist.c
Normal file
280
security/psm/server/slist.c
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "slist.h"
|
||||
|
||||
|
||||
SSMSortedList *
|
||||
SSMSortedList_New(SSMSortedListFn * functions)
|
||||
{
|
||||
SSMSortedList * list = NULL;
|
||||
|
||||
if (!functions)
|
||||
goto loser;
|
||||
|
||||
list = PR_NEWZAP(SSMSortedList);
|
||||
if (list == NULL)
|
||||
goto loser;
|
||||
|
||||
list->lock = PR_NewMonitor();
|
||||
if (list->lock == NULL)
|
||||
goto loser;
|
||||
|
||||
list->func.keyCompare = functions->keyCompare;
|
||||
list->func.freeListItemData = functions->freeListItemData;
|
||||
list->func.freeListItemKey = functions->freeListItemKey;
|
||||
|
||||
PR_INIT_CLIST(&list->list);
|
||||
list->nItems = 0;
|
||||
return list;
|
||||
loser:
|
||||
if (list) {
|
||||
if (list->lock)
|
||||
PR_DestroyMonitor(list->lock);
|
||||
PR_Free(list);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSortedList_Destroy(SSMSortedList *victim)
|
||||
{
|
||||
PRCList * link, *next;
|
||||
|
||||
if (!victim)
|
||||
goto done;
|
||||
|
||||
PR_EnterMonitor(victim->lock);
|
||||
/* free elements */
|
||||
for(link = PR_LIST_HEAD(&victim->list); link != &victim->list;){
|
||||
next = PR_NEXT_LINK(link);
|
||||
slist_remove_item(victim, (SSMSortedListItem *)link, PR_TRUE);
|
||||
link = next;
|
||||
}
|
||||
|
||||
PR_ExitMonitor(victim->lock);
|
||||
PR_ASSERT(victim->nItems == 0);
|
||||
PR_DestroyMonitor(victim->lock);
|
||||
PR_Free(victim);
|
||||
done:
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
||||
SSMSortedListItem * slist_remove_item(SSMSortedList * list,
|
||||
SSMSortedListItem * item,
|
||||
PRBool doFree)
|
||||
{
|
||||
PR_REMOVE_LINK(&item->link);
|
||||
list->nItems--;
|
||||
if (doFree) {
|
||||
list->func.freeListItemData(item->data);
|
||||
list->func.freeListItemKey(item->key);
|
||||
PR_Free(item);
|
||||
return NULL;
|
||||
}
|
||||
else return item;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSortedList_Insert(SSMSortedList * slist, void * key, void * data)
|
||||
{
|
||||
SSMSortedListItem * item, * nextItem;
|
||||
|
||||
if (!slist)
|
||||
goto loser;
|
||||
|
||||
item = slist_allocate_item(key, data);
|
||||
if (!item)
|
||||
goto loser;
|
||||
|
||||
PR_EnterMonitor(slist->lock);
|
||||
nextItem = slist_find_next(slist, key);
|
||||
PR_INSERT_BEFORE(&item->link, &nextItem->link);
|
||||
slist->nItems++;
|
||||
PR_ExitMonitor(slist->lock);
|
||||
|
||||
return SSM_SUCCESS;
|
||||
loser:
|
||||
return SSM_FAILURE;
|
||||
}
|
||||
|
||||
SSMSortedListItem * slist_allocate_item(void * key, void * data)
|
||||
{
|
||||
SSMSortedListItem * item;
|
||||
|
||||
item = PR_NEWZAP(SSMSortedListItem);
|
||||
if (item)
|
||||
{
|
||||
item->data = data;
|
||||
item->key = key;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSortedList_Find(SSMSortedList * slist, void * key, void ** data)
|
||||
{
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SSMSortedListItem * item;
|
||||
|
||||
if (!slist || !data)
|
||||
goto loser;
|
||||
|
||||
*data = NULL;
|
||||
PR_EnterMonitor(slist->lock);
|
||||
item = slist_find_item(slist, key);
|
||||
if (item) {
|
||||
*data = item->data;
|
||||
rv = SSM_SUCCESS;
|
||||
}
|
||||
PR_ExitMonitor(slist->lock);
|
||||
loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSortedList_Remove(SSMSortedList * slist, void * key, void ** data)
|
||||
{
|
||||
SSMSortedListItem * item;
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
|
||||
if (!slist)
|
||||
goto loser;
|
||||
PR_EnterMonitor(slist->lock);
|
||||
item = slist_find_item(slist, key);
|
||||
if (item) {
|
||||
rv = SSM_SUCCESS;
|
||||
if (data)
|
||||
*data = item->data;
|
||||
slist_remove_item(slist, item, PR_FALSE);
|
||||
slist->func.freeListItemKey(item->key);
|
||||
PR_Free(item);
|
||||
}
|
||||
PR_ExitMonitor(slist->lock);
|
||||
loser:
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSortedList_FindNext(SSMSortedList * slist, void * key, void ** data)
|
||||
{
|
||||
SSMSortedListItem * item;
|
||||
|
||||
if (!slist || !data)
|
||||
return SSM_FAILURE;
|
||||
|
||||
PR_EnterMonitor(slist->lock);
|
||||
item = slist_find_next(slist, key);
|
||||
*data = item->data;
|
||||
PR_ExitMonitor(slist->lock);
|
||||
return SSM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SSMSortedListItem *
|
||||
slist_find_next(SSMSortedList * slist, void * key)
|
||||
{
|
||||
PRCList * link;
|
||||
SSMSortedListItem * item;
|
||||
|
||||
for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
|
||||
link = PR_NEXT_LINK(link))
|
||||
if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) > 0) {
|
||||
/* insert here */
|
||||
item = (SSMSortedListItem *)link;
|
||||
goto done;
|
||||
}
|
||||
item = (SSMSortedListItem *)&slist->list;
|
||||
done:
|
||||
return item;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SSMSortedList_Lookup(SSMSortedList * slist, void * key)
|
||||
{
|
||||
SSMSortedListItem * item;
|
||||
if (!slist)
|
||||
goto loser;
|
||||
PR_EnterMonitor(slist->lock);
|
||||
item = slist_find_item(slist, key);
|
||||
PR_ExitMonitor(slist->lock);
|
||||
if (item)
|
||||
return PR_TRUE;
|
||||
loser:
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SSMSortedListItem *
|
||||
slist_find_item(SSMSortedList * slist, void * key)
|
||||
{
|
||||
PRCList * link;
|
||||
|
||||
for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
|
||||
link = PR_NEXT_LINK(link))
|
||||
if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) == 0) /* found it */
|
||||
return ((SSMSortedListItem *)link);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRIntn
|
||||
SSMSortedList_Enumerate(SSMSortedList * slist, SSMSortedListEnumerator_fn func,
|
||||
void * arg)
|
||||
{
|
||||
PRCList * link;
|
||||
PRIntn numentries = 0;
|
||||
SSMStatus rv;
|
||||
|
||||
if (!slist || !func)
|
||||
goto loser;
|
||||
|
||||
PR_EnterMonitor(slist->lock);
|
||||
for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
|
||||
link = PR_NEXT_LINK(link)) {
|
||||
rv = func(numentries, arg, ((SSMSortedListItem *)link)->key,
|
||||
((SSMSortedListItem *)link)->data);
|
||||
if (rv == SSM_SUCCESS)
|
||||
numentries ++;
|
||||
}
|
||||
PR_ExitMonitor(slist->lock);
|
||||
|
||||
loser:
|
||||
return numentries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
115
security/psm/server/slist.h
Normal file
115
security/psm/server/slist.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SORTEDLIST_H__
|
||||
#define __SORTEDLIST_H__
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "prmon.h"
|
||||
#include "prclist.h"
|
||||
#include "ssmerrs.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "nspr.h"
|
||||
|
||||
struct _SSMSortedListItem;
|
||||
typedef PRIntn (* SSMCompare_fn)(const void * p1, const void * p2);
|
||||
typedef void (* SSMListFree_fn)(void * data);
|
||||
typedef SSMStatus (* SSMSortedListEnumerator_fn)(PRIntn index, void * arg,
|
||||
void * key, void * data);
|
||||
|
||||
|
||||
/* This is an ordered collection of items without repetition. */
|
||||
/* This is to be used as a link in a PRCList.
|
||||
* You can cast any of the PRCList *'s in the list to one of these.
|
||||
* See prclist.h for details.
|
||||
*/
|
||||
typedef struct _SSMSortedListItem
|
||||
{
|
||||
PRCList link;
|
||||
void *key;
|
||||
void *data;
|
||||
} SSMSortedListItem;
|
||||
|
||||
typedef struct _SSMSortedListFn
|
||||
{
|
||||
SSMCompare_fn keyCompare;
|
||||
SSMListFree_fn freeListItemData;
|
||||
SSMListFree_fn freeListItemKey;
|
||||
} SSMSortedListFn;
|
||||
|
||||
/* An ordered collection, implemented in terms of PRCList. */
|
||||
struct _SSMSortedList
|
||||
{
|
||||
PRCList list;
|
||||
PRMonitor *lock;
|
||||
PRIntn nItems;
|
||||
SSMSortedListFn func;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _SSMSortedList SSMSortedList;
|
||||
|
||||
|
||||
SSMSortedList*
|
||||
SSMSortedList_New(SSMSortedListFn * functions);
|
||||
SSMStatus
|
||||
SSMSortedList_Destroy(SSMSortedList *victim);
|
||||
SSMStatus
|
||||
SSMSortedList_Insert(SSMSortedList * slist, void * key, void * data);
|
||||
SSMStatus
|
||||
SSMSortedList_Find(SSMSortedList * slist, void * key, void ** data);
|
||||
PRBool
|
||||
SSMSortedList_Lookup(SSMSortedList * slist, void * key);
|
||||
SSMStatus
|
||||
SSMSortedList_FindNext(SSMSortedList * slist, void * key, void ** data);
|
||||
SSMStatus
|
||||
SSMSortedList_Remove(SSMSortedList * slist, void * key, void ** data);
|
||||
PRIntn
|
||||
SSMSortedList_Enumerate(SSMSortedList * slist, SSMSortedListEnumerator_fn func,
|
||||
void * arg);
|
||||
|
||||
/*
|
||||
SSMStatus
|
||||
SSMSortedList_AtSorted(SSMSortedList *list, PRIntn which,
|
||||
void ** key, void **data);
|
||||
*/
|
||||
|
||||
SSMSortedListItem *
|
||||
slist_remove_item(SSMSortedList * list, SSMSortedListItem * item, PRBool doFree);
|
||||
SSMSortedListItem *
|
||||
slist_allocate_item(void * key, void * data);
|
||||
SSMSortedListItem *
|
||||
slist_find_next(SSMSortedList * slist, void * key);
|
||||
SSMSortedListItem *
|
||||
slist_find_item(SSMSortedList * slist, void * key);
|
||||
|
||||
#endif /* __SORTEDLIST_H__ */
|
2445
security/psm/server/sslconn.c
Normal file
2445
security/psm/server/sslconn.c
Normal file
File diff suppressed because it is too large
Load Diff
153
security/psm/server/sslconn.h
Normal file
153
security/psm/server/sslconn.h
Normal file
@ -0,0 +1,153 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_SSLCONN_H__
|
||||
#define __SSM_SSLCONN_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "prerror.h"
|
||||
#include "pk11func.h"
|
||||
#include "secitem.h"
|
||||
#include "ssl.h"
|
||||
#include "prnetdb.h"
|
||||
#include "certt.h"
|
||||
#include "nss.h"
|
||||
#include "nspr.h"
|
||||
#include "secrng.h"
|
||||
#include "secder.h"
|
||||
#include "key.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
#include "ctrlconn.h"
|
||||
#include "dataconn.h"
|
||||
#include "sslskst.h"
|
||||
|
||||
/* Initialization parameters for an SSMSSLDataConnection. */
|
||||
typedef struct SSMInfoSSL {
|
||||
SSMControlConnection* parent;
|
||||
char* hostIP;
|
||||
char* hostName;
|
||||
PRUint32 flags;
|
||||
PRUint32 port;
|
||||
PRBool forceHandshake;
|
||||
PRBool isTLS;
|
||||
CMTItem clientContext;
|
||||
} SSMInfoSSL;
|
||||
|
||||
/* enum for determining how long we will accept this server cert */
|
||||
typedef enum {BSCA_PERMANENT = 0, BSCA_SESSION = 1, BSCA_NO = 2} SSMBadServerCertAccept;
|
||||
|
||||
/* data related with UI */
|
||||
typedef struct _SSMSSLUIInfo {
|
||||
PRBool UICompleted;
|
||||
int numFilteredCerts;
|
||||
char** certNicknames;
|
||||
int chosen; /* index of the chosen cert */
|
||||
|
||||
/* fields for bad server cert UI */
|
||||
SSMBadServerCertAccept trustBadServerCert;
|
||||
/* whether the user decided to use the cert */
|
||||
} SSMSSLUIInfo;
|
||||
|
||||
/*
|
||||
Data connections.
|
||||
*/
|
||||
|
||||
typedef struct SSMSSLDataConnection {
|
||||
SSMDataConnection super;
|
||||
|
||||
PRBool clientSSL;
|
||||
char* hostIP;
|
||||
char* hostName;
|
||||
PRUint32 flags;
|
||||
PRUint32 port;
|
||||
PRBool forceHandshake;
|
||||
PRBool isTLS; /* TRUE if the connection starts out as a cleartext and
|
||||
* is SSL-ified later
|
||||
*/
|
||||
PRBool isSecure; /* SMTP | Proxy: whether the connection is secure
|
||||
* SSL: always true
|
||||
*/
|
||||
PRFileDesc* socketSSL;
|
||||
PRFileDesc* stepUpFD; /* FD used by control connection to wake up
|
||||
SSL thread when it's time to enable TLS/SSL
|
||||
on a previously cleartext connection (eg SMTP) */
|
||||
CMTItem* stepUpContext; /* Client context used for step-up */
|
||||
|
||||
#if 0
|
||||
PRMonitor* sslLock;
|
||||
#endif
|
||||
|
||||
SSMSSLSocketStatus* m_sockStat;
|
||||
PRInt32 m_error;
|
||||
|
||||
SSMSSLUIInfo m_UIInfo; /* field related with UI action */
|
||||
PRInt32 m_sslServerError;
|
||||
PRBool m_statusFetched;
|
||||
} SSMSSLDataConnection;
|
||||
|
||||
SSMStatus SSMSSLDataConnection_Create(void* arg,
|
||||
SSMControlConnection* ctrlconn,
|
||||
SSMResource** res);
|
||||
SSMStatus SSMSSLDataConnection_Shutdown(SSMResource* arg, SSMStatus status);
|
||||
SSMStatus SSMSSLDataConnection_Init(SSMSSLDataConnection* conn,
|
||||
SSMInfoSSL* info, SSMResourceType type);
|
||||
SSMStatus SSMSSLDataConnection_Destroy(SSMResource* res, PRBool doFree);
|
||||
void SSMSSLDataConnection_Invariant(SSMSSLDataConnection* conn);
|
||||
|
||||
SSMStatus SSMSSLDataConnection_GetAttrIDs(SSMResource* res,
|
||||
SSMAttributeID** ids, PRIntn* count);
|
||||
SSMStatus SSMSSLDataConnection_GetAttr(SSMResource* res, SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMSSLDataConnection_SetAttr(SSMResource * res,
|
||||
SSMResourceAttrType attrID,
|
||||
SSMAttributeValue *value);
|
||||
|
||||
SSMStatus SSMSSLDataConnection_PickleSecurityStatus(SSMSSLDataConnection* conn,
|
||||
PRIntn* len, void** blob,
|
||||
PRIntn* securityLevel);
|
||||
SSMStatus SSMSSLDataConnection_FormSubmitHandler(SSMResource* res,
|
||||
HTTPRequest* req);
|
||||
SECStatus SSM_DoubleCheckServerCert(CERTCertificate* cert,
|
||||
SSMSSLDataConnection* conn);
|
||||
SECStatus SSM_LDAPSSLGetClientAuthData(void* arg, PRFileDesc* socket,
|
||||
CERTDistNames* caNames,
|
||||
CERTCertificate** pRetCert,
|
||||
SECKEYPrivateKey** pRetKey);
|
||||
SECStatus SSM_LDAPSetupSSL(PRFileDesc* socket, PRFileDesc** sslSocket,
|
||||
CERTCertDBHandle* certdb, const char* hostname,
|
||||
SSMResource* caller);
|
||||
|
||||
#endif /* __SSM_SSLCONN_H__ */
|
1556
security/psm/server/ssldlgs.c
Normal file
1556
security/psm/server/ssldlgs.c
Normal file
File diff suppressed because it is too large
Load Diff
202
security/psm/server/ssldlgs.h
Normal file
202
security/psm/server/ssldlgs.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_SSLDLGS_H__
|
||||
#define __SSM_SSLDLGS_H__
|
||||
|
||||
#include "textgen.h"
|
||||
#include "minihttp.h"
|
||||
#include "sslconn.h"
|
||||
|
||||
#include "certt.h"
|
||||
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_ServerCertKeywordHandler()
|
||||
* Purpose: keyword handler for "_server_cert_info"
|
||||
* performs substitution for cert info data
|
||||
* syntax: {_server_cert_info cert_format,wrapper}
|
||||
* cert_format: either simple_cert_format (0) or
|
||||
* pretty_cert_format (1)
|
||||
* Arguments and return values:
|
||||
* - cx: SSMTextGenContext to be manipulated
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
*/
|
||||
SSMStatus SSM_ServerCertKeywordHandler(SSMTextGenContext* cx);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_FormatCert()
|
||||
* Purpose: creates a UnicodeString that is used in expanding the keyword
|
||||
* "_server_cert_info" from the given cert
|
||||
* this function provides info on hostname, issuer name, and validity
|
||||
* period. Any UI dialog that uses a subset of this info can use
|
||||
* this function.
|
||||
* Arguments and return values
|
||||
* - cert: server cert to be manipulated
|
||||
* - fmt: message format (shouldn't be NULL)
|
||||
* - result: resulting expanded string (shouldn't be NULL)
|
||||
*
|
||||
* Note: note that this is very similar to a _Print method. In fact,
|
||||
* this could be turned into SSMResourceCert_Print() method w/o too many
|
||||
* changes.
|
||||
*/
|
||||
SSMStatus SSM_FormatCert(CERTCertificate* cert, char* fmt,
|
||||
char** result);
|
||||
/*
|
||||
* Function: SSMStatus SSM_HTTPBadClientAuthButtonHandler()
|
||||
* Purpose: command handler for "BCAButton" (button handling
|
||||
* for bad client auth dialogs)
|
||||
* Arguments and return values:
|
||||
* - req: request object to be manipulated
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note: we use this command handler instead of the default handler
|
||||
* to block the SSL threads while this dialog is up.
|
||||
*/
|
||||
SSMStatus SSM_HTTPBadClientAuthButtonHandler(HTTPRequest* req);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_SSLMakeBadClientAuthDialog()
|
||||
* Purpose: make "no cert" dialog by sending the "no cert" UI event
|
||||
* Arguments and return values:
|
||||
* - conn: SSL connection object
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note: URL: ".../get?baseRef=bad_client_auth&target=(conn ID)"
|
||||
* blocks until the dialog is complete
|
||||
*/
|
||||
SSMStatus SSM_SSLMakeBadClientAuthDialog(SSMSSLDataConnection* conn);
|
||||
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_SSLMakeClientAuthDialog()
|
||||
* Purpose: generates the client auth cert selection dialog and receives
|
||||
* a chosen cert nickname from the user
|
||||
* Arguments and return values:
|
||||
* - conn: SSL connection object to be manipulated; m_UIInfo.chosenNickname
|
||||
* will be populated as a result of the dialog
|
||||
* - returns: SSM_SUCCESS if successful; otherwise error code
|
||||
*
|
||||
* Note: (design issue) how do we handle "cancel" event? Do we display the
|
||||
* "no cert" dialog and exit, or we just exit? Probably we just exit.
|
||||
*/
|
||||
SSMStatus SSM_SSLMakeClientAuthDialog(SSMSSLDataConnection* conn);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_ClientAuthCertListKeywordHandler()
|
||||
* Purpose: formats the client cert list according to the given format
|
||||
* for the cert selection dialog
|
||||
* syntax: {_client_auth_certList prefix,wrapper,suffix}
|
||||
* where wrapper is for the individual cert
|
||||
* Arguments and return values:
|
||||
* - cx: text context to be manipulated
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note:
|
||||
*/
|
||||
SSMStatus SSM_ClientAuthCertListKeywordHandler(SSMTextGenContext* cx);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_HTTPClientAuthButtonHandler()
|
||||
* Purpose: handles the user input for buttons in cert selection dialog
|
||||
* URL: "CAButton?baseRef=windowclose_doclose_js&target={0}&chosen=0&do_ok={text_ok}" or "CAButton?...&target={0}&do_cancel={text_cancel}", etc.
|
||||
*/
|
||||
SSMStatus SSM_HTTPClientAuthButtonHandler(HTTPRequest* req);
|
||||
|
||||
SECStatus SSM_SSLMakeCertExpiredDialog(CERTCertificate* cert,
|
||||
SSMSSLDataConnection* conn);
|
||||
SECStatus SSM_SSLMakeCertBadDomainDialog(CERTCertificate* cert,
|
||||
SSMSSLDataConnection* conn);
|
||||
SSMStatus SSM_ClientAuthCertSelectionButtonHandler(HTTPRequest* req);
|
||||
SSMStatus SSM_ServerAuthFailureButtonHandler(HTTPRequest* req);
|
||||
SSMStatus SSM_ServerAuthUnknownIssuerButtonHandler(HTTPRequest* req);
|
||||
SSMStatus SSM_CurrentTimeKeywordHandler(SSMTextGenContext* cx);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_ServerAuthDomainKeywordHandler()
|
||||
* Purpose: formats the domain name mismatch warning string for server auth
|
||||
* syntax: {_server_cert_domain_info bad_domain_wrapper}
|
||||
* Arguments and return values
|
||||
* - cx: text context to be manipulated
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note: I wrote a separate keyword handler although there is a generic
|
||||
* server cert info keyword handler; this is the only place where
|
||||
* one needs the URL hostname and it turns out to be simpler and more
|
||||
* efficient to write a separate handler for this purpose
|
||||
*/
|
||||
SSMStatus SSM_ServerAuthDomainNameKeywordHandler(SSMTextGenContext* cx);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_VerifyServerCertKeywordHandler()
|
||||
* Purpose: handles the nickname substitution for keyword
|
||||
* "_verify_server_cert"
|
||||
* Arguments and return values:
|
||||
* - cx: text context to be manipulated
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note: since this only comes from the server auth failure dialog, we know
|
||||
* beforehand that the cert is bad (thus no need really to verify the
|
||||
* cert). This might change if we want to print out the nature of the
|
||||
* error. Also, if we want to consolidate this view cert window
|
||||
* handling (it's not clear how we can do that because we have different
|
||||
* certs and different targets for different cases), this function
|
||||
* may have to be modified.
|
||||
*/
|
||||
SSMStatus SSM_VerifyServerCertKeywordHandler(SSMTextGenContext* cx);
|
||||
|
||||
/*
|
||||
* Function: SSMStatus SSM_PrettyFormatCert()
|
||||
* Purpose: formats the cert info for "View Security Certificate" dialogs
|
||||
* this function provides info on issuer name, serial number,
|
||||
* validity period, finger print, and comment. Any dialog that
|
||||
* needs a subset of the parameters can use this function to format
|
||||
* the cert
|
||||
* Arguments and return values:
|
||||
* - cert: cert to be presented
|
||||
* - fmt: MessageFormat object
|
||||
* - result: UnicodeString to be returned as a result of the operation
|
||||
* - returns: SSM_SUCCESS if successful; error code otherwise
|
||||
*
|
||||
* Note: this provides no information on whether the cert is valid or not
|
||||
* lot of the code is borrowed from CERT_HTMLInfo() from NSS
|
||||
* we also access lots of internal cert fields but can't help it...
|
||||
*/
|
||||
SSMStatus SSM_PrettyFormatCert(CERTCertificate* cert, char* fmt,
|
||||
char** result);
|
||||
|
||||
SECStatus SSM_SSLMakeUnknownIssuerDialog(CERTCertificate* cert,
|
||||
SSMSSLDataConnection* conn);
|
||||
SSMStatus SSM_HTTPUnknownIssuerStep1ButtonHandler(HTTPRequest* req);
|
||||
|
||||
#endif /* __SSM_SSLDLGS_H__ */
|
107
security/psm/server/sslerror.h
Normal file
107
security/psm/server/sslerror.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "nspr.h"
|
||||
|
||||
struct tuple_str {
|
||||
PRErrorCode errNum;
|
||||
const char * errString;
|
||||
};
|
||||
|
||||
typedef struct tuple_str tuple_str;
|
||||
|
||||
#define ER2(a,b) {a, b},
|
||||
#define ER3(a,b,c) {a, c},
|
||||
|
||||
#include "secerr.h"
|
||||
#include "sslerr.h"
|
||||
|
||||
const tuple_str errStrings[] = {
|
||||
|
||||
/* keep this list in asceding order of error numbers */
|
||||
#include "SSLerrs.h"
|
||||
#include "SECerrs.h"
|
||||
#include "NSPRerrs.h"
|
||||
|
||||
};
|
||||
|
||||
const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str);
|
||||
|
||||
/* Returns a UTF-8 encoded constant error string for "errNum".
|
||||
* Returns NULL of errNum is unknown.
|
||||
*/
|
||||
const char *
|
||||
SSL_Strerror(PRErrorCode errNum) {
|
||||
PRInt32 low = 0;
|
||||
PRInt32 high = numStrings - 1;
|
||||
PRInt32 i;
|
||||
PRErrorCode num;
|
||||
static int initDone;
|
||||
|
||||
/* make sure table is in ascending order.
|
||||
* binary search depends on it.
|
||||
*/
|
||||
if (!initDone) {
|
||||
PRErrorCode lastNum = 0x80000000;
|
||||
for (i = low; i <= high; ++i) {
|
||||
num = errStrings[i].errNum;
|
||||
if (num <= lastNum) {
|
||||
fprintf(stderr,
|
||||
"sequence error in error strings at item %d\n"
|
||||
"error %d (%s)\n"
|
||||
"should come after \n"
|
||||
"error %d (%s)\n",
|
||||
i, lastNum, errStrings[i-1].errString,
|
||||
num, errStrings[i].errString);
|
||||
}
|
||||
lastNum = num;
|
||||
}
|
||||
initDone = 1;
|
||||
}
|
||||
|
||||
/* Do binary search of table. */
|
||||
while (low + 1 < high) {
|
||||
i = (low + high) / 2;
|
||||
num = errStrings[i].errNum;
|
||||
if (errNum == num)
|
||||
return errStrings[i].errString;
|
||||
if (errNum < num)
|
||||
high = i;
|
||||
else
|
||||
low = i;
|
||||
}
|
||||
if (errNum == errStrings[low].errNum)
|
||||
return errStrings[low].errString;
|
||||
if (errNum == errStrings[high].errNum)
|
||||
return errStrings[high].errString;
|
||||
return NULL;
|
||||
}
|
503
security/psm/server/sslskst.c
Normal file
503
security/psm/server/sslskst.c
Normal file
@ -0,0 +1,503 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "sslconn.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "serv.h"
|
||||
#include "servimpl.h"
|
||||
|
||||
/* Shorthand macros for inherited classes */
|
||||
#define SSMRESOURCE(ss) (&(ss)->super)
|
||||
|
||||
/* implemented in resource.c: this should belong to resource.h! */
|
||||
SSMStatus SSM_UnpickleResource(SSMResource** res, SSMResourceType type,
|
||||
SSMControlConnection* connection,
|
||||
PRIntn len, void* value);
|
||||
|
||||
SSMStatus
|
||||
SSMSSLSocketStatus_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMSSLSocketStatus *ss;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
ss = (SSMSSLSocketStatus *) PR_CALLOC(sizeof(SSMSSLSocketStatus));
|
||||
if (!ss) goto loser;
|
||||
|
||||
rv = SSMSSLSocketStatus_Init(ss, connection,
|
||||
(PRFileDesc *) arg,
|
||||
SSM_RESTYPE_SSL_SOCKET_STATUS);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
|
||||
*res = &ss->super;
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (ss)
|
||||
{
|
||||
SSMRESOURCE(ss)->m_refCount = 1; /* force destroy */
|
||||
SSM_FreeResource(SSMRESOURCE(ss));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSSLSocketStatus_Init(SSMSSLSocketStatus *ss,
|
||||
SSMControlConnection * connection,
|
||||
PRFileDesc *fd, SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
int keySize, secretKeySize, level;
|
||||
SSMResource *certObj;
|
||||
SSMResourceID certRID;
|
||||
CERTCertificate *cert;
|
||||
|
||||
/* Initialize superclass */
|
||||
SSMResource_Init(connection, SSMRESOURCE(ss), type);
|
||||
|
||||
/* Get the peer cert and import it into an NSM object */
|
||||
cert = SSL_PeerCertificate(fd);
|
||||
if (!cert) goto loser;
|
||||
rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, cert,
|
||||
SSMRESOURCE(ss)->m_connection, &certRID,
|
||||
&certObj);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
ss->m_cert = (SSMResourceCert*)certObj;
|
||||
|
||||
/* Get the other socket status information */
|
||||
rv = SSL_SecurityStatus(fd, &level, &ss->m_cipherName,
|
||||
&keySize,
|
||||
&secretKeySize,
|
||||
NULL, NULL);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
ss->m_keySize = keySize;
|
||||
ss->m_secretKeySize = secretKeySize;
|
||||
ss->m_level = level;
|
||||
/* Sanity check before returning */
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
/* member destruct, if any are allocated, will happen in the
|
||||
_Destroy method */
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSSLSocketStatus_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMSSLSocketStatus *ss = (SSMSSLSocketStatus *) res;
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
/* Destroy our members. */
|
||||
if (ss->m_cert)
|
||||
{
|
||||
SSM_FreeResource(&ss->m_cert->super);
|
||||
ss->m_cert = NULL;
|
||||
}
|
||||
if (ss->m_cipherName)
|
||||
{
|
||||
PORT_Free(ss->m_cipherName);
|
||||
ss->m_cipherName = NULL;
|
||||
}
|
||||
|
||||
/* Destroy superclass. */
|
||||
SSMResource_Destroy(res, PR_FALSE);
|
||||
|
||||
/* Free if asked. */
|
||||
if (doFree)
|
||||
PR_Free(res);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMSSLSocketStatus_Invariant(SSMSSLSocketStatus *ss)
|
||||
{
|
||||
/* Superclass invariant */
|
||||
SSMResource_Invariant(SSMRESOURCE(ss));
|
||||
|
||||
/* Class check */
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(ss), SSM_RESTYPE_SSL_SOCKET_STATUS));
|
||||
|
||||
/* Member check */
|
||||
#if 0
|
||||
/* Make sure we used a cert to initialize ourselves */
|
||||
if (ss->m_cert)
|
||||
PR_ASSERT(ss->m_cert != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSSLSocketStatus_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMResource_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 4) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_SSS_KEYSIZE;
|
||||
(*ids)[*count++] = SSM_FID_SSS_SECRET_KEYSIZE;
|
||||
(*ids)[*count++] = SSM_FID_SSS_CERT_ID;
|
||||
(*ids)[*count++] = SSM_FID_SSS_CIPHER_NAME;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMSSLSocketStatus_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMSSLSocketStatus *ss = (SSMSSLSocketStatus *) res;
|
||||
char *tmpstr = NULL;
|
||||
|
||||
SSM_DEBUG("socket status get attr is called.\n");
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_SSS_KEYSIZE:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = ss->m_keySize;
|
||||
break;
|
||||
case SSM_FID_SSS_SECRET_KEYSIZE:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = ss->m_secretKeySize;
|
||||
break;
|
||||
case SSM_FID_SSS_CERT_ID:
|
||||
value->type = SSM_RID_ATTRIBUTE;
|
||||
value->u.numeric = ss->m_cert->super.m_id;
|
||||
break;
|
||||
case SSM_FID_SSS_SECURITY_LEVEL:
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
value->u.numeric = ss->m_level;
|
||||
break;
|
||||
case SSM_FID_SSS_CIPHER_NAME:
|
||||
value->type = SSM_STRING_ATTRIBUTE;
|
||||
value->u.string.len = PL_strlen(ss->m_cipherName);
|
||||
value->u.string.data = (unsigned char *) PL_strdup(ss->m_cipherName);
|
||||
break;
|
||||
|
||||
case SSM_FID_SSS_HTML_STATUS:
|
||||
value->type = SSM_STRING_ATTRIBUTE;
|
||||
rv = (*res->m_html_func)(res, NULL, (void**)&tmpstr);
|
||||
|
||||
value->u.string.len = PL_strlen(tmpstr);
|
||||
value->u.string.data = (unsigned char *) PL_strdup(tmpstr);
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMResource_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
if (tmpstr != NULL)
|
||||
PR_Free(tmpstr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_Pickle(SSMResource *res, PRIntn * len,
|
||||
void **value)
|
||||
{
|
||||
int blobSize, certSize;
|
||||
SSMStatus rv;
|
||||
SSMSSLSocketStatus * resource = (SSMSSLSocketStatus *)res;
|
||||
void * certBlob, *curptr, *tmpStr = NULL;
|
||||
|
||||
if (!res || !value) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
/* in case we fail */
|
||||
*value = NULL;
|
||||
if (len) *len = 0;
|
||||
#if 0
|
||||
/* first, pickle cert */
|
||||
rv = SSMControlConnection_GetResource(res->m_connection,
|
||||
resource->m_certID,
|
||||
(SSMResource **)&certObj);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
#endif
|
||||
|
||||
rv = SSM_PickleResource(&resource->m_cert->super, &certSize, &certBlob);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
/* allocate memory for the pickled blob */
|
||||
blobSize = certSize + sizeof(PRUint32)*5 +
|
||||
SSMSTRING_PADDED_LENGTH(strlen(resource->m_cipherName));
|
||||
curptr = PORT_ZAlloc(blobSize);
|
||||
if (!curptr) {
|
||||
rv = PR_OUT_OF_MEMORY_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
*value = curptr;
|
||||
*(PRUint32 *)curptr = resource->m_keySize;
|
||||
curptr = (PRUint32 *)curptr + 1;
|
||||
*(PRUint32 *)curptr = resource->m_secretKeySize;
|
||||
curptr = (PRUint32 *)curptr + 1;
|
||||
*(PRInt32*)curptr = resource->m_level;
|
||||
curptr = (PRInt32 *)curptr + 1;
|
||||
*(PRInt32*)curptr = resource->m_error;
|
||||
curptr = (PRInt32 *)curptr + 1;
|
||||
rv = SSM_StringToSSMString((SSMString **)&tmpStr, 0, resource->m_cipherName);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
memcpy(curptr, tmpStr, SSM_SIZEOF_STRING(*(SSMString *)tmpStr));
|
||||
curptr = (char *)curptr + SSM_SIZEOF_STRING(*(SSMString *)tmpStr);
|
||||
PR_Free(tmpStr);
|
||||
tmpStr = NULL;
|
||||
/* copy cert into the blob */
|
||||
memcpy(curptr, certBlob, certSize);
|
||||
|
||||
if (len) *len = blobSize;
|
||||
|
||||
return rv;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
if (value && *value)
|
||||
PR_Free(*value);
|
||||
if (len)
|
||||
*len = 0;
|
||||
if (tmpStr)
|
||||
PR_Free(tmpStr);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_Unpickle(SSMResource ** res,
|
||||
SSMControlConnection * connection,
|
||||
PRInt32 len,
|
||||
void *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMSSLSocketStatus *ss;
|
||||
void * curptr = NULL;
|
||||
PRUint32 strLength = 0, certLength = 0;
|
||||
SSMResource * certResource = NULL;
|
||||
|
||||
if (!res || !value) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
ss = (SSMSSLSocketStatus *) PR_CALLOC(sizeof(SSMSSLSocketStatus));
|
||||
if (!ss) goto loser;
|
||||
ss->m_cipherName = NULL;
|
||||
ss->m_cert = NULL;
|
||||
|
||||
/* Initialize superclass */
|
||||
SSMResource_Init(connection, SSMRESOURCE(ss),
|
||||
SSM_RESTYPE_SSL_SOCKET_STATUS);
|
||||
/* Unpickle socket status data */
|
||||
curptr = value;
|
||||
|
||||
ss->m_keySize = *(PRUint32 *)curptr;
|
||||
curptr =(PRUint32 *)curptr + 1;
|
||||
ss->m_secretKeySize = *(PRUint32 *)curptr;
|
||||
curptr =(PRUint32 *)curptr + 1;
|
||||
ss->m_level = *(PRInt32 *)curptr;
|
||||
curptr = (PRInt32 *)curptr + 1;
|
||||
ss->m_error = *(PRInt32 *)curptr;
|
||||
curptr = (PRInt32 *)curptr + 1;
|
||||
|
||||
/* Fix this */
|
||||
rv = SSM_SSMStringToString(&ss->m_cipherName, (int *) &strLength,
|
||||
(SSMString *)curptr);
|
||||
if (rv != PR_SUCCESS || ss->m_cipherName == NULL || strLength == 0)
|
||||
goto loser;
|
||||
curptr = (char *)curptr + SSMSTRING_PADDED_LENGTH(strLength) +
|
||||
sizeof(PRUint32);
|
||||
|
||||
/* Unpickle cert */
|
||||
certLength = len - ((unsigned long)curptr - (unsigned long)value);
|
||||
rv = SSM_UnpickleResource(&certResource, SSM_RESTYPE_CERTIFICATE,
|
||||
connection, certLength, curptr);
|
||||
if (rv != PR_SUCCESS || !certResource)
|
||||
goto loser;
|
||||
#if 0
|
||||
ss->m_certID = certResource->m_id;
|
||||
#endif
|
||||
ss->m_cert = (SSMResourceCert*)certResource;
|
||||
/* Sanity check before returning */
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
|
||||
*res = SSMRESOURCE(ss);
|
||||
goto done;
|
||||
|
||||
loser:
|
||||
if (ss) {
|
||||
if (ss->m_cipherName)
|
||||
PR_Free(ss->m_cipherName);
|
||||
if (ss->m_cert) {
|
||||
SSM_FreeResource(&ss->m_cert->super);
|
||||
#if 0
|
||||
(*(certResource->m_destroy_func))(certResource, PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
PR_Free(certResource);
|
||||
}
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_HTML(SSMResource *res, PRIntn *len, void ** value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMSSLSocketStatus * resource = (SSMSSLSocketStatus *)res;
|
||||
char * line = NULL;
|
||||
|
||||
if (!res || !value) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
if (len) *len = 0;
|
||||
*value = NULL;
|
||||
|
||||
switch (resource->m_level) {
|
||||
case SSL_SECURITY_STATUS_ON_HIGH:
|
||||
#ifdef FORTEZZA
|
||||
case SSL_SECURITY_STATUS_FORTEZZA:
|
||||
#endif
|
||||
line = PR_smprintf("%s", SECURITY_HIGH_MESSAGE);
|
||||
break;
|
||||
case SSL_SECURITY_STATUS_ON_LOW:
|
||||
line = PR_smprintf("%s", SECURITY_LOW_MESSAGE);
|
||||
break;
|
||||
default:
|
||||
*value = PR_smprintf("%s", SECURITY_NO_MESSAGE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (resource->m_keySize != resource->m_secretKeySize) {
|
||||
*value = PR_smprintf("%s (%s, %d bit with %d secret).", line,
|
||||
resource->m_cipherName,
|
||||
resource->m_keySize,
|
||||
resource->m_secretKeySize);
|
||||
} else {
|
||||
*value = PR_smprintf("%s (%s, %d bit).", line,
|
||||
resource->m_cipherName,
|
||||
resource->m_keySize);
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (value && *value)
|
||||
PR_Free(*value);
|
||||
*value = NULL;
|
||||
if (len && *len)
|
||||
*len = 0;
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
if (value && *value && len)
|
||||
*len = strlen((char *)*value)+1;
|
||||
if (line)
|
||||
PR_Free(line);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_UpdateSecurityStatus(SSMSSLSocketStatus* ss,
|
||||
PRFileDesc* socket)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
int keySize, secretKeySize, level;
|
||||
|
||||
/* ss should not be NULL when this function is called */
|
||||
PR_ASSERT(ss != NULL);
|
||||
|
||||
/* Get the security status information */
|
||||
if (ss->m_cipherName != NULL) {
|
||||
PR_Free(ss->m_cipherName);
|
||||
ss->m_cipherName = NULL;
|
||||
}
|
||||
rv = SSL_SecurityStatus(socket, &level, &ss->m_cipherName, &keySize,
|
||||
&secretKeySize, NULL, NULL);
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ss->m_keySize = keySize;
|
||||
ss->m_secretKeySize = secretKeySize;
|
||||
ss->m_level = level;
|
||||
|
||||
/* Sanity check before returning */
|
||||
SSMSSLSocketStatus_Invariant(ss);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) {
|
||||
rv = PR_FAILURE;
|
||||
}
|
||||
if (ss->m_cipherName != NULL) {
|
||||
PR_Free(ss->m_cipherName);
|
||||
ss->m_cipherName = NULL;
|
||||
}
|
||||
done:
|
||||
return rv;
|
||||
}
|
134
security/psm/server/sslskst.h
Normal file
134
security/psm/server/sslskst.h
Normal file
@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_SSLSKST_H__
|
||||
#define __SSM_SSLSKST_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "prerror.h"
|
||||
#include "pk11func.h"
|
||||
#include "secitem.h"
|
||||
#include "ssl.h"
|
||||
#include "prnetdb.h"
|
||||
#include "certt.h"
|
||||
#include "nss.h"
|
||||
#include "nspr.h"
|
||||
#include "secrng.h"
|
||||
#include "secder.h"
|
||||
#include "key.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
#include "ctrlconn.h"
|
||||
#include "dataconn.h"
|
||||
#include "certres.h"
|
||||
|
||||
/* Initialization parameters for an SSMSSLSocketStatus. */
|
||||
|
||||
/*
|
||||
SSL Socket Status object. This encapsulates the information about an SSL
|
||||
connection.
|
||||
*/
|
||||
|
||||
typedef struct SSMSSLSocketStatus
|
||||
{
|
||||
SSMResource super;
|
||||
|
||||
PRUint32 m_keySize;
|
||||
PRUint32 m_secretKeySize;
|
||||
PRInt32 m_level;
|
||||
char *m_cipherName;
|
||||
PRInt32 m_error;
|
||||
SSMResourceCert *m_cert; /* placeholder - will we want to get an
|
||||
SSMCertificate object ref later? */
|
||||
} SSMSSLSocketStatus;
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMSSLSocketStatus_Init(SSMSSLSocketStatus *ss,
|
||||
SSMControlConnection * connection,
|
||||
PRFileDesc *fd, SSMResourceType type);
|
||||
SSMStatus SSMSSLSocketStatus_Destroy(SSMResource *res, PRBool doFree);
|
||||
void SSMSSLSocketStatus_Invariant(SSMSSLSocketStatus *ss);
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count);
|
||||
|
||||
SSMStatus SSMSSLSocketStatus_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value);
|
||||
SSMStatus SSMSSLSocketStatus_Pickle(SSMResource *res, PRIntn * len,
|
||||
void **value);
|
||||
SSMStatus SSMSSLSocketStatus_Unpickle(SSMResource **res,
|
||||
SSMControlConnection * conn, PRIntn len,
|
||||
void *value);
|
||||
SSMStatus SSMSSLSocketStatus_HTML(SSMResource *res, PRIntn *len, void ** value);
|
||||
/*
|
||||
* Function: SSMStatus SSMSSLSocketStatus_UpdateSecurityStatus()
|
||||
* Purpose: updates the security status
|
||||
* Arguments and return values:
|
||||
* - ss: socket status (it should not be NULL when called)
|
||||
* - socket: SSL socket
|
||||
* - returns: PR_SUCCESS if the update is successful; PR_FAILURE otherwise
|
||||
*
|
||||
* Note: if the update fails, one can keep doing other work but (obviously)
|
||||
* should not attempt to use any of the security-related values
|
||||
*/
|
||||
SSMStatus SSMSSLSocketStatus_UpdateSecurityStatus(SSMSSLSocketStatus* ss,
|
||||
PRFileDesc* socket);
|
||||
|
||||
/*
|
||||
* The following string are used to present security status in HTML format.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
|
||||
#define SECURITY_LOW_MESSAGE "This is a secure document that uses a medium-grade encryption key suited\nfor U.S. export"
|
||||
|
||||
#define SECURITY_HIGH_MESSAGE "This is a secure document that uses a high-grade encryption key for U.S.\ndomestic use only"
|
||||
|
||||
#define SECURITY_NO_MESSAGE "This is an insecure document that is not encrypted and offers no security\nprotection."
|
||||
|
||||
#else
|
||||
|
||||
#define SECURITY_LOW_MESSAGE "This is a secure document that uses a medium-grade encryption key suited for U.S. export"
|
||||
|
||||
#define SECURITY_HIGH_MESSAGE "This is a secure document that uses a high-grade encryption key for U.S. domestic use only"
|
||||
|
||||
#define SECURITY_NO_MESSAGE "This is an insecure document that is not encrypted and offers no security protection."
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
79
security/psm/server/ssmerrs.h
Normal file
79
security/psm/server/ssmerrs.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSMERRS_H__
|
||||
#define __SSMERRS_H__
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SSM_SUCCESS = (int) 0,
|
||||
SSM_FAILURE = (int) PR_FAILURE,
|
||||
|
||||
SSM_ERROR_BASE = (int) -10000,
|
||||
SSM_ERR_ALREADY_SHUT_DOWN,
|
||||
SSM_ERR_INVALID_FUNC,
|
||||
SSM_ERR_BAD_RESOURCE_TYPE,
|
||||
SSM_ERR_BAD_RESOURCE_ID,
|
||||
SSM_ERR_BAD_ATTRIBUTE_ID,
|
||||
SSM_ERR_ATTRIBUTE_TYPE_MISMATCH,
|
||||
SSM_ERR_ATTRIBUTE_MISSING,
|
||||
SSM_ERR_DEFER_RESPONSE, /* internal: tell control connection to wait
|
||||
on a response from another thread -- the
|
||||
response is placed in the control queue */
|
||||
SSM_ERR_BAD_REQUEST, /* couldn't understand the request */
|
||||
SSM_ERR_USER_CANCEL, /* explicit cancel by user */
|
||||
SSM_ERR_WAIT_TIMEOUT, /* wait has timed out */
|
||||
SSM_ERR_CLIENT_DESTROY, /* explicit destroy by client sw */
|
||||
SSM_ERR_NO_USER_CERT, /* there was no usable user cert for client auth */
|
||||
SSM_ERR_NO_TARGET, /*Could not find a target to handle a form submission */
|
||||
SSM_ERR_NO_BUTTON, /* Could not find an OK or Cancel value in a
|
||||
form submission
|
||||
*/
|
||||
SSM_ERR_NO_FORM_NAME,
|
||||
SSM_ERR_OUT_OF_MEMORY,
|
||||
SSM_TIME_EXPIRED,
|
||||
SSM_ERR_NO_PASSWORD,
|
||||
SSM_ERR_BAD_PASSWORD,
|
||||
SSM_ERR_BAD_DB_PASSWORD,
|
||||
SSM_ERR_BAD_FILENAME,
|
||||
SSM_ERR_NEED_USER_INIT_DB,
|
||||
SSM_ERR_CANNOT_DECODE,
|
||||
SSM_ERR_NEW_DEF_MAIL_CERT,
|
||||
SSM_PKCS12_CERT_ALREADY_EXISTS,
|
||||
SSM_ERR_MAX_ERR
|
||||
};
|
||||
|
||||
#endif
|
||||
|
1278
security/psm/server/textgen.c
Normal file
1278
security/psm/server/textgen.c
Normal file
File diff suppressed because it is too large
Load Diff
144
security/psm/server/textgen.h
Normal file
144
security/psm/server/textgen.h
Normal file
@ -0,0 +1,144 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
Include file for libnls related utilities. Separated because there
|
||||
are a lot of headers for libnls, and only those objects which override
|
||||
the default Print function (see resource.h) should be including
|
||||
these files.
|
||||
|
||||
mwelch - 1999 January
|
||||
*/
|
||||
|
||||
#ifndef __textgen_h__
|
||||
#define __textgen_h__
|
||||
|
||||
#include "nlsutil.h"
|
||||
#include "minihttp.h"
|
||||
#include "resource.h"
|
||||
#include "ctrlconn.h"
|
||||
|
||||
/* Indices for the resource bundles.
|
||||
Keep in sync with (resBundleNames) below. */
|
||||
typedef enum
|
||||
{
|
||||
SSM_RESBNDL_TEXT = (PRInt32) 0,
|
||||
SSM_RESBNDL_UI,
|
||||
SSM_RESBNDL_BIN,
|
||||
SSM_RESBNDL_DOC,
|
||||
SSM_RESBNDL_COUNT
|
||||
} SSMResourceBundleIndex;
|
||||
|
||||
extern char *resBundleNames[];
|
||||
|
||||
/* Text generator state, used by keyword handlers */
|
||||
typedef struct SSMTextGenContext
|
||||
{
|
||||
struct SSMTextGenContext *m_caller; /* who called us, if at all */
|
||||
HTTPRequest * m_request; /* the HTTP request being processed */
|
||||
char* m_keyword; /* the keywd by which we are called */
|
||||
SSMCollection * m_params; /* params to this keyword */
|
||||
char* m_result; /* where we store the result */
|
||||
} SSMTextGenContext;
|
||||
|
||||
/* Create/destroy a textgen context. */
|
||||
SSMStatus SSMTextGen_NewContext(SSMTextGenContext *caller, /* can be NULL */
|
||||
HTTPRequest *req,
|
||||
char *keyword,
|
||||
char **params,
|
||||
SSMTextGenContext **result);
|
||||
|
||||
/* Create a top-level textgen context. */
|
||||
SSMStatus SSMTextGen_NewTopLevelContext(HTTPRequest *req,
|
||||
SSMTextGenContext **result);
|
||||
|
||||
void SSMTextGen_DestroyContext(SSMTextGenContext *victim);
|
||||
|
||||
/* Helper routines used with a TextGenContext */
|
||||
|
||||
SSMResource *SSMTextGen_GetTargetObject(SSMTextGenContext *cx);
|
||||
SSMResource *SSMTextGen_GetControlConnection(SSMTextGenContext *cx);
|
||||
|
||||
/*
|
||||
Top level routine called by non-NLS-using parts of Cartman.
|
||||
Retrieves a string, expands it, then formats it according to the
|
||||
_Print method of the target object.
|
||||
*/
|
||||
SSMStatus SSM_GetUTF8Text(SSMTextGenContext *cx, /* can be NULL */
|
||||
const char *key,
|
||||
char **resultText);
|
||||
|
||||
/* Get a numeric parameter from the properties file. */
|
||||
SSMStatus SSM_GetNumber(SSMTextGenContext *cx, char *key, PRInt32 *param);
|
||||
|
||||
/* Just gets and expands a string. Can pass NULL for (res). */
|
||||
SSMStatus SSM_GetAndExpandText(SSMTextGenContext *cx,
|
||||
const char *key, char **result);
|
||||
|
||||
SSMStatus SSM_GetAndExpandTextKeyedByString(SSMTextGenContext *cx,
|
||||
const char *key,
|
||||
char **result);
|
||||
|
||||
/* Keyword processing function. */
|
||||
typedef SSMStatus (*KeywordHandlerFunc)(SSMTextGenContext *cx);
|
||||
|
||||
SSMStatus SSM_HelloKeywordHandler(SSMTextGenContext *cx);
|
||||
|
||||
/* Register a keyword callback. */
|
||||
SSMStatus SSM_RegisterKeywordHandler(char *keyword,
|
||||
KeywordHandlerFunc func);
|
||||
|
||||
|
||||
/* Perform NLS-specific initialization. (dataDirectory) contains the path
|
||||
of the directory containing the "conv" folder with conversion libraries
|
||||
for the current locale. */
|
||||
void SSM_InitNLS(char *dataDirectory);
|
||||
|
||||
/* Given a key and a context, cycle through resource bundles until
|
||||
we find a match for the desired key. */
|
||||
SSMStatus
|
||||
SSM_FindUTF8StringInBundles(SSMTextGenContext *cx,
|
||||
const char *key,
|
||||
char **utf8result);
|
||||
|
||||
SSMStatus SSMTextGen_SubstituteString(SSMTextGenContext *cx,
|
||||
char *str,
|
||||
char **result);
|
||||
|
||||
SSMStatus
|
||||
SSM_WarnPKCS12Incompatibility(SSMTextGenContext *cx);
|
||||
|
||||
SSMStatus
|
||||
SSM_PassVariable(SSMTextGenContext *cx);
|
||||
|
||||
#endif
|
101
security/psm/server/timebomb.c
Normal file
101
security/psm/server/timebomb.c
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Timebomb code
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
#include "prlong.h"
|
||||
#include "timestamp.h"
|
||||
extern SSMTimeBombExpired;
|
||||
|
||||
SSMStatus SSMControlConnection_ProcessHello(SSMControlConnection *ctrl,
|
||||
SECItem *msg);
|
||||
|
||||
SSMStatus SSMTimebomb_SendMessage(SSMControlConnection * control,
|
||||
SECItem * message);
|
||||
SECItem * SSMTimebomb_GetMessage(SSMControlConnection * control);
|
||||
|
||||
void SSM_CheckTimebomb(void)
|
||||
{
|
||||
PRTime timeNow = PR_Now();
|
||||
if (LL_CMP(timeNow, >,expirationTime))
|
||||
SSMTimeBombExpired = PR_TRUE;
|
||||
else SSMTimeBombExpired = PR_FALSE;
|
||||
}
|
||||
|
||||
void SSM_CartmanHasExpired(SSMControlConnection * control)
|
||||
{
|
||||
/* time has expired for this module */
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SECItem * message = NULL;
|
||||
PRInt32 tmp, sent;
|
||||
SingleNumMessage reply;
|
||||
|
||||
SSM_DEBUG("timebomb: wait for hello message\n");
|
||||
|
||||
/* first, let control connection establish, to get browser to come up */
|
||||
message = SSMTimebomb_GetMessage(control);
|
||||
if (!message)
|
||||
goto loser;
|
||||
/* PR_ASSERT(message &&
|
||||
(message->type&SSM_TYPE_MASK == SSM_HELLO_MESSAGE));
|
||||
*/
|
||||
tmp = message->type & SSM_TYPE_MASK;
|
||||
if (tmp != SSM_HELLO_MESSAGE)
|
||||
SSM_DEBUG("timebomb: type is %x \n", tmp);
|
||||
PR_ASSERT(tmp == SSM_HELLO_MESSAGE);
|
||||
SSM_FreeMessage(message);
|
||||
message = SSM_ConstructMessage(0);
|
||||
if (!message)
|
||||
goto loser;
|
||||
message->type = SSM_REPLY_ERR_MESSAGE | SSM_HELLO_MESSAGE;
|
||||
reply.value = SSM_TIME_EXPIRED;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, message, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (!message->len || !message->data)
|
||||
goto loser;
|
||||
SSMTimebomb_SendMessage(control, message);
|
||||
SSM_DEBUG("timebomb: sent error reply for hello message, exiting...\n");
|
||||
|
||||
loser:
|
||||
/* there is some error. Clean up and exit */
|
||||
done:
|
||||
/* just quit */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif /* TIMEBOMB */
|
Loading…
x
Reference in New Issue
Block a user