title: Setting signature in phpbb forum with cURL and Ruby script doesn't work
body: <p>I would like to set my forum signature in a phpbb forum, because it contains a coupon code and needs to be updated from time to time as the coupon expires, eg. once a month. So I want to achieve this automatically, for example with a cron job. I want to use cURL command line application and Ruby, because I am already familiar to them. However phpbb applies some security measuers called form creation_time and form_token to avoid automatic form submissions. They are created this way:</p>
  
  <pre><code>$now = time();
      $token_sid = ($user-&gt;data['user_id'] == ANONYMOUS &amp;&amp; !empty($config['form_token_sid_guests'])) ? $user-&gt;session_id : '';
      $token = sha1($now . $user-&gt;data['user_form_salt'] . $form_name . $token_sid);
  </code></pre>
  
  <p>So creation_time represent the time as an integer value (Time.now.to_i in Ruby) and the form_token is a 40 character digest hash, which is a function of 4 variable: the mentioned time value, some kind of salt (it is taken from the phpbb database, and is set when user logs in first time), form name (ucp I think) and the PHP session id.</p>
  
  <p>My code looks like follows:</p>
  
  <pre><code>#!/usr/bin/ruby
  
  coupon_code=ARGV[0]
  
  signature="For 20% discount, use this coupon code when buying from example.com: #{coupon_code}"
  
  #getting a PHP session id, called sid from the login page before logging in
  ret=%x{curl -c ~/example-com-cookie.txt 'http://www.example.com/ucp.php?mode=login' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://www.example.com/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' --compressed -L}
  
  matchdata=/\&lt;input type\=\"hidden\" name\=\"sid\" value\=\"(.*?)\".*?\/\&gt;/.match(ret.scrub)
  if matchdata != nil then
   sid=matchdata[1]
  else
   sid=""
  end
  
  puts sid
  
  #login to the forum, and getting the cookie values, storing the in a cookie file (cookie jar)
  ret=%x{curl 'http://www.example.com/ucp.php?mode=login&amp;sid=#{sid}' -c ~/example-com-cookie.txt -H 'Origin: http://www.example.com' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Referer: http://www.example.com' -H 'Connection: keep-alive' --data 'username=myusername&amp;password=mypassword&amp;sid=#{sid}&amp;redirect=index.php&amp;login=Login' --compressed -L}
  
  #getting form_token and creation_time hidden HTML field values
  ret=%x{curl 'http://www.example.com/ucp.php?i=profile&amp;mode=signature' -b  ~/example-com-cookie.txt -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://www.example.com/ucp.php?i=profile&amp;mode=signature' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' --compressed -L}
  matchdata=(/\&lt;input type\=\"hidden\" name\=\"creation_time\" value\=\"(.*?)\".*?\/\&gt;.*?\&lt;input type\=\"hidden\" name\=\"form_token\" value\=\"(.*?)\".*?\/\&gt;/m).match(ret.scrub)
  puts matchdata.inspect
  
  creation_time=matchdata[1]
  #creation_time="1435022180"
  form_token=matchdata[2]
  #form_token="7f9d14cac39a5c5bcaf91682b3ff0410ea7ba6b8"#
  
  puts creation_time
  puts form_token
  
  #modifying signature
  ret=%x{curl 'http://www.example.com/ucp.php?i=profile&amp;mode=signature' -b  ~/example-com-cookie.txt -H 'Origin: http://www.example.com' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Referer: http://www.example.com/ucp.php?i=profile&amp;mode=signature' -H 'Connection: keep-alive' --data 'addbbcode20=100&amp;signature=#{CGI.escape(signature)}&amp;submit=Submit&amp;creation_time=#{creation_time}&amp;form_token=#{form_token}' --compressed -L}
  matchdata=/\&lt;span class\=\"genmed error\"\&gt;(.*?)\&lt;\/span\&gt;/.match(ret.scrub)
  
  if matchdata == nil then 
   puts "All OK!"
  else
   puts matchdata[1]
  end
  </code></pre>
  
  <p>I took the cURL lines form a real browser session made with Chrome, I simply copied the POST and GET requests from the developer console (Ctrl+Shift+I) with context menu "Copy as cURL" and then I made the necessary substitutions. Unfortunately my code doesn't work. I always get a HTML page containing the error message "Invalid Form". </p>
  
  <p>However when I use the two commented lines when setting the creation_time and form_token variables (they originate from a real browser session, I simply copied them from the HTML source) </p>
  
  <pre><code>creation_time="1435022180"
  form_token="7f9d14cac39a5c5bcaf91682b3ff0410ea7ba6b8"
  </code></pre>
  
  <p>my script works again even if I logout and login again from and into that real browser session! What's going on here?</p>