@ -123,6 +123,7 @@ namespace http {
const char HTTP_COMMAND_LOGLEVEL [ ] = " set_loglevel " ;
const char HTTP_COMMAND_LOGLEVEL [ ] = " set_loglevel " ;
const char HTTP_COMMAND_KILLSTREAM [ ] = " closestream " ;
const char HTTP_COMMAND_KILLSTREAM [ ] = " closestream " ;
const char HTTP_COMMAND_LIMITTRANSIT [ ] = " limittransit " ;
const char HTTP_COMMAND_LIMITTRANSIT [ ] = " limittransit " ;
const char HTTP_COMMAND_GET_REG_STRING [ ] = " get_reg_string " ;
const char HTTP_PARAM_SAM_SESSION_ID [ ] = " id " ;
const char HTTP_PARAM_SAM_SESSION_ID [ ] = " id " ;
const char HTTP_PARAM_ADDRESS [ ] = " address " ;
const char HTTP_PARAM_ADDRESS [ ] = " address " ;
@ -407,7 +408,7 @@ namespace http {
}
}
}
}
static void ShowLeaseSetDestination ( std : : stringstream & s , std : : shared_ptr < const i2p : : client : : LeaseSetDestination > dest )
static void ShowLeaseSetDestination ( std : : stringstream & s , std : : shared_ptr < const i2p : : client : : LeaseSetDestination > dest , uint32_t token )
{
{
s < < " <b>Base64:</b><br> \r \n <textarea readonly cols= \" 80 \" rows= \" 8 \" wrap= \" on \" > " ;
s < < " <b>Base64:</b><br> \r \n <textarea readonly cols= \" 80 \" rows= \" 8 \" wrap= \" on \" > " ;
s < < dest - > GetIdentity ( ) - > ToBase64 ( ) < < " </textarea><br> \r \n <br> \r \n " ;
s < < dest - > GetIdentity ( ) - > ToBase64 ( ) < < " </textarea><br> \r \n <br> \r \n " ;
@ -419,6 +420,20 @@ namespace http {
s < < " </div> \r \n </div> \r \n " ;
s < < " </div> \r \n </div> \r \n " ;
}
}
if ( dest - > IsPublic ( ) )
{
std : : string webroot ; i2p : : config : : GetOption ( " http.webroot " , webroot ) ;
auto base32 = dest - > GetIdentHash ( ) . ToBase32 ( ) ;
s < < " <div class='slide'><label for='slide-regaddr'><b>Address registration line</b></label> \r \n <input type= \" checkbox \" id= \" slide-regaddr \" /> \r \n <div class= \" slidecontent \" > \r \n "
" <form method= \" get \" action= \" " < < webroot < < " \" > \r \n "
" <input type= \" hidden \" name= \" cmd \" value= \" " < < HTTP_COMMAND_GET_REG_STRING < < " \" > \r \n "
" <input type= \" hidden \" name= \" token \" value= \" " < < token < < " \" > \r \n "
" <input type= \" hidden \" name= \" b32 \" value= \" " < < base32 < < " \" > \r \n "
" <b>Domain:</b> \r \n <input type= \" text \" maxlength= \" 67 \" name= \" name \" placeholder= \" domain.i2p \" required> \r \n "
" <button type= \" submit \" >Generate</button> \r \n "
" </form> \r \n <small><b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.</small> \r \n </div> \r \n </div> \r \n <br> \r \n " ;
}
if ( dest - > GetNumRemoteLeaseSets ( ) )
if ( dest - > GetNumRemoteLeaseSets ( ) )
{
{
s < < " <div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i> " < < dest - > GetNumRemoteLeaseSets ( )
s < < " <div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i> " < < dest - > GetNumRemoteLeaseSets ( )
@ -494,7 +509,7 @@ namespace http {
if ( dest )
if ( dest )
{
{
ShowLeaseSetDestination ( s , dest ) ;
ShowLeaseSetDestination ( s , dest , token ) ;
// show streams
// show streams
s < < " <table> \r \n <caption>Streams</caption> \r \n <thead> \r \n <tr> " ;
s < < " <table> \r \n <caption>Streams</caption> \r \n <thead> \r \n <tr> " ;
s < < " <th style= \" width:25px; \" >StreamID</th> " ;
s < < " <th style= \" width:25px; \" >StreamID</th> " ;
@ -545,7 +560,7 @@ namespace http {
s < < " <b>I2CP Local Destination:</b><br> \r \n <br> \r \n " ;
s < < " <b>I2CP Local Destination:</b><br> \r \n <br> \r \n " ;
auto it = i2cpServer - > GetSessions ( ) . find ( std : : stoi ( id ) ) ;
auto it = i2cpServer - > GetSessions ( ) . find ( std : : stoi ( id ) ) ;
if ( it ! = i2cpServer - > GetSessions ( ) . end ( ) )
if ( it ! = i2cpServer - > GetSessions ( ) . end ( ) )
ShowLeaseSetDestination ( s , it - > second - > GetDestination ( ) ) ;
ShowLeaseSetDestination ( s , it - > second - > GetDestination ( ) , 0 ) ;
else
else
ShowError ( s , " I2CP session not found " ) ;
ShowError ( s , " I2CP session not found " ) ;
}
}
@ -1210,15 +1225,15 @@ namespace http {
if ( dest )
if ( dest )
{
{
if ( dest - > DeleteStream ( streamID ) )
if ( dest - > DeleteStream ( streamID ) )
s < < " <b>SUCCESS</b>: Stream closed<br><br> \r \n " ;
s < < " <b>SUCCESS</b>: Stream closed<br> \r \n <br> \r \n " ;
else
else
s < < " <b>ERROR</b>: Stream not found or already was closed<br><br> \r \n " ;
s < < " <b>ERROR</b>: Stream not found or already was closed<br> \r \n <br> \r \n " ;
}
}
else
else
s < < " <b>ERROR</b>: Destination not found<br><br> \r \n " ;
s < < " <b>ERROR</b>: Destination not found<br> \r \n <br> \r \n " ;
}
}
else
else
s < < " <b>ERROR</b>: StreamID can be null<br><br> \r \n " ;
s < < " <b>ERROR</b>: StreamID can be null<br> \r \n <br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page=local_destination&b32= " < < b32 < < " \" >Return to destination page</a><br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page=local_destination&b32= " < < b32 < < " \" >Return to destination page</a><br> \r \n " ;
s < < " <p>You will be redirected back in 5 seconds</b> " ;
s < < " <p>You will be redirected back in 5 seconds</b> " ;
@ -1232,13 +1247,53 @@ namespace http {
if ( limit > 0 & & limit < = 65535 )
if ( limit > 0 & & limit < = 65535 )
SetMaxNumTransitTunnels ( limit ) ;
SetMaxNumTransitTunnels ( limit ) ;
else {
else {
s < < " <b>ERROR</b>: Transit tunnels count must not exceed 65535<br><br> \r \n " ;
s < < " <b>ERROR</b>: Transit tunnels count must not exceed 65535 \r \n <br> \r \n <br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page=commands \" >Back to commands list</a><br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page=commands \" >Back to commands list</a> \r \n <br> \r \n " ;
s < < " <p>You will be redirected back in 5 seconds</b> " ;
s < < " <p>You will be redirected back in 5 seconds</b> " ;
res . add_header ( " Refresh " , redirect . c_str ( ) ) ;
res . add_header ( " Refresh " , redirect . c_str ( ) ) ;
return ;
return ;
}
}
}
}
else if ( cmd = = HTTP_COMMAND_GET_REG_STRING )
{
std : : string b32 = params [ " b32 " ] ;
std : : string name = params [ " name " ] ;
i2p : : data : : IdentHash ident ;
ident . FromBase32 ( b32 ) ;
auto dest = i2p : : client : : context . FindLocalDestination ( ident ) ;
if ( dest ) {
std : : size_t pos ;
pos = name . find ( " .i2p " ) ;
if ( pos = = ( name . length ( ) - 4 ) ) {
pos = name . find ( " .b32.i2p " ) ;
if ( pos = = std : : string : : npos ) {
auto signatureLen = dest - > GetIdentity ( ) - > GetSignatureLen ( ) ;
uint8_t * signature = new uint8_t [ signatureLen ] ;
char * sig = new char [ signatureLen * 2 ] ;
std : : stringstream out ;
out < < name < < " = " < < dest - > GetIdentity ( ) - > ToBase64 ( ) ;
dest - > Sign ( ( uint8_t * ) out . str ( ) . c_str ( ) , out . str ( ) . length ( ) , signature ) ;
auto len = i2p : : data : : ByteStreamToBase64 ( signature , signatureLen , sig , signatureLen * 2 ) ;
sig [ len ] = 0 ;
out < < " #!sig= " < < sig ;
s < < " <b>SUCCESS</b>:<br> \r \n <textarea readonly cols= \" 80 \" rows= \" 10 \" wrap= \" on \" > " < < out . str ( ) < < " </textarea> \r \n <br> \r \n <br> \r \n " ;
delete [ ] signature , sig ;
} else {
s < < " <b>ERROR</b>: Domain can't end with .b32.i2p \r \n <br> \r \n <br> \r \n " ;
}
} else {
s < < " <b>ERROR</b>: Domain must end with .i2p \r \n <br> \r \n <br> \r \n " ;
}
} else {
s < < " <b>ERROR</b>: Such destination is not found \r \n <br> \r \n <br> \r \n " ;
}
s < < " <a href= \" " < < webroot < < " ?page=local_destination&b32= " < < b32 < < " \" >Return to destination page</a> \r \n " ;
return ;
}
else
else
{
{
res . code = 400 ;
res . code = 400 ;