6343a32002-11-22H. William Welliver III #pike __REAL_VERSION__
b1fd322014-09-29Martin Nilsson #require constant(SSL.Port) inherit SSL.Port;
2b3fe22004-02-29Martin Nilsson 
6343a32002-11-22H. William Welliver III import "."; int portno;
b1fd322014-09-29Martin Nilsson string interface;
6343a32002-11-22H. William Welliver III function(Request:void) callback;
e2c7ee2013-09-06Arne Goedeke //! object|function|program request_program=Request;
6343a32002-11-22H. William Welliver III 
b1fd322014-09-29Martin Nilsson //! A very simple SSL server. Binds a port and calls a callback with //! @[request_program] objects.
6343a32002-11-22H. William Welliver III 
f5553d2002-11-26H. William Welliver III //! Create a HTTPS (HTTP over SSL) server. //!
b1fd322014-09-29Martin Nilsson //! @param callback
3d13aa2002-11-27Martin Nilsson //! The function run when a request is received. //! takes one argument of type @[Request].
b1fd322014-09-29Martin Nilsson //! @param port
3d13aa2002-11-27Martin Nilsson //! The port number to bind to, defaults to 443.
b1fd322014-09-29Martin Nilsson //! @param interface
3d13aa2002-11-27Martin Nilsson //! The interface address to bind to.
f5553d2002-11-26H. William Welliver III //! @param key
3d13aa2002-11-27Martin Nilsson //! An optional SSL secret key, provided in binary format, such //! as that created by @[Standards.PKCS.RSA.private_key()].
f5553d2002-11-26H. William Welliver III //! @param certificate
3524712015-05-26Martin Nilsson //! An optional SSL certificate or chain of certificates with the host
3f76cd2004-01-15H. William Welliver III //! certificate first, provided in binary format.
790ab62014-09-03Per Hedbor //! @param share //! If true, the connection will be shared if possible. See //! @[Stdio.Port.bind] for more information
b1fd322014-09-29Martin Nilsson protected void create(function(Request:void) callback, void|int port, void|string interface, void|string|Crypto.Sign.State key, void|string|array(string) certificate, void|int share)
6343a32002-11-22H. William Welliver III {
b1fd322014-09-29Martin Nilsson  ::create();
6343a32002-11-22H. William Welliver III 
b1fd322014-09-29Martin Nilsson  portno = port || 443;
8e06a32014-09-30Martin Nilsson  this::callback=callback; this::interface=interface;
b1fd322014-09-29Martin Nilsson  if( key && certificate ) { if( stringp(certificate) ) certificate = ({ certificate }); ctx->add_cert( key, certificate, ({"*"}) ); } else set_default_keycert();
8e06a32014-09-30Martin Nilsson  if (!bind(portno, new_connection, this::interface, share))
b1fd322014-09-29Martin Nilsson  error("Failed to bind port %s%d: %s\n", interface?interface+":":"", portno, strerror(errno()));
6343a32002-11-22H. William Welliver III } void destroy() { close(); }
3d13aa2002-11-27Martin Nilsson //! The port accept callback
9eaf1d2008-06-28Martin Nilsson protected void new_connection()
6343a32002-11-22H. William Welliver III {
b1fd322014-09-29Martin Nilsson  SSL.File fd=accept();
6343a32002-11-22H. William Welliver III  Request r=request_program();
563bd72004-01-11Martin Nilsson  r->attach_fd(fd,this,callback);
6343a32002-11-22H. William Welliver III }
b1fd322014-09-29Martin Nilsson protected void set_default_keycert()
6343a32002-11-22H. William Welliver III {
b1fd322014-09-29Martin Nilsson  foreach(({ Crypto.RSA(), Crypto.DSA(),
8b52802014-03-28Henrik Grubbström (Grubba) #if constant(Crypto.ECC.Curve)
b1fd322014-09-29Martin Nilsson  Crypto.ECC.SECP_521R1.ECDSA(),
8b52802014-03-28Henrik Grubbström (Grubba) #endif
b1fd322014-09-29Martin Nilsson  }), Crypto.Sign private_key) { switch(private_key->name()) { case "RSA": private_key->generate_key(4096); break; case "DSA": private_key->generate_key(4096, 160); break; default: // ECDSA. private_key->generate_key(); break;
8b52802014-03-28Henrik Grubbström (Grubba)  }
b1fd322014-09-29Martin Nilsson  mapping a = ([ "organizationName" : "Pike TLS server", "commonName" : "*", ]); string c = Standards.X509.make_selfsigned_certificate(private_key, 3600*24*365, a); ctx->add_cert( private_key, ({ c }) );
a2be872005-12-28Martin Nilsson  }
b1fd322014-09-29Martin Nilsson }
6343a32002-11-22H. William Welliver III 
b9c0792014-09-29Martin Nilsson protected string _sprintf(int t) { return t=='O' && sprintf("%O(%O:%d)", this_program, interface, portno); }