]> Git repositories of Nishi - rbuild.git/commitdiff
added pam
authorNishi <nishi@nishi.boats>
Fri, 11 Oct 2024 19:30:59 +0000 (19:30 +0000)
committerNishi <nishi@nishi.boats>
Fri, 11 Oct 2024 19:30:59 +0000 (19:30 +0000)
git-svn-id: file:///raid/svn-personal/rbuild/trunk@8 c68d3453-7f82-0740-9748-1d72386a946b

PAM/rbuild [new file with mode: 0644]
README
Server/auth.c
Server/config.c
Server/main.c
Server/rbs_auth.h
Server/rbs_config.h
Server/server.c
config.h [new file with mode: 0644]

diff --git a/PAM/rbuild b/PAM/rbuild
new file mode 100644 (file)
index 0000000..36ff444
--- /dev/null
@@ -0,0 +1,7 @@
+# $Id$
+# vim: syntax=pamconf
+
+auth required pam_unix.so
+account required pam_unix.so
+password required pam_deny.so
+session required pam_deny.so
diff --git a/README b/README
index c80c8312e0649a001bf9230f66ee88e0753028c8..ee7a428d4ca89b359d847809e5568de23278bf2e 100644 (file)
--- a/README
+++ b/README
@@ -1 +1,3 @@
 Remote builder. Useful for cross-compiling, just to reduce your resource usage, etc.
+
+You probably want to copy PAM/rbuild to /etc/pam.d to get PAM authentication working.
index c196dcbc5a3c77ed26fe85a58d898619e242a777..ec4d4f1e75e582b1909d282c13625aa5d00260e7 100644 (file)
@@ -2,6 +2,14 @@
 
 #include "rbs_auth.h"
 
+#include "rbs_config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <cm_bool.h>
+#include <cm_string.h>
+
 #ifdef HAS_PAM_AUTH
 #include <security/pam_appl.h>
 #endif
@@ -37,3 +45,71 @@ const char* rbs_none_auth =
 "not available"
 #endif
 ;
+
+#ifdef HAS_PAM_AUTH
+int rbs_pam_conv(int nmsg, const struct pam_message** msg, struct pam_response** resp, void* appdata){
+       int i;
+       *resp = malloc(sizeof(**resp) * nmsg);
+       for(i = 0; i < nmsg; i++){
+               if((*msg)[i].msg_style == PAM_PROMPT_ECHO_OFF || (*msg)[i].msg_style == PAM_PROMPT_ECHO_ON){
+                       (*resp)[i].resp = cm_strdup((const char*)appdata);
+                       (*resp)[i].resp_retcode = 0;
+               }
+       }
+       return PAM_SUCCESS;
+}
+
+CMBOOL rbs_auth_pam(const char* username, const char* password){
+       CMBOOL state = CMFALSE;
+       struct pam_conv conv;
+       pam_handle_t* pamh = NULL;
+       int retval;
+       conv.conv = rbs_pam_conv;
+       conv.appdata_ptr = (void*)password;
+       retval = pam_start("rbuild", NULL, &conv, &pamh);
+       if(retval == PAM_SUCCESS){
+               retval = pam_set_item(pamh, PAM_USER, username);
+       }
+       if(retval == PAM_SUCCESS){
+               retval = pam_authenticate(pamh, 0);
+       }
+       if(retval == PAM_SUCCESS){
+               retval = pam_acct_mgmt(pamh, 0);
+       }
+       if(retval == PAM_SUCCESS){
+               state = CMTRUE;
+       }
+       pam_end(pamh, retval);
+       return state;
+}
+#endif
+
+CMBOOL rbs_auth(const char* section, const char* username, const char* password){
+       char* auth = cm_strdup(rbs_config_get(section, "auth"));
+       int i;
+       char* arg = NULL;
+       CMBOOL state = CMFALSE;
+       for(i = 0; auth[i] != 0; i++){
+               if(auth[i] == ':'){
+                       arg = auth + i + 1;
+                       auth[i] = 0;
+                       break;
+               }
+       }
+#ifdef HAS_NONE_AUTH
+       if(strcmp(auth, "none") == 0){
+               state = CMTRUE;
+       }else
+#endif
+#ifdef HAS_PAM_AUTH
+       if(strcmp(auth, "pam") == 0){
+               state = rbs_auth_pam(username, password);
+       }else
+#endif
+       if(1){
+               free(auth);
+               return CMFALSE;
+       }
+       free(auth);
+       return state;
+}
index cbf772c3aa20d0a6870bcae38a88dd85b05bf46b..b757ecad7f2392c2772838f6d88776eb95310056 100644 (file)
@@ -2,19 +2,97 @@
 
 #include "rbs_config.h"
 
+#include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
 
+#include <cm_string.h>
 #include <cm_bool.h>
 
