s3:web/swat: use strtoll() instead of atoi/atol/atoll
[samba.git] / source3 / web / swat.c
index 8f64a5426f88947d36b4d33cdf7700267129246f..1ecaa5795d5293292b04f7f799f5f2d25e56e8c9 100644 (file)
@@ -59,6 +59,8 @@ static int iNumNonAutoPrintServices = 0;
 #define ENABLE_USER_FLAG "enable_user_flag"
 #define RHOST "remote_host"
 #define XSRF_TOKEN "xsrf"
+#define XSRF_TIME "xsrf_time"
+#define XSRF_TIMEOUT 300
 
 #define _(x) lang_msg_rotate(talloc_tos(),x)
 
@@ -148,7 +150,7 @@ static char *make_parm_name(const char *label)
 }
 
 void get_xsrf_token(const char *username, const char *pass,
-                   const char *formname, char token_str[33])
+                   const char *formname, time_t xsrf_time, char token_str[33])
 {
        struct MD5Context md5_ctx;
        uint8_t token[16];
@@ -159,6 +161,7 @@ void get_xsrf_token(const char *username, const char *pass,
        MD5Init(&md5_ctx);
 
        MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
+       MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
        if (username != NULL) {
                MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
        }
@@ -172,7 +175,7 @@ void get_xsrf_token(const char *username, const char *pass,
                char tmp[3];
 
                snprintf(tmp, sizeof(tmp), "%02x", token[i]);
-               strncat(token_str, tmp, sizeof(tmp));
+               strlcat(token_str, tmp, sizeof(tmp));
        }
 }
 
@@ -180,11 +183,13 @@ void print_xsrf_token(const char *username, const char *pass,
                      const char *formname)
 {
        char token[33];
+       time_t xsrf_time = time(NULL);
 
-       get_xsrf_token(username, pass, formname, token);
+       get_xsrf_token(username, pass, formname, xsrf_time, token);
        printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
               XSRF_TOKEN, token);
-
+       printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
+              XSRF_TIME, (long long int)xsrf_time);
 }
 
 bool verify_xsrf_token(const char *formname)
@@ -193,8 +198,36 @@ bool verify_xsrf_token(const char *formname)
        const char *username = cgi_user_name();
        const char *pass = cgi_user_pass();
        const char *token = cgi_variable_nonull(XSRF_TOKEN);
+       const char *time_str = cgi_variable_nonull(XSRF_TIME);
+       char *p = NULL;
+       long long xsrf_time_ll = 0;
+       time_t xsrf_time = 0;
+       time_t now = time(NULL);
+
+       errno = 0;
+       xsrf_time_ll = strtoll(time_str, &p, 10);
+       if (errno != 0) {
+               return false;
+       }
+       if (p == NULL) {
+               return false;
+       }
+       if (PTR_DIFF(p, time_str) > strlen(time_str)) {
+               return false;
+       }
+       if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
+               return false;
+       }
+       if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
+               return false;
+       }
+       xsrf_time = xsrf_time_ll;
+
+       if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
+               return false;
+       }
 
-       get_xsrf_token(username, pass, formname, expected);
+       get_xsrf_token(username, pass, formname, xsrf_time, expected);
        return (strncmp(expected, token, sizeof(expected)) == 0);
 }
 
@@ -1345,18 +1378,15 @@ static void printers_page(void)
        int i;
        int mode = 0;
        unsigned int parm_filter = FLAG_BASIC;
+       const char form_name[] = "printers";
+
+       if (!verify_xsrf_token(form_name)) {
+               goto output_page;
+       }
 
        if (share)
                snum = lp_servicenumber(share);
 
-        printf("<H2>%s</H2>\n", _("Printer Parameters"));
-        printf("<H3>%s</H3>\n", _("Important Note:"));
-        printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
-        printf("%s",_("are autoloaded printers from "));
-        printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
-        printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
-
        if (cgi_variable("Commit") && snum >= 0) {
                commit_parameters(snum);
                if (snum >= iNumNonAutoPrintServices)
@@ -1385,8 +1415,6 @@ static void printers_page(void)
                }
        }
 
-       printf("<FORM name=\"swatform\" method=post>\n");
-
        if ( cgi_variable("ViewMode") )
                mode = atoi(cgi_variable_nonull("ViewMode"));
         if ( cgi_variable("BasicMode"))
@@ -1394,6 +1422,19 @@ static void printers_page(void)
         if ( cgi_variable("AdvMode"))
                 mode = 1;
 
+output_page:
+        printf("<H2>%s</H2>\n", _("Printer Parameters"));
+
+        printf("<H3>%s</H3>\n", _("Important Note:"));
+        printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
+        printf("%s",_("are autoloaded printers from "));
+        printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
+        printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
+
+
+       printf("<FORM name=\"swatform\" method=post>\n");
+       print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
+
        ViewModeBoxes( mode );
        switch ( mode ) {
                case 0: