ta name='robots' content='index, nofollow'/>
summary refs log blame commit diff
path: root/bounce.c
blob: c9b27b016ff23889325baeba24baaf57abab1eaa (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                                                                       
                                                                       





                                                                    
                                               
  

                                                                         










                                                                       

   
                   
                
                  
                  
                   
                   
                         
                 
                
                   
                    


                   
                    
                     
                       
                     
                     



                     



                         

                   

             
                            
                      


                                                        

                                                         

                                           


                                          
                                      



                                                                                
               
                                              
                                                                                   




































                                                                  
                                               
                                                              




                                       






                                                           









                                                               

                      
                            












                                                                  
                                                                              


                           


                                               
                         

 

                  
                   


                      


                                                                             
                                                 

                           
 


                                                     


                                        
                                                    
                
                                  
                                                   
         
                                                       


                                                                              





                                                                         


                                                                         
 
                     

 


                                                


                                                                                 

                                                  


                                                                               




                                                         


                                           

 















                                                                               
               

                                











                                                                               
         


                                                                              

 
                                   
                               


                                                    

 
                                  


                                    

                                           
                                     

                                     
                                  
                                   
 
                              

                                      
                                          
 

                                  
                          
                           
                              


                                
 
                                
                                                      
 







                                                                        
                                                                            
                                                                       






























                                                                         
 

                    




                                                                
 
                                                                                    
                              
                                                         
                                                                          
                                                                                     
                                                           
                                                                                     
                                                             
                                                           
                                                                                     
                                                                            
                                                                 
                                                           
                                                                                     
                                                             
                                                                             
                                                             
                                                             
                                                           
                                                          

                                                       
                                                             

                                                       
                                                       
                                                       
                                                                      
                                                       
                                                        
                                                       
                                                                  
                                                             


                                                         
                                                                                 
                                              
 








                                                                                
                           



                                                                                          

                           



                                                                                        
         

                                                   





                                                         
                                                   


                                                                   
 

                                         
 





                                                            



                                                         
                                                      

                     
 
                    
                                  

                                                                       

                                                       
                                                               




                                              

                                                                    
                                                                                  



                                                                                    
                                                              
                                                            

                                              
                                            
                                               
         
                                      

      
                                                            
                                                     
                                                        
 
                                           
                                                 
                                                     
 

                                       
                                 
                                       


                                       
                                            
                                                
                                                   
                                        
         
                               
 
                  






                                                                
                 
 

                                                                      
 
                                                                                


                                                             
                                                        
                                             



                                                
                                       
                                                                                    




                                                       






                                                                                   
                                 

                                         
 
                                                                 
                                                                     
                                                                 

                                                                                   
                                               


                         

                                                               




                                             
                                       
                                             
                                   


                                       
                                             




                                                                      

                 
 
                                           




                                                                                      

                                       
 
/* Copyright (C) 2019  C. McEnroe <june@causal.agency>
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Additional permission under GNU GPL version 3 section 7:
 *
 * If you modify this Program, or any covered work, by linking or
 * combining it with LibreSSL (or a modified version of that library),
 * containing parts covered by the terms of the OpenSSL License and the
 * original SSLeay license, the licensors of this Program grant you
 * additional permission to convey the resulting work. Corresponding
 * Source for a non-source form of such a combination shall include the
 * source code for the parts of LibreSSL used as well as that of the
 * covered work.
 */

#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <openssl/rand.h>
#include <poll.h>
#include <pwd.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sysexits.h>
#include <tls.h>
#include <unistd.h>

#ifdef __FreeBSD__
#include <sys/capsicum.h>
#endif

#include "bounce.h"

bool verbose;

static void hashPass(void) {
	byte rand[12];
	int n = RAND_bytes(rand, sizeof(rand));
	if (n < 1) errx(EX_OSERR, "RAND_bytes failure");

	char salt[3 + BASE64_SIZE(sizeof(rand))] = "$6$";
	base64(&salt[3], rand, sizeof(rand));

	char *pass = getpass("Password: ");
	printf("%s\n", crypt(pass, salt));
}

static void genKey(const char *path) {
	const char *name = strrchr(path, '/');
	name = (name ? &name[1] : path);
	char subj[256];
	snprintf(subj, sizeof(subj), "/CN=%.*s", (int)strcspn(name, "."), name);
	execlp(
		OPENSSL_BIN, "openssl", "req",
		"-x509", "-new", "-newkey", "rsa:4096", "-sha256", "-days", "3650",
		"-nodes", "-subj", subj, "-keyout", path,
		NULL
	);
	err(EX_UNAVAILABLE, "openssl");
}

static void redir(int dst, int src) {
	int fd = dup2(src, dst);
	if (fd < 0) err(EX_OSERR, "dup2");
	close(src);
}

static void genCert(const char *path, const char *ca) {
	int out = open(path, O_WRONLY | O_APPEND | O_CREAT, 0600);
	if (out < 0) err(EX_CANTCREAT, "%s", path);

	redir(STDOUT_FILENO, out);
	if (!ca) {
		genKey(path);
		return;
	}

	int rw[2];
	int error = pipe(rw);
	if (error) err(EX_OSERR, "pipe");

	pid_t pid = fork();
	if (pid < 0) err(EX_OSERR, "fork");
	if (!pid) {
		close(rw[0]);
		redir(STDOUT_FILENO, rw[1]);
		genKey(path);
	}

	close(rw[1]);
	redir(STDIN_FILENO, rw[0]);
	execlp(
		OPENSSL_BIN, "openssl", "x509",
		"-CA", ca, "-CAcreateserial", "-days", "3650",
		NULL
	);
	err(EX_UNAVAILABLE, "openssl");
}

static size_t parseSize(const char *str) {
	char *rest;
	size_t size = strtoull(str, &rest, 0);
	if (*rest) errx(EX_USAGE, "invalid size: %s", str);
	return size;
}

static struct timeval parseInterval(const char *str) {
	char *rest;
	long ms = strtol(str, &rest, 0);
	if (*rest) errx(EX_USAGE, "invalid interval: %s", str);
	return (struct timeval) {
		.tv_sec = ms / 1000,
		.tv_usec = 1000 * (ms % 1000),
	};
}

static FILE *saveFile;

static void saveSave(void) {
	int error = ringSave(saveFile);
	if (error) warn("fwrite");
	error = fclose(saveFile);
	if (error) warn("fclose");
}

static void saveLoad(const char *path) {
	umask(0066);
	saveFile = fopen(path, "a+");
	if (!saveFile) err(EX_CANTCREAT, "%s", path);

	int error = flock(fileno(saveFile), LOCK_EX | LOCK_NB);
	if (error && errno != EWOULDBLOCK) err(EX_OSERR, "flock");
	if (error) errx(EX_CANTCREAT, "lock held by other process: %s", path);

	rewind(saveFile);
	ringLoad(saveFile);
	error = ftruncate(fileno(saveFile), 0);
	if (error) err(EX_IOERR, "ftruncate"