--- /dev/null
+# $Id$
+# vim: syntax=pamconf
+
+auth required pam_unix.so
+account required pam_unix.so
+password required pam_deny.so
+session required pam_deny.so
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.
#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
"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;
+}
#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");
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){
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");
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;
#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
#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
#include "../config.h"
#include "rbs_server.h"
+#include "rbs_config.h"
#include "rbs_auth.h"
#include <stdlib.h>
int port = 7980;
CMBOOL rbs_server_init(void){
+ ready = cm_strdup(RBUILD_VERSION);
if(run_inetd){
return CMTRUE;
}else{
#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);
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);
}
}
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
--- /dev/null
+/* $Id$ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define RBUILD_VERSION "1.00"
+
+#endif