+extern CMBOOL run_inetd;
+
+struct rbs_section sections[1024];
+int used_sections = -1;
+
 extern char* rbs_config;
 
 void rbs_config_init(void){
+       int i;
+       for(i = 0; i <= used_sections; i++){
+               int j;
+               for(j = 0; j < sections[i].used; j++){
+                       free(sections[i].attr[j].key);
+                       free(sections[i].attr[j].value);
+               }
+               free(sections[i].name);
+       }
+       used_sections = -1;
+}
+
+char* rbs_config_get(const char* section, const char* key){
+       int i;
+       for(i = 0; i <= used_sections; i++){
+               if(strcmp(sections[i].name, section) == 0){
+                       int j;
+                       for(j = 0; j < sections[i].used; j++){
+                               if(strcmp(sections[i].attr[j].key, key) == 0) return sections[i].attr[j].value;
+                       }
+               }
+       }
+       return "";
 }
 
 CMBOOL rbs_config_parse(void){
        FILE* f = fopen(rbs_config, "r");
        if(f != NULL){
+               struct stat s;
+               if(stat(rbs_config, &s) == 0){
+                       char* buf = malloc(s.st_size + 1);
+                       int i;
+                       int incr = 0;
+                       buf[s.st_size] = 0;
+                       fread(buf, 1, s.st_size, f);
+                       for(i = 0;; i++){
+                               if(buf[i] == 0 || buf[i] == '\n'){
+                                       char oldc = buf[i];
+                                       char* line;
+                                       buf[i] = 0;
+
+                                       line = buf + incr;
+                                       if(strlen(line) > 0 && line[0] != '#'){
+                                               if(line[0] == '[' && line[strlen(line) - 1] == ']'){
+                                                       line[strlen(line) - 1] = 0;
+                                                       used_sections++;
+                                                       sections[used_sections].name = cm_strdup(line + 1);
+                                                       sections[used_sections].used = 0;
+                                                       if(!run_inetd) printf("Adding section `%s'\n", line + 1);
+                                               }else if(used_sections == -1){
+                                               }else{
+                                                       int j;
+                                                       for(j = 0; line[j] != 0; j++){
+                                                               if(line[j] == '='){
+                                                                       line[j] = 0;
+                                                                       sections[used_sections].attr[sections[used_sections].used].key = cm_strdup(line);
+                                                                       sections[used_sections].attr[sections[used_sections].used].value = cm_strdup(line + j + 1);
+                                                                       if(!run_inetd) printf("\t%s: `%s'\n", line, line + j + 1);
+                                                                       sections[used_sections].used++;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       incr = i + 1;
+                                       if(oldc == 0) break;
+                               }else if(buf[i] == '\r'){
+                                       buf[i] = 0;
+                               }
+                       }
+                       free(buf);
+               }
                fclose(f);
+               if(used_sections == -1) return CMFALSE;
                return CMTRUE;
        }else{
                fprintf(stderr, "Could not open the config\n");
index 0a38e6a747b0807bc7c4af3d0ede14ca448c36d4..6f02e21fb9e610aee60ebea21ee1e1420bf637b4 100644 (file)
@@ -20,6 +20,7 @@ extern const char* rbs_pam_auth;
 
 int main(int argc, char** argv){
        int i;
+       CMBOOL dryrun = CMFALSE;
        for(i = 1; i < argc; i++){
                if(argv[i][0] == '-'){
                        if(strcmp(argv[i], "--inetd") == 0 || strcmp(argv[i], "-i") == 0){
@@ -31,6 +32,8 @@ int main(int argc, char** argv){
                                        return 1;
                                }
                                rbs_config = argv[i];
+                       }else if(strcmp(argv[i], "--dry-run") == 0 || strcmp(argv[i], "-d") == 0){
+                               dryrun = CMTRUE;
                        }else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0){
                                printf("rbuild-server version %s\n", RBUILD_VERSION);
                                printf("Authentication methods:\n");
@@ -55,6 +58,7 @@ int main(int argc, char** argv){
                fprintf(stderr, "Failed to parse config\n");
                return 1;
        }
+       if(dryrun) return 0;
        if(!rbs_server_init()){
                fprintf(stderr, "Failed to initialize\n");
                return 1;
index e8119145d1010889302bbd0c078e29be51771ec0..4ac1e492e7bcdce2afa1e0f431f3f7ee89d561c5 100644 (file)
@@ -3,4 +3,8 @@
 #ifndef __RBS_AUTH_H__
 #define __RBS_AUTH_H__
 
+#include <cm_bool.h>
+
+CMBOOL rbs_auth(const char* section, const char* username, const char* password);
+
 #endif
index 538601bde1c692dc2ee08d587e240617de895b8e..0dda5e49a6d2d68e43eaf826fd65c78199708d7c 100644 (file)
@@ -6,6 +6,18 @@
 #include <cm_bool.h>
 
 void rbs_config_init(void);
+char* rbs_config_get(const char* section, const char* key);
 CMBOOL rbs_config_parse(void);
 
+struct rbs_kv {
+       char* key;
+       char* value;
+};
+
+struct rbs_section {
+       char* name;
+       struct rbs_kv attr[128];
+       int used;
+};
+
 #endif
index 6ce96c45d7b1333ac714f2c56cc8fa2d8e467719..ea9c36efbac60b4fa6e8af67802e53aefef75a52 100644 (file)
@@ -3,6 +3,7 @@
 #include "../config.h"
 
 #include "rbs_server.h"
+#include "rbs_config.h"
 #include "rbs_auth.h"
 
 #include <stdlib.h>
@@ -32,6 +33,7 @@ int server_socket;
 int port = 7980;
 
 CMBOOL rbs_server_init(void){
+       ready = cm_strdup(RBUILD_VERSION);
        if(run_inetd){
                return CMTRUE;
        }else{
@@ -87,8 +89,46 @@ void rbs_close(int sock){
 #endif
 }
 
+char* rbs_readline(int sock){
+       char cbuf[2];
+       char* line;
+       cbuf[1] = 0;
+       line = cm_strdup("");
+       do{
+               fd_set rfds;
+               struct timeval tv;
+               int ret;
+
+               FD_ZERO(&rfds);
+               FD_SET(sock, &rfds);
+               tv.tv_sec = 5;
+               tv.tv_usec = 0;
+
+               ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
+               if(ret <= 0){
+                       free(line);
+                       return NULL;
+               }
+               if(run_inetd){
+                       fread(cbuf, 1, 1, stdin);
+               }else{
+                       recv(sock, cbuf, 1, 0);
+               }
+               if(cbuf[0] != '\n' && cbuf[0] != '\r'){
+                       char* tmp = line;
+                       line = cm_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+       }while(cbuf[0] != '\n');
+       return line;
+}
+
 void rbs_server_handler(void* sockptr){
-       int sock = -1;
+       int sock = 0;
+       char* user = NULL;
+       char* pass = NULL;
+       char* section = NULL;
+       CMBOOL authed = CMFALSE;
        if(sockptr != NULL){
                sock = *(int*)sockptr;
                free(sockptr);
@@ -107,14 +147,61 @@ void rbs_server_handler(void* sockptr){
                tv.tv_sec = 5;
                tv.tv_usec = 0;
 
-               ret = select(1, &rfds, NULL, NULL, &tv);
+               ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
 
                if(ret < 0){
                        break;
                }else if(ret == 0){
-                       rbs_write(sock, "TIMEOUT\n", 8);
                        break;
                }else{
+                       char* line = rbs_readline(sock);
+                       int i;
+                       char* arg = NULL;
+                       char* cmd = line;
+                       if(line == NULL){
+                               break;
+                       }
+                       for(i = 0; line[i] != 0; i++){
+                               if(line[i] == ' '){
+                                       line[i] = 0;
+                                       arg = line + i + 1;
+                                       break;
+                               }
+                       }
+                       if(strcmp(cmd, "QUIT") == 0){
+                               free(line);
+                               break;
+                       }else if(strcmp(cmd, "SECTION") == 0 && arg != NULL){
+                               if(strcmp(rbs_config_get(arg, "auth"), "") == 0 || section != NULL){
+                                       free(line);
+                                       break;
+                               }
+                               section = cm_strdup(arg);
+                       }else if(strcmp(cmd, "USER") == 0 && arg != NULL){
+                               if(section == NULL || user != NULL){
+                                       free(line);
+                                       break;
+                               }
+                               user = cm_strdup(arg);
+                       }else if(strcmp(cmd, "PASS") == 0 && arg != NULL){
+                               if(user == NULL || pass != NULL){
+                                       free(line);
+                                       break;
+                               }
+                               pass = cm_strdup(arg);
+                               if(rbs_auth(section, user, pass)){
+                                       rbs_write(sock, "SUCCESS\n", 8);
+                                       authed = CMTRUE;
+                               }else{
+                                       rbs_write(sock, "FAIL\n", 5);
+                                       free(line);
+                                       break;
+                               }
+                       }else{
+                               free(line);
+                               break;
+                       }
+                       free(line);
                }
        }
 
@@ -126,9 +213,9 @@ void rbs_server_handler(void* sockptr){
 
 CMBOOL rbs_server_loop(void){
        if(run_inetd){
+               setvbuf(stdin, NULL, _IONBF, 0);
                rbs_server_handler(NULL);
        }else{
-               ready = cm_strdup(RBUILD_VERSION);
 #ifndef WINSOCK
                signal(SIGCHLD, SIG_IGN);
 #endif
diff --git a/config.h b/config.h
new file mode 100644 (file)
index 0000000..4e7153b
--- /dev/null
+++ b/config.h
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define RBUILD_VERSION "1.00"
+
+#endif