📄 main.c
字号:
/* PKCIPE - public key based configuration tool for CIPE main.c - startup stuff Copyright 2000 Olaf Titz <olaf@bigred.inka.de> 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 2 of the License, or (at your option) any later version.*//* $Id: main.c,v 1.15 2003/05/10 20:07:44 olaf81825 Exp $ */#include <fcntl.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>#include <unistd.h>#include <sys/resource.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/utsname.h>#include <sys/wait.h>#include <netinet/in.h>#include <arpa/inet.h>#include <openssl/err.h>#include <openssl/pem.h>#include "pkcipe.h"#ifndef KEYFILE#define KEYFILE "/etc/cipe/identity.priv"#endif#ifndef LOGFAC#define LOGFAC LOG_DAEMON#endifvoid usage(const char *n) __attribute__((noreturn));void SSLprinterror(int level){ static int l=0; if (!l) { ERR_load_crypto_strings(); l=1; } cipe_syslog(level, "%s", ERR_error_string(ERR_get_error(), NULL));}void term(int s){ Log(LOG_NOTICE, "got termination signal"); exit(255);}void tout(int s){ Log(LOG_NOTICE, "Timeout"); exit(3);}#define MAGIC_STRING_LEN 0x1bint doFD(int fd, struct in_addr addr){ unsigned char buf[32]; int e; if (fcntl(fd, F_SETFD, FD_CLOEXEC)<0) perror("FD_CLOEXEC"); /* not fatal */ signInit(); vrfyInit(); setSendKey(NULL); setRecvKey(NULL); sprintf(buf, "CIPE/%02d %-18.18s*", protoVersion, VERSION " " PVNOTE); packetSendP(fd, (unsigned char *)buf, MAGIC_STRING_LEN, 2); if (packetRecvP(fd, buf, sizeof(buf), 2)<6) { Log(LOG_INFO, "peer: no magic"); close(fd); return 2; } for (e=0; buf[e]&&buf[e]!='/'; ++e); e=atoi(buf+e+1); if (protoVersion>e) protoVersion=e; debug((DEB_PROTO, "Using protocol %d", protoVersion)); if (protoVersion<1 || protoVersion>MAX_SUPPORTED_PROTOCOL) { Log(LOG_INFO, "peer: unknown protocol: %d/%d", protoVersion, e); close(fd); return 2; } e=doProtocol(fd, addr); return (e<0) ? 2 : 0;}int doClient(const char *hp, struct sockaddr_in *ra){ int c, e; struct sockaddr_in sa; if (getaddr(hp, &sa, "tcp")<0) return 1; if ((c=socket(PF_INET, SOCK_STREAM, 0))<0) { perror("socket"); return 1; } setsig(SIGALRM, tout); alarm(timeout); if (connect(c, (struct sockaddr*)&sa, sizeof(sa))<0) { perror("connect"); close(c); return 1; } if (ra) sa=*ra; Log(LOG_INFO, "connect to %s", inet_ntoa(sa.sin_addr)); e=doFD(c, sa.sin_addr); close(c); return e;}#ifdef DEBUGint doServer(int p, struct sockaddr_in *ra){ struct sockaddr_in sa; int l, c, e; if ((l=socket(PF_INET, SOCK_STREAM, 0))<0) { perror("socket"); return 1; } c=1; if (setsockopt(l, SOL_SOCKET, SO_REUSEADDR, &c, sizeof(c))<0) perror("SO_REUSEADDR"); /* not fatal */ if (fcntl(l, F_SETFD, FD_CLOEXEC)<0) perror("FD_CLOEXEC"); /* not fatal */ memset(&sa, 0, sizeof(sa)); sa.sin_family=AF_INET; sa.sin_port=htons(p); sa.sin_addr.s_addr=htonl(INADDR_ANY); if (bind(l, (struct sockaddr*)&sa, sizeof(sa))<0) { perror("bind"); close(l); return 1; } if (listen(l, 64)<0) { perror("listen"); close(l); return 1; } setsig(SIGALRM, tout); while (1) { e=sizeof(sa); alarm(0); if ((c=accept(l, (struct sockaddr*)&sa, &e))<0) { if (errno!=EINTR) perror("accept"); continue; } Log(LOG_INFO, "connect from %s", inet_ntoa(sa.sin_addr)); e=doFD(c, ra ? ra->sin_addr : sa.sin_addr); close(c); Log(LOG_INFO, "doServer: status %d", e); }}#endifvoid usage(const char *n){#ifdef DEBUG fprintf(stderr, "usage: %s [ -p proto ] [ -k keyfile ] [ -c host:port | -s port ]\n [ -r host ] [ -t timeout ] [ -D debug ] [ -E ] [ identity ]\n", n);#else fprintf(stderr, "usage: %s [ -p proto ] [ -k keyfile ] [ -c host:port ]\n [ -r host ] [ -t timeout ] [ -E ] [ identity ]\n", n);#endif exit(1);}int main(int argc, char *argv[]){ int c; char *ok=KEYFILE;#ifdef DEBUG char *os=NULL;#endif char *oc=NULL, *or=NULL; struct sockaddr_in ra; char *pn=strrchr(argv[0], '/'); if (pn) ++pn; else pn=argv[0];#ifdef DEBUG { /* ensure we can dump core */ struct rlimit rl; rl.rlim_cur=rl.rlim_max=8192*1024; if (setrlimit(RLIMIT_CORE, &rl)<0) perror("setrlimit"); chdir("/var/run/cipe"); /* XX */ }#endif while ((c=getopt(argc, argv, "p:k:c:r:it:s:D:E"))!=EOF) { switch (c) { case 'p': protoVersion=atoi(optarg); break; case 'k': ok=optarg; break; case 'c': oc=optarg; break; case 'r': or=optarg; break; case 'i': break; /* ignored for compatibility */ case 't': timeout=atoi(optarg); break;#ifdef DEBUG case 's': os=optarg; break; case 'D': debugging=atoi(optarg); break;#endif case 'E': logstderr=1; break; default: usage(pn); } } if (optind>=argc) { if (!(myIdentity=malloc(SYS_NMLN+2))) { fprintf(stderr, "Out of memory, a hopeless case\n"); return 1; } if (gethostname(myIdentity, SYS_NMLN)<0) { perror("gethostname"); return 1; } } else { myIdentity=argv[optind]; } umask(077); OpenSSL_add_all_algorithms(); if (initDH()<0) return -1; if (secchk(ok, 0077, 0022, 1)<0) return 1; { FILE *f=fopen(ok, "r"); if (!f) { perror("open keyfile"); return 1; } myKey=PEM_read_PrivateKey(f, NULL, NULL, NULL); fclose(f); if (!myKey || RSA_check_key(myKey->pkey.rsa)!=1) { SSLprinterror(LOG_STDERR); return 1; } } if (!logstderr) openlog(pn, LOG_CONS|LOG_PID, LOGFAC); if (or) getaddr(or, &ra, NULL); setsig(SIGINT, term); setsig(SIGTERM, term);#ifdef DEBUG if (os) return doServer(atoi(os), or ? &ra : NULL);#endif if (oc) { return doClient(oc, or ? &ra :NULL); } else { struct sockaddr_in sa; int ss=sizeof(sa); if (getpeername(0, (struct sockaddr*)&sa, &ss)<0) { Log(LOG_ERR, "main: getsockname: %m"); sa.sin_addr.s_addr=htonl(INADDR_ANY); } Log(LOG_INFO, "connect from %s", inet_ntoa(sa.sin_addr)); return doFD(0, or ? ra.sin_addr : sa.sin_addr); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -