nmps

simple network-based command-line rpg wrote in c99
git clone git://git.kocotian.pl/nmps.git
Log | Files | Refs | LICENSE

commit ec882aa0fa04202e102a4e40cc2c5ec00b3c0f62
parent e0458872b2dfc8eeeff914ea6ebd6c4dfd945d5d
Author: kocotian <kocotian@kocotian.pl>
Date:   Mon,  9 Nov 2020 20:23:43 +0100

authorization

Diffstat:
Ahttp.h | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mnmps | 0
Mnmps.c | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 240 insertions(+), 3 deletions(-)

diff --git a/http.h b/http.h @@ -0,0 +1,149 @@ +#ifndef HTTP_H +#define HTTP_H + +#define _XOPEN_SOURCE 700 + +/* + * http.h + * simple and small http library for C99 + * version 0.1.2 + * creator: kocotian + */ + +#include <arpa/inet.h> +#include <netdb.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> + +#ifndef MAX_REQUEST_LEN +#define MAX_REQUEST_LEN 1024 +#endif + +size_t sendHTTPRequest(char *hostname, unsigned short port, char *request, int request_length, char **buffer); +size_t httpGET(char *hostname, unsigned short port, char *path, char **buffer); +int getResponseStatus(char *response); +int parseResponseLine(char *response, char *value, char **buffer); +char *truncateHeader(char *response); +int getHeaderLength(char *response); + +size_t +sendHTTPRequest(char *hostname, unsigned short port, + char *request, int request_length, char **buffer) +{ + char tmpbuf[BUFSIZ]; + struct hostent *hostent; + struct sockaddr_in sockaddr_in; + in_addr_t in_addr; + size_t totalbytes = 0; + int sockfd, byteswrote = 0, writeiter = 0; + if((hostent = gethostbyname(hostname)) == NULL) + { + fprintf(stderr, "gethostbyname(%s) error", hostname); + return 0; + } + if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + { + perror("socket opening error"); + return 0; + } + in_addr = inet_addr(inet_ntoa(*(struct in_addr*)*(hostent -> h_addr_list))); + sockaddr_in.sin_port = htons(port); + sockaddr_in.sin_addr.s_addr = in_addr; + sockaddr_in.sin_family = AF_INET; + if(connect(sockfd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)) == -1) + { + perror("socket connecting error"); + return 0; + } + if((write(sockfd, request, request_length)) == -1) + { + perror("sending request error"); + return 0; + } + *buffer = calloc(BUFSIZ, 1); + while((byteswrote = read(sockfd, tmpbuf, BUFSIZ)) > 0) + { + totalbytes += byteswrote; + strncat(*buffer, tmpbuf, byteswrote); + *buffer = realloc(*buffer, BUFSIZ * ((++writeiter) + 1)); + } + close(sockfd); + return totalbytes; +} + +size_t +httpGET(char *hostname, unsigned short port, char *path, char **buffer) +{ + char *request_template = "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n"; + char request[MAX_REQUEST_LEN]; + int request_length; + request_length = snprintf(request, MAX_REQUEST_LEN, request_template, + path, hostname); + return sendHTTPRequest(hostname, port, request, request_length, buffer); +} + +int +getResponseStatus(char *response) +{ + char *firstline = strtok(response, "\r"); char *status; + firstline = strtok(response, "\r"); + status = strtok(firstline, " "); + status = strtok(NULL, " "); + return atoi(status); +} + +int +parseResponseLine(char *response, char *value, char **buffer) +{ + char *tmpbuf = strtok(response, "\r"); + if(!strcmp(value, "HTTP")) + { + *buffer = tmpbuf; + return 0; + } + while(strcmp(tmpbuf, "\n")) + { + tmpbuf = strtok(NULL, "\r"); + unsigned short iter = -1; + char allOk = 1; + while(value[++iter]) + { + if(value[iter] != tmpbuf[iter + 1]) + { + allOk = 0; + break; + } + else allOk = 1; + } + if(allOk) + { + iter += 2; + int i2 = 1; + *buffer = malloc(i2); + while(tmpbuf[iter]) + { + (*buffer)[i2 - 1] = tmpbuf[++iter]; + *buffer = realloc(*buffer, ++i2); + } + (*buffer)[i2 - 2] = 0; + return 0; + } + } + return -1; +} + +char *truncateHeader(char *response) +{ + return strstr(response, "\r\n\r\n") + 4; +} + +int getHeaderLength(char *response) +{ + return strstr(response, "\r\n\r\n") - response; +} + +#endif diff --git a/nmps b/nmps Binary files differ. diff --git a/nmps.c b/nmps.c @@ -1,14 +1,102 @@ #define _XOPEN_SOURCE 700 +#include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/socket.h> +#include <unistd.h> -#define VERSION "a0.1" +#include "arg.h" +#include "http.h" +#include "util.c" + +#define VERSION "a0.1.1" + +extern void herror(const char *s); + +static size_t authorize(const char *host, const char *port, const char *username, const char *password); +static size_t request(char *hostname, unsigned short port, char *command, char *args[], char **buffer); +static void usage(void); + +char *argv0; + +static size_t +authorize(const char *host, const char *port, const char *username, const char *password) +{ + size_t size; + char *buffer, *args[] = {username, password, NULL}; + if (!(size = request(host, atoi(port), "/auth", args, &buffer))) + return 1; + else { + if(!strcmp(truncateHeader(buffer), "Authorized")) + return size; + else + die("%s", truncateHeader(buffer)); + } +} + +static size_t +request(char *hostname, unsigned short port, + char *command, char *args[], char **buffer) +{ + char *argv = calloc(0, 1); + char *request_template = "GET %s?argv=%s HTTP/1.0\r\nHost: %s\r\n\r\n"; + char request[BUFSIZ]; + int iter = -1, argvsize = 0, request_length; + while (args[++iter] != NULL) { + argv = realloc(argv, argvsize += strlen(args[iter]) + 1); + strcat(argv, args[iter]); + strcat(argv, "\1"); + } + request_length = snprintf(request, BUFSIZ, request_template, + command, argv, hostname); + return sendHTTPRequest(hostname, port, request, request_length, buffer); +} + +static void +usage(void) +{ + die("usage: %s [-p port] <host>", argv0); +} int main(int argc, char *argv[]) { - (void)argc; (void)argv; - puts("welcome in npms version "VERSION); + char *port = "80", *host = "localhost", username[32] = "unknown", password[64] = ""; + int character, chiter = -1; + + ARGBEGIN { + case 'p': + port = ARGF(); + break; + case 'h': /* fallthrough */ + default: + usage(); + break; + } ARGEND; + + if (argc != 1) + usage(); + + getlogin_r(username, 32); + host = argv[argc - 1]; + + fprintf(stderr, "Connecting to %s ", host); + if (gethostbyname(host) == NULL) { + herror("failed"); + return -1; + } + + fprintf(stderr, "succeeded!\n"); + fprintf(stderr, "%s@%s's password: \033[8m", username, host); + while ((character = fgetc(stdin)) != '\n') { + password[++chiter] = character; + } + password[++chiter] = 0; + fprintf(stderr, "\033[0m"); + + if(authorize(host, port, username, password)) + printf("Authorization successful!\n"); + return 0; }