login-validator: Save shadow file by IP
This commit is contained in:
parent
59abc217d1
commit
26c162f319
6 changed files with 82 additions and 23 deletions
|
|
@ -169,5 +169,5 @@ func (l loginChecker) registerUser(username, remoteAddr string, ent ARPEntry) (n
|
|||
}
|
||||
|
||||
func (l loginChecker) lateLoginAction(username, remoteAddr string, mac ARPEntry, ip net.IP) error {
|
||||
return RegisterUserMAC(mac, ip, username)
|
||||
return RegisterUserMAC(mac, ip, username, remoteAddr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,27 @@ package main
|
|||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/cavaliergopher/cpio"
|
||||
)
|
||||
|
||||
func copy_challenge(fd io.Writer) error {
|
||||
fdchal, err := os.Open(path.Join(tftpDir, "challenge-initrd.img"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fdchal.Close()
|
||||
|
||||
_, err = io.Copy(fd, fdchal)
|
||||
return err
|
||||
}
|
||||
|
||||
func passwd(w http.ResponseWriter, r *http.Request) {
|
||||
if addr := r.Header.Get("X-Forwarded-For"); addr != "" {
|
||||
r.RemoteAddr = addr
|
||||
|
|
@ -45,7 +56,10 @@ func passwd(w http.ResponseWriter, r *http.Request) {
|
|||
defer file.Close()
|
||||
|
||||
// Save the file
|
||||
fd, err := os.Create(path.Join(tftpDir, "shadows", fmt.Sprintf("%s.img", initrd_name(r.RemoteAddr))))
|
||||
initrd := initrd_name(r.RemoteAddr)
|
||||
os.MkdirAll(path.Join(tftpDir, "shadows", initrd), 0755)
|
||||
|
||||
fd, err := os.Create(path.Join(tftpDir, "shadows", initrd, "challenge-initrd.img"))
|
||||
if err != nil {
|
||||
log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error())
|
||||
http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError)
|
||||
|
|
@ -53,25 +67,32 @@ func passwd(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
defer fd.Close()
|
||||
|
||||
fd2, err := os.Create(path.Join(tftpDir, "shadows", initrd, "shadow"))
|
||||
if err != nil {
|
||||
log.Println("Error when creating shadow file from", r.RemoteAddr, err.Error())
|
||||
http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fd2.Close()
|
||||
|
||||
// Copy the original challenge
|
||||
fdchal, err := os.Open(path.Join(tftpDir, "challenge-initrd.img"))
|
||||
err = copy_challenge(fd)
|
||||
if err != nil {
|
||||
log.Println(r.RemoteAddr, "Error when opening original challenge initramfs:", err.Error())
|
||||
http.Error(w, "Unable to treat your passwd file, please try again later", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fdchal.Close()
|
||||
|
||||
io.Copy(fd, fdchal)
|
||||
|
||||
// Append the new cpio archive
|
||||
zw := gzip.NewWriter(fd)
|
||||
wfd := io.MultiWriter(fd, fd2)
|
||||
zw := gzip.NewWriter(wfd)
|
||||
wcpio := cpio.NewWriter(zw)
|
||||
|
||||
hdr := &cpio.Header{
|
||||
Name: "etc/shadow",
|
||||
Mode: 0640,
|
||||
Size: header.Size,
|
||||
Name: "etc/shadow_",
|
||||
Mode: 0640,
|
||||
ModTime: time.Now(),
|
||||
Size: header.Size,
|
||||
}
|
||||
if err := wcpio.WriteHeader(hdr); err != nil {
|
||||
log.Println("Error when writing cpio header from", r.RemoteAddr, err.Error())
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/sha512"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
|
|
@ -16,25 +17,22 @@ const pxeUserTplPath = "pxelinux.cfg/tpl"
|
|||
const ipxeUserTplPath = "pxelinux.cfg/tpl.ipxe"
|
||||
const pxeUserPath = "pxelinux.cfg"
|
||||
|
||||
func RegisterUserMAC(ent ARPEntry, ip net.IP, username string) error {
|
||||
if err := registerUser(ipxeUserTplPath, fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x.ipxe", ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip); err != nil {
|
||||
func RegisterUserMAC(ent ARPEntry, ip net.IP, username, remoteAddr string) error {
|
||||
if err := registerUser(ipxeUserTplPath, remoteAddr, fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x.ipxe", ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return registerUser(pxeUserTplPath, fmt.Sprintf("%02x-%02x-%02x-%02x-%02x-%02x-%02x", ent.HWType, ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip)
|
||||
return registerUser(pxeUserTplPath, remoteAddr, fmt.Sprintf("%02x-%02x-%02x-%02x-%02x-%02x-%02x", ent.HWType, ent.HWAddress[0], ent.HWAddress[1], ent.HWAddress[2], ent.HWAddress[3], ent.HWAddress[4], ent.HWAddress[5]), username, ip)
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterUserIP(ip net.IP, username string) error {
|
||||
return registerUser(pxeUserTplPath, fmt.Sprintf("%02X%02X%02X%02X", ip.To4()[0], ip.To4()[1], ip.To4()[2], ip.To4()[3]), username, ip)
|
||||
}
|
||||
|
||||
func initrd_name(remote string) string {
|
||||
log.Println("initrd_name:", remote)
|
||||
initrd := hmac.New(md5.New, []byte(loginSalt))
|
||||
initrd.Write([]byte(remote))
|
||||
return fmt.Sprintf("%x", initrd.Sum(nil))
|
||||
}
|
||||
|
||||
func registerUser(tplPath string, filename string, username string, ip net.IP) error {
|
||||
func registerUser(tplPath, remoteAddr string, filename string, username string, ip net.IP) error {
|
||||
if pxeTplCnt, err := ioutil.ReadFile(path.Join(tftpDir, tplPath)); err != nil {
|
||||
return err
|
||||
} else if userfd, err := os.OpenFile(path.Join(tftpDir, pxeUserPath, filename), os.O_RDWR|os.O_CREATE, 0644); err != nil {
|
||||
|
|
@ -42,6 +40,24 @@ func registerUser(tplPath string, filename string, username string, ip net.IP) e
|
|||
} else {
|
||||
defer userfd.Close()
|
||||
|
||||
initrd := initrd_name(remoteAddr)
|
||||
|
||||
err := os.MkdirAll(path.Join(tftpDir, "shadows", initrd), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fd, err := os.Create(path.Join(tftpDir, "shadows", initrd, "challenge-initrd.img"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
err = copy_challenge(fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pkey := hmac.New(sha512.New512_224, []byte(loginSalt))
|
||||
pkey.Write([]byte(username))
|
||||
|
||||
|
|
@ -53,7 +69,7 @@ func registerUser(tplPath string, filename string, username string, ip net.IP) e
|
|||
return err
|
||||
} else if err := pxeTmpl.Execute(userfd, map[string]string{
|
||||
"username": username,
|
||||
"initrd": initrd_name(ip.String()),
|
||||
"initrd": initrd,
|
||||
"pkey": fmt.Sprintf("%x", pkey.Sum(nil)),
|
||||
"ip": ip.String(),
|
||||
}); err != nil {
|
||||
|
|
|
|||
Reference in a new issue