summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@iohq.net>2016-04-03 12:35:36 -0600
committerAaron Ball <nullspoon@iohq.net>2016-04-03 12:39:29 -0600
commit9c9a3d1d62b1876c8969ce06b1a9abd2264ac4bd (patch)
tree3c8b6861021995b369a81c04fa6ed5ce586a37ca /src
downloadremoteinfo-master.tar.gz
remoteinfo-master.tar.xz
Initial commitHEADmaster
Currently parses the query string for the key "q", and outputs REMOTE_ADDR if q == ip, or HTTP_USER_AGENT if q == agent. Also includes a lot of error handling in case the user tries to cause a buffer overflow of qs. Contains a set default of 512 bytes for each query string key and value. Also note that this commit contains a lot of useless experimental code that needs to be cleaned up and/or broken out into files other than main.c (yick).
Diffstat (limited to 'src')
-rw-r--r--src/main.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..1bc49e7
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,173 @@
+/**
+ * Copyright (C) 2014 Aaron Ball <nullspoon@iohq.net>
+ *
+ * Remoteinfo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Remoteinfo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with remoteinfo. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define qsmax 512
+
+/**
+ * Searches the query string for the specified key, and copies the value
+ * to the out variable.
+ *
+ * @param char* key Key to search the query string for
+ * @param int len Maximum length of key and value (for security reasons)
+ * @param char* out Pointer to output variable value will be copied to
+ *
+ * @return int Found (1), not found (0), or error (-1)
+ */
+int getqs(char* key, int len, char* out) {
+ char* qs;
+ char* val;
+ int valstart;
+ int i;
+
+ // Get the query string
+ qs = getenv("QUERY_STRING");
+
+ // Exit early if the query string was not found.
+ if(qs == NULL) return -1;
+
+ // Search for the key in the query string
+ val = strstr(qs, key);
+
+ // Exit early if the key/value was not found.
+ if(val == NULL) return 0;
+
+ i = 0;
+ // Find the equals sign
+ while(val[i] != '=') {
+ // break if we hit a qs delimiter (&)
+ if(val[i] == '&') return 0;
+ // Break if we hit the maximum length (for security, to avoid buffer
+ // overflows or overflow dumps.
+ if((i + 1) == len) return 0;
+ i++;
+ }
+ // Repoint the start of val
+ val = &val[i + 1];
+
+ // Reset i to 0
+ i = 0;
+ while(val[i] != '\0') {
+ // break if we hit a qs delimiter (&)
+ if(val[i] == '&') break;
+ // Break if we hit the maximum length (for security, to avoid buffer
+ // overflows or overflow dumps.
+ if((i + 1) == len) break;
+ // copy char in
+ out[i] = val[i];
+ i++;
+ }
+ out[i] = '\0';
+ return 1;
+}
+
+
+void read_file(char* path, FILE* out) {
+ FILE *f = fopen(path, "r");
+
+ fprintf(out, "<pre>");
+
+ char buf;
+ while((buf = fgetc(f)) != EOF) {
+ if(buf == '<') {
+ // Print an html line break if we fine a newline
+ fprintf(out, "&lt;");
+ } else {
+ fprintf(out, "%c", buf);
+ }
+ }
+ fprintf(out, "</pre>");
+
+ fclose(f);
+}
+
+void stylesheet(char* path, FILE* out) {
+ fprintf(out, "<link rel=\"stylesheet\" ");
+ fprintf(out, "type=\"text/css\" href=\"%s\" />\n", path);
+}
+
+int print_html_header(FILE* out) {
+ fprintf(out, "<html>\n");
+ fprintf(out, "<head>\n");
+ stylesheet("style.css", out);
+ fprintf(out, "</head>\n");
+ fprintf(out, "<body>\n");
+}
+
+void print_body(FILE* out) {
+ char q[qsmax];
+ int found;
+ char* reqvar;
+
+ // Get value of q
+ found = getqs("q", qsmax, q);
+ if(found != 1) return;
+
+ // All looks well, let's try to handle the query string.
+ if(strcmp(q, "ip") == 0) {
+ // IP request
+ reqvar = getenv("REMOTE_ADDR");
+ if(reqvar == NULL) {
+ fprintf(out, "ERROR: REMOTE_ADDR not set.");
+ } else {
+ fprintf(out, "%s", getenv("REMOTE_ADDR"));
+ }
+ } else if(strcmp(q, "agent") == 0) {
+ // Useragent request
+ reqvar = getenv("HTTP_USER_AGENT");
+ if(reqvar == NULL) {
+ fprintf(out, "ERROR: HTTP_USER_AGENT not set.");
+ } else {
+ fprintf(out, "%s", getenv("HTTP_USER_AGENT"));
+ }
+ }
+ fprintf(out, "\n");
+}
+
+
+void print_html_footer(FILE* out) {
+ fprintf(out, "</body>\n</html>\n");
+}
+
+
+int main(int argc, char* argv[]) {
+ // Print the content type header (very useful)
+ fprintf(stdout, "Content-Type: text/html;\n\n");
+
+ // Check if "type" qs is specified, and handle appropriately if it is
+ // This is for printing in different formats (eg: style html, json, etc)
+ int found;
+ char type[qsmax];
+ found = getqs("type", qsmax, type);
+
+ if(found == 1) {
+ // Prints the html header (<html><head>, etc.)
+ print_html_header(stdout);
+ }
+
+ print_body(stdout);
+
+ // Annnnd the footer
+ if(found == 1) {
+ // Prints the html footer (</body></html>)
+ print_html_footer(stdout);
+ }
+
+ return 0;
+}

Generated by cgit