128 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
| #!/usr/bin/env python
 | |
| #
 | |
| # -*- coding: utf-8 -*-
 | |
| # Copyright 2020 The Matrix.org Foundation C.I.C.
 | |
| #
 | |
| # Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| # Unless required by applicable law or agreed to in writing, software
 | |
| # distributed under the License is distributed on an "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| # See the License for the specific language governing permissions and
 | |
| # limitations under the License.
 | |
| import argparse
 | |
| import json
 | |
| import sys
 | |
| from json import JSONDecodeError
 | |
| 
 | |
| import yaml
 | |
| from signedjson.key import read_signing_keys
 | |
| from signedjson.sign import sign_json
 | |
| 
 | |
| from synapse.util import json_encoder
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     parser = argparse.ArgumentParser(
 | |
|         description="""Adds a signature to a JSON object.
 | |
| 
 | |
| Example usage:
 | |
| 
 | |
|     $ scripts-dev/sign_json.py -N test -k localhost.signing.key "{}"
 | |
|     {"signatures":{"test":{"ed25519:a_ZnZh":"LmPnml6iM0iR..."}}}
 | |
| """,
 | |
|         formatter_class=argparse.RawDescriptionHelpFormatter,
 | |
|     )
 | |
| 
 | |
|     parser.add_argument(
 | |
|         "-N",
 | |
|         "--server-name",
 | |
|         help="Name to give as the local homeserver. If unspecified, will be "
 | |
|         "read from the config file.",
 | |
|     )
 | |
| 
 | |
|     parser.add_argument(
 | |
|         "-k",
 | |
|         "--signing-key-path",
 | |
|         help="Path to the file containing the private ed25519 key to sign the "
 | |
|         "request with.",
 | |
|     )
 | |
| 
 | |
|     parser.add_argument(
 | |
|         "-c",
 | |
|         "--config",
 | |
|         default="homeserver.yaml",
 | |
|         help=(
 | |
|             "Path to synapse config file, from which the server name and/or signing "
 | |
|             "key path will be read. Ignored if --server-name and --signing-key-path "
 | |
|             "are both given."
 | |
|         ),
 | |
|     )
 | |
| 
 | |
|     input_args = parser.add_mutually_exclusive_group()
 | |
| 
 | |
|     input_args.add_argument("input_data", nargs="?", help="Raw JSON to be signed.")
 | |
| 
 | |
|     input_args.add_argument(
 | |
|         "-i",
 | |
|         "--input",
 | |
|         type=argparse.FileType("r"),
 | |
|         default=sys.stdin,
 | |
|         help=(
 | |
|             "A file from which to read the JSON to be signed. If neither --input nor "
 | |
|             "input_data are given, JSON will be read from stdin."
 | |
|         ),
 | |
|     )
 | |
| 
 | |
|     parser.add_argument(
 | |
|         "-o",
 | |
|         "--output",
 | |
|         type=argparse.FileType("w"),
 | |
|         default=sys.stdout,
 | |
|         help="Where to write the signed JSON. Defaults to stdout.",
 | |
|     )
 | |
| 
 | |
|     args = parser.parse_args()
 | |
| 
 | |
|     if not args.server_name or not args.signing_key_path:
 | |
|         read_args_from_config(args)
 | |
| 
 | |
|     with open(args.signing_key_path) as f:
 | |
|         key = read_signing_keys(f)[0]
 | |
| 
 | |
|     json_to_sign = args.input_data
 | |
|     if json_to_sign is None:
 | |
|         json_to_sign = args.input.read()
 | |
| 
 | |
|     try:
 | |
|         obj = json.loads(json_to_sign)
 | |
|     except JSONDecodeError as e:
 | |
|         print("Unable to parse input as JSON: %s" % e, file=sys.stderr)
 | |
|         sys.exit(1)
 | |
| 
 | |
|     if not isinstance(obj, dict):
 | |
|         print("Input json was not an object", file=sys.stderr)
 | |
|         sys.exit(1)
 | |
| 
 | |
|     sign_json(obj, args.server_name, key)
 | |
|     for c in json_encoder.iterencode(obj):
 | |
|         args.output.write(c)
 | |
|     args.output.write("\n")
 | |
| 
 | |
| 
 | |
| def read_args_from_config(args: argparse.Namespace) -> None:
 | |
|     with open(args.config, "r") as fh:
 | |
|         config = yaml.safe_load(fh)
 | |
|         if not args.server_name:
 | |
|             args.server_name = config["server_name"]
 | |
|         if not args.signing_key_path:
 | |
|             args.signing_key_path = config["signing_key_path"]
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |