Files @ 17ef3ec18076
Branch filter:

Location: DistRen/src/server/slavefuncs.c

ethanzonca
Removed old key stuff from login function
/*
  Copyright 2009 Nathan Phillip Brink, Ethan Zonca, Matthew Orlando

  This file is a part of DistRen.

  DistRen is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  DistRen 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 Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
*/

 /*
  * Registration on server. Needs attention. Prevent account spamming.
  * distrenslave -c username email@example.com
 */

#include "slavefuncs.h"
#include "blendjob.h"
#include "execio.h"

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h> /*< malloc(), free() */
#include <sys/stat.h>
#include <fcntl.h>

/** Converts an integer to a string, thanks to Dom_ (http://www.signalsondisplay.com/) */
char *int_to_str(int nbr)
{
  int   div;
  int   len;
  int   i;
  char  *res;

  res = malloc(4 * sizeof(*res)); // Was xmalloc, hopefully it still works :D
  i = 0;
  while (i < 3)
    res[i++] = '\0';
  res[3] = '\0';
  i = 0;
  div = 1;
  len = 1;
  while (nbr / div >= 10)
    {
      div *= 10;
      len++;
    }
  while (len)
    {
      res[i++] = '0' + (nbr / div);
      len--;
      nbr %= div;
      div /= 10;
    }
  return (res);
}
/** Generates a SSH key with ssh-keygen */
int ssh_keygen(){
	// distren.id_rsa and distren.id_rsa.pub are now generated in SYSCONFDIR (etc)

	// Checks to see if the keys are already present.
	int status;
	struct stat buffer;
	status = stat(SYSCONFDIR "/distren.id_rsa", &buffer);
	if(status != -1){
		fprintf(stderr, "Please delete etc/distren.id_rsa and etc/distren.id_rsa.pub to register.\n");
		return 0;
	}

/* start execio code */
	char *command = "ssh-keygen"; // @TODO: append .exe if win32?
	int ret;
	char *cmd[] = { command, "-q", "-f", SYSCONFDIR "/distren.id_rsa", "-N", "", (char *)NULL }; // TODO: Give me the correct args!

	char buf[10];
	struct execio *testrem;
	size_t readlen;
	ret = execio_open(&testrem, command, cmd); // This path will be absolute for testing, should be relative to install on production
	buf[9] = '\0'; // null-terminating the array...
	while(!execio_read(testrem, buf, 9, &readlen))
	    {
	      if(readlen > 9) {
		fprintf(stderr, "Something is terribly wrong!\n");
	      }
	      buf[readlen] = '\0';
	      fprintf(stderr, "read \"%s\"\n", buf);
	    }
	execio_close(testrem);
/* end execio code */

	// Supposedly execio returns 1 if it has bad args.
	if(ret == 1){
		fprintf(stderr, "Generating your key failed. Ensure that ssh-keygen is present!\n"); // Use different executor that searches the path? there is one...
		return 0;
	}
	else{
		fprintf(stderr,"We successfully generated your key! Yay!");
		return 1;
	}
return 0;
}

/** Registers the user on the DistRen server */
int register_user(char *username, char *email)
{

	// @TODO: Check for problems (e.g. existing rsa key) BEFORE useradding!

  /*
   * Logs into sandboxed user on zserver2 and registers a user. Should eventually generate a key on the server and return it to the user.
   * All created user accounts should be sandboxed accordingly, requiring a different skel, and the default shell to be rbash. Also,
   * a custom path defined in the .bash_profile of the skel is needed.
   */
  char buf[10];
  struct execio *testrem;
  char *execargv[] =
    {
      "ssh",
      "distren_setup@protofusion.org",
      "-i",
      SYSCONFDIR "/setup_rsa", // default distributed key, account can only create users.
      "-p",
      "23",
      "newuser",
      "-M",
      "-c",
      email,
      "-d",
      "/home/distren",
      "--gid",
      "541",
      username,
      (char *)NULL
    };
  size_t readlen;
  execio_open(&testrem, "ssh", execargv); // TODO: Grab returns from this someday.
  buf[9] = '\0'; // null-terminating the array...
  while(!execio_read(testrem, buf, 9, &readlen))
    {
      if(readlen > 9) {
	fprintf(stderr, "!!!! Something is terribly wrong!\n");
      }
      buf[readlen] = '\0';
      fprintf(stderr, "read \"%s\"\n", buf);
    }
  execio_close(testrem);

  /* @TODO: Parse the output buffer or something to check when user creation fails due to duplicate users. This is pretty important. */

  // puts the person's username in the conf
  if(conf_replace(username) == 0){
	  fprintf(stderr, "Failed!\n");
	  return 0;
  }

  // generates keys for login, @TODO: pub key must somehow be sent to the server.
  if(ssh_keygen() == 0){
	  fprintf(stderr, "Failed!\n");
	  return 0;
  }

  return 1;
}

/** Logs the user into the server with a nice ssh session */
int login_user(char *username)
{
  char *userhost;
  char buf[10];
  struct execio *testrem;
  char *execargv[] =
    {
      "ssh",

      "-i",
      SYSCONF "distren.id_rsa"
      "-p",
      "23",
      (char *)NULL,// username and hostname
      "echo",
      "hello", // This should eventually open a non-terminating connection to the server for communication,

      (char *)NULL
    };
  size_t readlen;

  /*< @TODO remove being tied to protofusion.org for no reason  */
  userhost = malloc(strlen(username) + strlen("@protofusion.org") + 1);
  if(!userhost)
    return 43;

  strcpy(userhost, username);
  strcat(userhost, "@protofusion.org"); // Throws @protofusion.org after the username


  fprintf(stderr, "Logging you in to %s", userhost);
  if(fopen(SYSCONF "distren.id_rsa", "r") == NULL){
	  fprintf(stderr,"Your key, %s, has not been found! Re-register or somehow regenerate your key! We need a way to regenerate keys coded in, but we don't have the facilities yet!",userkey);
	  return 0;
  }
  execio_open(&testrem, "ssh", execargv); // TODO: Grab returns from this someday
  buf[9] = '\0'; // null-terminating the array...
  while(!execio_read(testrem, buf, 9, &readlen))
    {
      if(readlen > 9) {
	fprintf(stderr, "!!!! Something is terribly wrong!\n");
      }
    buf[readlen] = '\0';
    fprintf(stderr, "read \"%s\"\n", buf);
    }
  execio_close(testrem);
  return 1; // 1 can be like... error-free login...
}

/** Replaces username and key in the slave's conf file */
int conf_replace(char *username){
  /* Note: SYSCONFDIR doesn't include a trailing slash */
  int maxlinelen = 120;
  char *fileOrig = SYSCONFDIR "/distrenslave.conf";
  char *fileRepl = SYSCONFDIR "/distrenslave.conf.edited";
  char *text2find = "!username";
  char *text2repl = username;
  char buffer[maxlinelen+2];
  char *buff_ptr, *find_ptr;
  FILE *fp1, *fp2;
  size_t find_len = strlen(text2find);
  fp1 = fopen(fileOrig,"r");
  fp2 = fopen(fileRepl,"w");
  if (fp1 ==NULL){
	  fprintf(stderr, "%s doesn't exist\n",fileOrig);
	  return 0;
  }
  else if(fp2 ==NULL){
	  fprintf(stderr, "Can't write a file to disk! Check permissions.\n");
	  return 0;
  }
  else{
    while(fgets(buffer,maxlinelen+2,fp1))
      {
          buff_ptr = buffer;
          while ((find_ptr = strstr(buff_ptr,text2find)))
          {
          while(buff_ptr < find_ptr)
          	fputc((int)*buff_ptr++,fp2);
          fputs(text2repl,fp2);
          buff_ptr += find_len;
          }
          fputs(buff_ptr,fp2);
      }
    rename(fileRepl, fileOrig);
  }

  fclose(fp2);
  fclose(fp1);
  fprintf(stderr,"Wrote conf file...\n");
return 1;
}


/* Executors */

/*
  It seems that the client will need to know the job number. fixme.
*/

/** Executor function for Blender operations */
void exec_blender(struct blendjob* blendjob, char *input, char *output, int frame)
{

	char *frame_str = int_to_str(frame); // Converts the int frame to a string, so it can be in the cmd array. GNU/*nix compatible only, fix before releasing win32, although dll for windows for asprintf exists!

  /* start execio code */
  	char *command = "blender"; // @TODO: append .exe if win32?
  	int ret;
    char *cmd[] = { command, "-b", "-o", output, input, "-f", frame_str, (char *)NULL };

  	char buf[10];
  	struct execio *testrem;
  	size_t readlen;
  	ret = execio_open(&testrem, command, cmd); // This path will be absolute for testing, should be relative to install on production
  	buf[9] = '\0'; // null-terminating the array...
  	while(!execio_read(testrem, buf, 9, &readlen))
  	    {
  	      if(readlen > 9) {
  		fprintf(stderr, "Something is terribly wrong!\n");
  	      }
  	      buf[readlen] = '\0';
  	      fprintf(stderr, "read \"%s\"\n", buf);
  	    }
  	execio_close(testrem);
  /* end execio code */
  	if(ret == 1){
  		fprintf(stderr,"Error starting Blender. Check your install.");
  	}
  	else{
  		fprintf(stderr,"Blender at least started nicely, who knows if it rendered anything though.");
  	}
}